├── res └── font_atlas.png ├── src ├── glfw │ ├── glfw3.lib │ ├── native.odin │ ├── types.odin │ ├── bindings.odin │ └── constants.odin ├── stbi │ ├── stb_image.lib │ ├── stb_image_write.lib │ ├── stb_image_write.odin │ └── stb_image.odin ├── odin-gl │ ├── LICENSE │ ├── LICENSE_glad │ ├── README.md │ ├── helpers.odin │ └── constants.odin ├── image.odin ├── vert.glsl ├── draw.odin ├── frag.glsl └── main.odin ├── hyperbolic-fighers.exe ├── LD47.sublime-project ├── README.md └── LICENSE /res/font_atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gingerBill/LD47/HEAD/res/font_atlas.png -------------------------------------------------------------------------------- /src/glfw/glfw3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gingerBill/LD47/HEAD/src/glfw/glfw3.lib -------------------------------------------------------------------------------- /hyperbolic-fighers.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gingerBill/LD47/HEAD/hyperbolic-fighers.exe -------------------------------------------------------------------------------- /src/stbi/stb_image.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gingerBill/LD47/HEAD/src/stbi/stb_image.lib -------------------------------------------------------------------------------- /src/stbi/stb_image_write.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gingerBill/LD47/HEAD/src/stbi/stb_image_write.lib -------------------------------------------------------------------------------- /LD47.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "path": ".", 6 | "file_exclude_patterns": [ 7 | "*.sublime-workspace", 8 | ] 9 | }, 10 | { 11 | "path": "W:/Odin/core/", 12 | "name": "Odin Core", 13 | } 14 | ], 15 | "settings": { 16 | "tab_size": 8, 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /src/glfw/native.odin: -------------------------------------------------------------------------------- 1 | package glfw_bindings 2 | 3 | // TODO: Unfinished 4 | 5 | import "core:os" 6 | 7 | when os.OS == "windows" { 8 | foreign import glfw { "glfw3.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" }; 9 | 10 | HWND :: rawptr; 11 | 12 | @(default_calling_convention="c", link_prefix="glfw") 13 | foreign glfw { 14 | GetWin32Window :: proc(window: Window_Handle) -> HWND ---; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/stbi/stb_image_write.odin: -------------------------------------------------------------------------------- 1 | package stbi 2 | 3 | import "core:os" 4 | import "core:strings" 5 | 6 | when os.OS == "windows" do foreign import stbiw "stb_image_write.lib" 7 | // bind 8 | @(default_calling_convention="c") 9 | @(link_prefix="stbi_") 10 | foreign stbiw { 11 | write_png :: proc(filename: cstring, w, h, comp: i32, data: rawptr, stride_in_bytes: i32) -> i32 ---; 12 | write_bmp :: proc(filename: cstring, w, h, comp: i32, data: rawptr) -> i32 ---; 13 | write_tga :: proc(filename: cstring, w, h, comp: i32, data: rawptr) -> i32 ---; 14 | write_hdr :: proc(filename: cstring, w, h, comp: i32, data: ^f32) -> i32 ---; 15 | write_jpg :: proc(filename: cstring, w, h, comp: i32, data: rawptr, quality: i32 /*0 to 100*/) -> i32 ---; 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hyperbolic Space Fighters Extreme! 2 | 3 | THE Hyperbolic Space Fighting Game of Your Psychedelic Dreams. 4 | 5 | In the hyperbolic space, things can get pretty gnarly. Straight lines can appear to bend. 6 | 7 | At the edge of the ring is the infinite, and the infinite wraps back around at you. 8 | 9 | **WARNING:** This game can be disorienting due to the hyperbolic and psychedelic nature. 10 | 11 | ## Objective 12 | 13 | * Destroy as many blue enemies in hyperbolic space by shooting projectiles from your ship 14 | * Your ship has a green cannon attached which it will launch projectiles 15 | 16 | ## Controls 17 | 18 | ### Keyboard 19 | * Move - WASD or Arrow Keys 20 | * Shoot - Space 21 | * Pause - P or Escape 22 | * Cancel - Escape 23 | 24 | ### XBox Controller 25 | 26 | * Move - Left Stick or D-Pad 27 | * Shoot - A 28 | 29 | 30 | ## Platforms 31 | 32 | * Windows AMD64/x86-64 33 | 34 | ## Tools 35 | 36 | Tools Used: 37 | * [Odin](https://odin-lang.org/) Programming Language 38 | * [GLFW](https://www.glfw.org/) 39 | * OpenGL 40 | * [STB](https://github.com/nothings/stb) Image 41 | 42 | 43 | ## Lacking Features 44 | 45 | * Audio 46 | -------------------------------------------------------------------------------- /src/odin-gl/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 vassvik 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/odin-gl/LICENSE_glad: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 David Herberth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Ginger Bill. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | * Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /src/glfw/types.odin: -------------------------------------------------------------------------------- 1 | package glfw_bindings 2 | 3 | Window_Handle :: distinct rawptr; 4 | Monitor_Handle :: distinct rawptr; 5 | Cursor_Handle :: distinct rawptr; 6 | 7 | Vid_Mode :: struct { 8 | width: i32, 9 | height: i32, 10 | red_bits: i32, 11 | green_bits: i32, 12 | blue_bits: i32, 13 | refresh_rate: i32, 14 | }; 15 | 16 | Gamma_Ramp :: struct { 17 | red, green, blue: ^u16, 18 | size: u32, 19 | }; 20 | 21 | Image :: struct { 22 | width, height: i32, 23 | pixels: ^u8, 24 | }; 25 | 26 | Gamepad_State :: struct { 27 | buttons: [15]b8, 28 | axes: [6]f32, 29 | }; 30 | 31 | /*** Procedure type declarations ***/ 32 | Window_Iconify_Proc :: #type proc "c" (window: Window_Handle, iconified: i32); 33 | Window_Refresh_Proc :: #type proc "c" (window: Window_Handle); 34 | Window_Focus_Proc :: #type proc "c" (window: Window_Handle, focused: i32); 35 | Window_Close_Proc :: #type proc "c" (window: Window_Handle); 36 | Window_Size_Proc :: #type proc "c" (window: Window_Handle, width, height: i32); 37 | Window_Pos_Proc :: #type proc "c" (window: Window_Handle, xpos, ypos: i32); 38 | Window_Maximize_Proc :: #type proc "c" (window: Window_Handle, iconified: i32); 39 | Window_Content_Scale_Proc :: #type proc "c" (window: Window_Handle, xscale, yscale: f32); 40 | Framebuffer_Size_Proc :: #type proc "c" (window: Window_Handle, width, height: i32); 41 | Drop_Proc :: #type proc "c" (window: Window_Handle, count: i32, paths: ^cstring); 42 | Monitor_Proc :: #type proc "c" (window: Window_Handle); 43 | 44 | Key_Proc :: #type proc "c" (window: Window_Handle, key, scancode, action, mods: i32); 45 | Mouse_Button_Proc :: #type proc "c" (window: Window_Handle, button, action, mods: i32); 46 | Cursor_Pos_Proc :: #type proc "c" (window: Window_Handle, xpos, ypos: f64); 47 | Scroll_Proc :: #type proc "c" (window: Window_Handle, xoffset, yoffset: f64); 48 | Char_Proc :: #type proc "c" (window: Window_Handle, codepoint: rune); 49 | Char_Mods_Proc :: #type proc "c" (window: Window_Handle, codepoint: rune, mods: i32); 50 | Cursor_Enter_Proc :: #type proc "c" (window: Window_Handle, entered: i32); 51 | Joystick_Proc :: #type proc "c" (joy, event: i32); 52 | 53 | Error_Proc :: #type proc "c" (error: i32, description: cstring); 54 | -------------------------------------------------------------------------------- /src/odin-gl/README.md: -------------------------------------------------------------------------------- 1 | # odin-gl: opengl loader in Odin 2 | 3 | Includes procedures to load OpenGL function pointers. Currently only supports the `core` profile, up to version 4.6. Based on the output from the [glad](https://github.com/Dav1dde/glad) webservice using 4.6 `core`. 4 | 5 | #### Note: You will be required to pass your own GetProcAddress equivalent (wglGetProcAddress, glXGetProcAddress, glfwGetProcAddress, etc.), for example: 6 | 7 | ```go 8 | gl.load_up_to(4, 5, proc(p: rawptr, name: cstring) do (cast(^rawptr)p)^ = glfw.GetProcAddress(name); ); 9 | ``` 10 | [odin-glfw](https://github.com/vassvik/odin-glfw) also provides a useful helper you can pass straight to `gl.load_up_to`: 11 | ```go 12 | gl.load_up_to(4, 5, glfw.set_proc_address); 13 | ``` 14 | 15 | #### NOTE: It is recommended to put this into the shared collection: 16 | ``` 17 | cd /path/to/Odin/shared 18 | git clone https://github.com/vassvik/odin-gl.git 19 | ``` 20 | 21 | ## Extra utility procedures (Outdated. See the end of `gl.odin`) 22 | 23 | Some useful helper procedures can be found in `helpers.odin`, for tasks such as: 24 | 25 | - loading vertex, fragment and compute shaders (from source or files) using `load_shaders_file`, `load_shaders_source`, `load_compute_file` and `load_compute_source` 26 | - grabbing uniform and attribute locations using `get_uniform_location` and `get_attribute_location` 27 | - getting all active uniforms from a program using `get_uniforms_from_program` 28 | - hot reloading of shaders (windows only right now) using `update_shader_if_changed` and `update_shader_if_changed_compute` 29 | 30 | ## Debug mode 31 | 32 | Each `gl` call will be appended by a debug helper calling `glGetError()` if compiled with `-debug`. This can be useful to detect incorrect usage. Sample output (also outputting the NO_ERRORS case for the sake of showcasing): 33 | 34 | ``` 35 | glGetError() returned NO_ERROR 36 | call: glTexImage2D(GL_TEXTURE_2D=3553, 0, 34836, 1150, 1024, 0, GL_RGBA=6408, GL_FLOAT=5126, 0x0) 37 | in: C://texture.odin(156:23) 38 | glGetError() returned NO_ERROR 39 | call: glEnable(GL_DEBUG_OUTPUT=37600) 40 | in: C://main.odin(185:6) 41 | glGetError() returned NO_ERROR 42 | call: glGetError() -> 0 43 | in: C://main.odin(193:5) 44 | glGetError() returned INVALID_ENUM 45 | call: glEnable(INVALID_ENUM=123123123) 46 | in: C://main.odin(194:5) 47 | glGetError() returned INVALID_VALUE 48 | call: glPointSize(-1.000) 49 | in: C://main.odin(195:5) 50 | glGetError() returned NO_ERROR 51 | call: glDisable(GL_SCISSOR_TEST=3089) 52 | in: C://main.odin(270:6) 53 | glGetError() returned NO_ERROR 54 | call: glViewport(0, 0, 1150, 1024) 55 | in: C://main.odin(271:6) 56 | glGetError() returned NO_ERROR 57 | call: glClearColor(0.800, 0.800, 0.800, 1.000) 58 | in: C://main.odin(272:6) 59 | ``` -------------------------------------------------------------------------------- /src/stbi/stb_image.odin: -------------------------------------------------------------------------------- 1 | package stbi 2 | 3 | import "core:os" 4 | 5 | when os.OS == "windows" do foreign import stbi "stb_image.lib" 6 | 7 | // 8 | // load image by filename, open file, or memory buffer 9 | // 10 | Io_Callbacks :: struct { 11 | read: proc "c" (user: rawptr, data: ^u8, size: i32) -> i32, // fill 'data' with 'size' u8s. return number of u8s actually read 12 | skip: proc "c" (user: rawptr, n: i32), // skip the next 'n' u8s, or 'unget' the last -n u8s if negative 13 | eof: proc "c" (user: rawptr) -> i32, // returns nonzero if we are at end of file/data 14 | } 15 | 16 | @(default_calling_convention="c", link_prefix="stbi_") 17 | foreign stbi { 18 | //////////////////////////////////// 19 | // 20 | // 8-bits-per-channel interface 21 | // 22 | load :: proc(filename: cstring, x, y, channels_in_file: ^i32, desired_channels: i32) -> ^u8 ---; 23 | load_from_memory :: proc(buffer: ^u8, len: i32, x, y, channels_in_file: ^i32, desired_channels: i32) -> ^u8 ---; 24 | load_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr, x, y, channels_in_file: ^i32, desired_channels: i32) -> ^u8 ---; 25 | 26 | //////////////////////////////////// 27 | // 28 | // 16-bits-per-channel interface 29 | // 30 | load_16 :: proc(filename: ^u8, x, y, channels_in_file: ^i32, desired_channels: i32) -> ^u16 ---; 31 | 32 | //////////////////////////////////// 33 | // 34 | // float-per-channel interface 35 | // 36 | loadf :: proc(filename: cstring, x, y, channels_in_file: ^i32, desired_channels: i32) -> ^f32 ---; 37 | loadf_from_memory :: proc(buffer: ^u8, len: i32, x, y, channels_in_file: ^i32, desired_channels: i32) -> ^f32 ---; 38 | loadf_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr, x, y, channels_in_file: ^i32, desired_channels: i32) -> ^f32 ---; 39 | 40 | 41 | hdr_to_ldr_gamma :: proc(gamma: f32) ---; 42 | hdr_to_ldr_scale :: proc(scale: f32) ---; 43 | 44 | is_hdr_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr) -> i32 ---; 45 | is_hdr_from_memory :: proc(buffer: ^u8, len: i32) -> i32 ---; 46 | 47 | is_hdr :: proc(filename: cstring) -> i32 ---; 48 | 49 | // get a VERY brief reason for failure 50 | // NOT THREADSAFE 51 | failure_reason :: proc() -> ^u8 ---; 52 | 53 | // free the loaded image -- this is just free() 54 | image_free :: proc(retval_from_load: rawptr) ---; 55 | 56 | // get image dimensions & components without fully decoding 57 | info :: proc(filename: cstring, x, y, comp: ^i32) -> i32 ---; 58 | info_from_memory :: proc(buffer: ^u8, len: i32, x, y, comp: ^i32) -> i32 ---; 59 | info_from_callbacks :: proc(clbk: ^Io_Callbacks, user: rawptr, x, y, comp: ^i32) -> i32 ---; 60 | 61 | // for image formats that explicitly notate that they have premultiplied alpha, 62 | // we just return the colors as stored in the file. set this flag to force 63 | // unpremultiplication. results are undefined if the unpremultiply overflow. 64 | set_unpremultiply_on_load :: proc (flag_true_if_should_unpremultiply: i32) ---; 65 | 66 | 67 | // indicate whether we should process iphone images back to canonical format, 68 | // or just pass them through "as-is" 69 | convert_iphone_png_to_rgb :: proc(flag_true_if_should_convert: i32) ---; 70 | 71 | // flip the image vertically, so the first pixel in the output array is the bottom left 72 | set_flip_vertically_on_load :: proc(flag_true_if_should_flip: i32) ---; 73 | 74 | // ZLIB client - used by PNG, available for other purposes 75 | zlib_decode_malloc :: proc(buffer: ^u8, len: i32, outlen: ^i32) -> ^u8 ---; 76 | zlib_decode_malloc_guesssize :: proc(buffer: ^u8, len, initial_size: i32, outlen: ^i32) -> ^u8 ---; 77 | zlib_decode_malloc_guesssize_headerflag :: proc(buffer: ^u8, len, initial_size: i32, outlen: ^i32, parse_header: i32) -> ^u8 ---; 78 | 79 | zlib_decode_buffer :: proc(out_buffer: ^u8, olen: i32, in_buffer: ^u8, ilen: i32) -> i32 ---; 80 | zlib_decode_noheader_malloc :: proc(buffer: ^u8, len: i32, outlen: ^i32) -> ^u8 ---; 81 | zlib_decode_noheader_buffer :: proc(obuffer: ^u8, olen: i32, ibuffer: ^u8, ilen: i32) -> i32 ---; 82 | } 83 | -------------------------------------------------------------------------------- /src/image.odin: -------------------------------------------------------------------------------- 1 | package ld47 2 | 3 | import "core:fmt" 4 | import "core:mem" 5 | import gl "shared:odin-gl" 6 | import stbi "shared:stbi" 7 | 8 | 9 | gl_GetTextureHandle: proc "c" (texture: u32) -> u64; 10 | gl_MakeTextureHandleResident: proc "c" (texture: u64); 11 | 12 | 13 | Texture_Id :: enum u32 { 14 | White = 0, 15 | Error = 1, 16 | Font_Atlas = 2, 17 | } 18 | #assert(len(Texture_Id) <= 128); 19 | 20 | 21 | Sampling_Mode :: enum { 22 | Nearest, 23 | Linear, 24 | } 25 | 26 | Wrap_Mode :: enum { 27 | Repeat, 28 | Mirrored_Repeat, 29 | Clamp_To_Edge, 30 | Clamp_To_Border, 31 | } 32 | 33 | Texture :: distinct u64; 34 | 35 | Uniform_Texture_Entry :: struct { 36 | handle: Texture, 37 | _: u64, // Padding required for the GPU 38 | } 39 | #assert(size_of(Uniform_Texture_Entry) == 16); 40 | 41 | g_textures: [Texture_Id]Uniform_Texture_Entry; 42 | 43 | 44 | Channel_Kind :: enum i32 { 45 | None = 0, 46 | R = 1, 47 | RG = 2, 48 | RGB = 3, 49 | RGBA = 4, 50 | } 51 | 52 | Image :: struct { 53 | width: i32, 54 | height: i32, 55 | channels: Channel_Kind, 56 | data: []byte, 57 | } 58 | 59 | _sampling_mode_table := [Sampling_Mode]i32{ 60 | .Nearest = gl.NEAREST, 61 | .Linear = gl.LINEAR, 62 | }; 63 | _wrap_mode_table := [Wrap_Mode]i32{ 64 | .Repeat = gl.REPEAT, 65 | .Mirrored_Repeat = gl.MIRRORED_REPEAT, 66 | .Clamp_To_Edge = gl.CLAMP_TO_EDGE, 67 | .Clamp_To_Border = gl.CLAMP_TO_BORDER, 68 | }; 69 | 70 | channels_to_gl_formats :: proc(channels: Channel_Kind) -> (format, internal: u32) { 71 | switch channels { 72 | case .R: return gl.RED, gl.RGBA8; 73 | case .RG: return gl.RG, gl.RGBA8; 74 | case .RGB: return gl.RGB, gl.RGBA8; 75 | case .RGBA: return gl.RGBA, gl.RGBA8; 76 | case .None: // 77 | } 78 | panic("unknown channel size"); 79 | } 80 | 81 | create_image_from_file :: proc(filepath: string) -> Image { 82 | path := make([]byte, len(filepath)+1, context.temp_allocator); 83 | copy(path, filepath); 84 | path[len(filepath)] = 0; 85 | cpath := cstring(raw_data(path)); 86 | 87 | x, y, c: i32; 88 | c_data := stbi.load(cpath, &x, &y, &c, 4); 89 | defer stbi.image_free(c_data); 90 | 91 | size := int(x*y*c); 92 | data := make([]byte, size); 93 | mem.copy(raw_data(data), c_data, size); 94 | return Image{ 95 | width = x, 96 | height = y, 97 | channels = Channel_Kind(c), 98 | data = data, 99 | }; 100 | } 101 | 102 | create_texture_from_image :: proc(image: Image, sampling_mode: Sampling_Mode, wrap_mode := Wrap_Mode.Clamp_To_Edge) -> Texture { 103 | format, internal_format := channels_to_gl_formats(image.channels); 104 | 105 | sm := _sampling_mode_table[sampling_mode]; 106 | wm := _wrap_mode_table[wrap_mode]; 107 | 108 | tex: u32; 109 | gl.CreateTextures(gl.TEXTURE_2D, 1, &tex); 110 | 111 | gl.TextureParameteri(tex, gl.TEXTURE_MIN_FILTER, sm); 112 | gl.TextureParameteri(tex, gl.TEXTURE_MAG_FILTER, sm); 113 | gl.TextureParameteri(tex, gl.TEXTURE_WRAP_S, wm); 114 | gl.TextureParameteri(tex, gl.TEXTURE_WRAP_T, wm); 115 | gl.TextureStorage2D(tex, 1, internal_format, image.width, image.height); 116 | gl.TextureSubImage2D(tex, 0, 0, 0, image.width, image.height, format, gl.UNSIGNED_BYTE, raw_data(image.data)); 117 | 118 | raw_handle := gl_GetTextureHandle(tex); // Check for validity 119 | assert(raw_handle != 0); 120 | gl_MakeTextureHandleResident(raw_handle); 121 | return Texture(raw_handle); 122 | } 123 | 124 | create_texture_coloured :: proc(col: Colour, wrap_mode := Wrap_Mode.Clamp_To_Edge) -> Texture { 125 | W :: 8; 126 | cdata: [W*W]Colour = col; 127 | data := cast(^[4*W*W]u8)&cdata; 128 | image := Image{ 129 | width = W, 130 | height = W, 131 | channels = .RGBA, 132 | data = data[:], 133 | }; 134 | return create_texture_from_image(image, .Nearest, wrap_mode); 135 | } 136 | 137 | create_texture_from_file :: proc(filepath: string, sampling_mode: Sampling_Mode, wrap_mode := Wrap_Mode.Clamp_To_Edge) -> Texture { 138 | return create_texture_from_image(create_image_from_file(filepath), sampling_mode, wrap_mode); 139 | } 140 | 141 | 142 | init_textures :: proc() { 143 | g_textures[.White].handle = create_texture_coloured({255, 255, 255, 255}); 144 | g_textures[.Error].handle = create_texture_coloured({255, 0, 255, 255}); 145 | g_textures[.Font_Atlas].handle = create_texture_from_file("res/font_atlas.png", .Linear); 146 | } 147 | -------------------------------------------------------------------------------- /src/vert.glsl: -------------------------------------------------------------------------------- 1 | #version 450 core 2 | #extension GL_ARB_bindless_texture : require 3 | #extension GL_ARB_gpu_shader5 : require 4 | 5 | #define Prim_Kind_Invalid 0 6 | #define Prim_Kind_Rect 1 7 | #define Prim_Kind_Rect_Textured 2 8 | #define Prim_Kind_Poincare 16 9 | #define Prim_Kind_Entity 17 10 | #define Prim_Kind_Menu_Poincare 18 11 | 12 | layout(location=0) uniform vec4 u_screen_rect; // x y w h 13 | 14 | layout(std430, binding=0) buffer Buffer_Float { 15 | readonly restrict float buffer_float[]; 16 | }; 17 | 18 | layout(binding=0) uniform Samplers { 19 | uvec4 u_samplers[128]; 20 | }; 21 | 22 | out flat uint v_prim_kind; 23 | 24 | out vec2 v_position_origin; 25 | out vec2 v_position; 26 | out vec2 v_position_ss; 27 | out vec2 v_size; 28 | out vec4 v_colour; 29 | out vec2 v_uv; 30 | out flat uvec2 v_sampler; 31 | out flat uint v_texture_id; 32 | 33 | out vec2 v_epos; 34 | out float v_erot; 35 | out flat uint v_ekind; 36 | out flat uint v_vcount; 37 | 38 | 39 | vec2 corner_to_vec2(in uint corner) { 40 | /* 41 | 0 = vec2(0, 0) 42 | 1 = vec2(1, 0) 43 | 2 = vec2(1, 1) 44 | 3 = vec2(0, 1) 45 | */ 46 | return round(fract(float(corner) * 0.25 + vec2(0.125, 0.375))); 47 | } 48 | 49 | 50 | 51 | 52 | void main() { 53 | uint vertex = gl_VertexID; 54 | uint prim_kind = bitfieldExtract(vertex, 0, 6); 55 | uint extra = bitfieldExtract(vertex, 6, 2); 56 | uint data_pos = bitfieldExtract(vertex, 8, 24); 57 | 58 | vec2 position = vec2(0, 0); 59 | vec4 colour = vec4(1, 1, 1, 1); 60 | vec2 uv = vec2(0, 0); 61 | uint texture_id = 0; 62 | 63 | v_prim_kind = prim_kind; 64 | 65 | if (prim_kind == Prim_Kind_Invalid) { 66 | // DO NOWT 67 | } else if (prim_kind == Prim_Kind_Rect) { 68 | uint corner = extra; 69 | vec2 pos = vec2(buffer_float[data_pos+0], buffer_float[data_pos+1]); 70 | vec2 size = vec2(buffer_float[data_pos+2], buffer_float[data_pos+3]); 71 | uint col = floatBitsToUint(buffer_float[data_pos+4]); 72 | colour = unpackUnorm4x8(col); 73 | 74 | vec2 cc = corner_to_vec2(corner); 75 | position = pos + cc*size; 76 | 77 | v_position_origin = pos; 78 | v_size = size; 79 | } else if (prim_kind == Prim_Kind_Rect_Textured) { 80 | uint corner = extra; 81 | vec2 pos = vec2(buffer_float[data_pos+0], buffer_float[data_pos+1]); 82 | vec2 size = vec2(buffer_float[data_pos+2], buffer_float[data_pos+3]); 83 | vec2 uv0 = vec2(buffer_float[data_pos+4], buffer_float[data_pos+5]); 84 | vec2 uv1 = vec2(buffer_float[data_pos+6], buffer_float[data_pos+7]); 85 | uint col = floatBitsToUint(buffer_float[data_pos+8]); 86 | colour = unpackUnorm4x8(col); 87 | texture_id = floatBitsToUint(buffer_float[data_pos+9]); 88 | vec2 cc = corner_to_vec2(corner); 89 | position = pos + cc*size; 90 | v_position_origin = pos; 91 | v_size = size; 92 | v_uv = mix(uv0, uv1, cc); 93 | } else if (prim_kind == Prim_Kind_Poincare || prim_kind == Prim_Kind_Menu_Poincare) { 94 | uint corner = extra; 95 | vec2 pos = vec2(buffer_float[data_pos+0], buffer_float[data_pos+1]); 96 | vec2 size = vec2(buffer_float[data_pos+2], buffer_float[data_pos+3]); 97 | 98 | vec2 cc = corner_to_vec2(corner); 99 | position = pos + cc*size; 100 | 101 | v_position_origin = pos; 102 | v_size = size; 103 | v_uv = cc*2 - 1; 104 | if (size.x < size.y) { 105 | v_uv.y *= size.y/size.x; 106 | } else { 107 | v_uv.x *= size.x/size.y; 108 | } 109 | } else if (prim_kind == Prim_Kind_Entity) { 110 | uint corner = extra; 111 | vec2 pos = vec2(buffer_float[data_pos+0], buffer_float[data_pos+1]); 112 | vec2 size = vec2(buffer_float[data_pos+2], buffer_float[data_pos+3]); 113 | vec2 epos = vec2(buffer_float[data_pos+4], buffer_float[data_pos+5]); 114 | float erot = buffer_float[data_pos+6]; 115 | uint col = floatBitsToUint(buffer_float[data_pos+7]); 116 | colour = unpackUnorm4x8(col); 117 | uint ekind_and_vcount = floatBitsToUint(buffer_float[data_pos+8]); 118 | uint ekind = bitfieldExtract(ekind_and_vcount, 0, 16); 119 | uint vcount = bitfieldExtract(ekind_and_vcount, 16, 16); 120 | 121 | vec2 cc = corner_to_vec2(corner); 122 | position = pos + cc*size; 123 | 124 | v_position_origin = pos; 125 | v_size = size; 126 | v_uv = cc*2 - 1; 127 | if (size.x < size.y) { 128 | v_uv.y *= size.y/size.x; 129 | } else { 130 | v_uv.x *= size.x/size.y; 131 | } 132 | 133 | v_epos = epos; 134 | v_erot = erot; 135 | v_ekind = ekind; 136 | v_vcount = vcount; 137 | } 138 | 139 | 140 | float L = u_screen_rect.x; 141 | float T = u_screen_rect.y; 142 | float R = u_screen_rect.x + u_screen_rect.z; 143 | float B = u_screen_rect.y + u_screen_rect.w; 144 | 145 | mat4 ortho_projection = mat4( 146 | 2.0/(R-L), 0.0, 0.0, 0.0, 147 | 0.0, 2.0/(T-B), 0.0, 0.0, 148 | 0.0, 0.0, 1.0, 0.0, 149 | (R+L)/(L-R), (T+B)/(B-T), 0.0, 1.0 150 | ); 151 | 152 | v_position = position; 153 | v_colour = colour; 154 | v_sampler = u_samplers[texture_id].xy; 155 | v_texture_id = texture_id; 156 | 157 | vec4 position_ss = ortho_projection * vec4(position, 0, 1); 158 | v_position_ss = position_ss.xy / position_ss.w; 159 | gl_Position = position_ss; 160 | } 161 | -------------------------------------------------------------------------------- /src/glfw/bindings.odin: -------------------------------------------------------------------------------- 1 | package glfw_bindings 2 | 3 | import "core:os" 4 | 5 | when os.OS == "linux" do foreign import glfw "system:glfw"; 6 | when os.OS == "windows" do foreign import glfw { "glfw3.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" }; 7 | 8 | /*** Functions ***/ 9 | @(default_calling_convention="c", link_prefix="glfw") 10 | foreign glfw { 11 | Init :: proc() -> i32 ---; 12 | Terminate :: proc() ---; 13 | 14 | InitHint :: proc(hint, value: i32) ---; 15 | 16 | GetVersion :: proc(major, minor, rev: ^i32) ---; 17 | GetError :: proc(description: ^cstring) -> i32 ---; 18 | 19 | GetPrimaryMonitor :: proc() -> Monitor_Handle ---; 20 | GetMonitors :: proc(count: ^i32) -> ^Monitor_Handle ---; 21 | GetMonitorPos :: proc(monitor: Monitor_Handle, xpos, ypos: ^i32) ---; 22 | GetMonitorPhysicalSize :: proc(monitor: Monitor_Handle, widthMM, heightMM: ^i32) ---; 23 | GetMonitorContentScale :: proc(monitor: Monitor_Handle, xscale, yscale: ^f32) ---; 24 | 25 | SetMonitorUserPointer :: proc(monitor: Monitor_Handle, pointer: rawptr) ---; 26 | GetMonitorUserPointer :: proc(monitor: Monitor_Handle) -> rawptr ---; 27 | 28 | GetVideoMode :: proc(monitor: Monitor_Handle) -> ^Vid_Mode ---; 29 | SetGamma :: proc(monitor: Monitor_Handle, gamma: f32) ---; 30 | GetGammaRamp :: proc(monitor: Monitor_Handle) -> ^Gamma_Ramp ---; 31 | SetGammaRamp :: proc(monitor: Monitor_Handle, ramp: ^Gamma_Ramp) ---; 32 | 33 | CreateWindow :: proc(width, height: i32, title: cstring, monitor: Monitor_Handle, share: Window_Handle) -> Window_Handle ---; 34 | DestroyWindow :: proc(window: Window_Handle) ---; 35 | 36 | WindowHint :: proc(hint, value: i32) ---; 37 | DefaultWindowHints :: proc() ---; 38 | WindowHintString :: proc(hint: i32, value: cstring) ---; 39 | WindowShouldClose :: proc(window: Window_Handle) -> b32 ---; 40 | 41 | SwapInterval :: proc(interval: i32) ---; 42 | SwapBuffers :: proc(window: Window_Handle) ---; 43 | 44 | SetWindowTitle :: proc(window: Window_Handle, title: cstring) ---; 45 | SetWindowIcon :: proc(window: Window_Handle, count: i32, images: ^Image) ---; 46 | SetWindowPos :: proc(window: Window_Handle, xpos, ypos: i32) ---; 47 | SetWindowSizeLimits :: proc(window: Window_Handle, minwidth, minheight, maxwidth, maxheight: i32) ---; 48 | SetWindowAspectRatio :: proc(window: Window_Handle, numer, denom: i32) ---; 49 | SetWindowSize :: proc(window: Window_Handle, width, height: i32) ---; 50 | GetWindowPos :: proc(window: Window_Handle, xpos, ypos: ^i32) ---; 51 | GetWindowSize :: proc(window: Window_Handle, width, height: ^i32) ---; 52 | GetFramebufferSize :: proc(window: Window_Handle, width, height: ^i32) ---; 53 | GetWindowFrameSize :: proc(window: Window_Handle, left, top, right, bottom: ^i32) ---; 54 | 55 | GetWindowContentScale :: proc(window: Window_Handle, xscale, yscale: ^f32) ---; 56 | GetWindowOpacity :: proc(window: Window_Handle) -> f32 ---; 57 | SetWindowOpacity :: proc(window: Window_Handle, opacity: f32) ---; 58 | 59 | GetVersionString :: proc() -> cstring ---; 60 | GetMonitorName :: proc(monitor: Monitor_Handle) -> cstring ---; 61 | GetClipboardString :: proc(window: Window_Handle) -> cstring ---; 62 | GetVideoModes :: proc(monitor: Monitor_Handle, count: ^i32) -> ^Vid_Mode ---; 63 | GetKey :: proc(window: Window_Handle, key: i32) -> b32 ---; 64 | GetKeyName :: proc(key, scancode: i32) -> cstring ---; 65 | SetWindowShouldClose :: proc(window: Window_Handle, value: b32) ---; 66 | JoystickPresent :: proc(joy: i32) -> b32 ---; 67 | VulkanSupported :: proc() -> b32 ---; 68 | GetJoystickName :: proc(joy: i32) -> cstring ---; 69 | GetKeyScancode :: proc(key: i32) -> b32 ---; 70 | 71 | IconifyWindow :: proc(window: Window_Handle) ---; 72 | RestoreWindow :: proc(window: Window_Handle) ---; 73 | MaximizeWindow :: proc(window: Window_Handle) ---; 74 | ShowWindow :: proc(window: Window_Handle) ---; 75 | HideWindow :: proc(window: Window_Handle) ---; 76 | FocusWindow :: proc(window: Window_Handle) ---; 77 | 78 | RequestWindowAttention :: proc(window: Window_Handle) ---; 79 | 80 | GetWindowMonitor :: proc(window: Window_Handle) -> Monitor_Handle ---; 81 | SetWindowMonitor :: proc(window: Window_Handle, monitor: Monitor_Handle, xpos, ypos, width, height, refresh_rate: i32) ---; 82 | GetWindowAttrib :: proc(window: Window_Handle, attrib: i32) -> i32 ---; 83 | SetWindowUserPointer :: proc(window: Window_Handle, pointer: rawptr) ---; 84 | GetWindowUserPointer :: proc(window: Window_Handle) -> rawptr ---; 85 | 86 | SetWindowAttrib :: proc(window: Window_Handle, attrib, value: i32) ---; 87 | 88 | PollEvents :: proc() ---; 89 | WaitEvents :: proc() ---; 90 | WaitEventsTimeout :: proc(timeout: f64) ---; 91 | PostEmptyEvent :: proc() ---; 92 | 93 | GetInputMode :: proc(window: Window_Handle, mode: i32) -> i32 ---; 94 | SetInputMode :: proc(window: Window_Handle, mode, value: i32) ---; 95 | 96 | GetMouseButton :: proc(window: Window_Handle, button: i32) -> i32 ---; 97 | GetCursorPos :: proc(window: Window_Handle, xpos, ypos: ^f64) ---; 98 | SetCursorPos :: proc(window: Window_Handle, xpos, ypos: f64) ---; 99 | 100 | CreateCursor :: proc(image: ^Image, xhot, yhot: i32) -> Cursor_Handle ---; 101 | DestroyCursor :: proc(cursor: Cursor_Handle) ---; 102 | SetCursor :: proc(window: Window_Handle, cursor: Cursor_Handle) ---; 103 | CreateStandardCursor :: proc(shape: i32) -> Cursor_Handle ---; 104 | 105 | GetJoystickAxes :: proc(joy: i32, count: ^i32) -> ^f32 ---; 106 | GetJoystickButtons :: proc(joy: i32, count: ^i32) -> ^u8 ---; 107 | GetJoystickHats :: proc(jid: i32, count: ^i32) -> ^u8 ---; 108 | GetJoystickGUID :: proc(jid: i32) -> cstring ---; 109 | SetJoystickUserPointer :: proc(jid: i32, pointer: rawptr) ---; 110 | GetJoystickUserPointer :: proc(jid: i32) -> rawptr ---; 111 | JoystickIsGamepad :: proc(jid: i32) -> b32 ---; 112 | UpdateGamepadMappings :: proc(str: cstring) -> i32 ---; 113 | GetGamepadName :: proc(jid: i32) -> cstring ---; 114 | GetGamepadState :: proc(jid: i32, state: ^Gamepad_State) -> i32 ---; 115 | 116 | SetClipboardString :: proc(window: Window_Handle, str: cstring) ---; 117 | 118 | GetTime :: proc() -> f64 ---; 119 | SetTime :: proc(time: f64) ---; 120 | GetTimerValue :: proc() -> u64 ---; 121 | GetTimerFrequency :: proc() -> u64 ---; 122 | 123 | MakeContextCurrent :: proc(window: Window_Handle) ---; 124 | GetCurrentContext :: proc() -> Window_Handle ---; 125 | GetProcAddress :: proc(name: cstring) -> rawptr ---; 126 | ExtensionSupported :: proc(extension: cstring) -> b32 ---; 127 | 128 | GetRequiredInstanceExtensions :: proc(count: ^u32) -> ^cstring ---; 129 | 130 | SetWindowIconifyCallback :: proc(window: Window_Handle, cbfun: Window_Iconify_Proc) -> Window_Iconify_Proc ---; 131 | SetWindowRefreshCallback :: proc(window: Window_Handle, cbfun: Window_Refresh_Proc) -> Window_Refresh_Proc ---; 132 | SetWindowFocusCallback :: proc(window: Window_Handle, cbfun: Window_Focus_Proc) -> Window_Focus_Proc ---; 133 | SetWindowCloseCallback :: proc(window: Window_Handle, cbfun: Window_Close_Proc) -> Window_Close_Proc ---; 134 | SetWindowSizeCallback :: proc(window: Window_Handle, cbfun: Window_Size_Proc) -> Window_Size_Proc ---; 135 | SetWindowPosCallback :: proc(window: Window_Handle, cbfun: Window_Pos_Proc) -> Window_Pos_Proc ---; 136 | SetFramebufferSizeCallback :: proc(window: Window_Handle, cbfun: Framebuffer_Size_Proc) -> Framebuffer_Size_Proc ---; 137 | SetDropCallback :: proc(window: Window_Handle, cbfun: Drop_Proc) -> Drop_Proc ---; 138 | SetMonitorCallback :: proc(window: Window_Handle, cbfun: Monitor_Proc) -> Monitor_Proc ---; 139 | SetWindowMaximizeCallback :: proc(window: Window_Handle, cbfun: Window_Maximize_Proc) -> Window_Maximize_Proc ---; 140 | SetWindowContentScaleCallback :: proc(window: Window_Handle, cbfun: Window_Content_Scale_Proc) -> Window_Content_Scale_Proc ---; 141 | 142 | SetKeyCallback :: proc(window: Window_Handle, cbfun: Key_Proc) -> Key_Proc ---; 143 | SetMouseButtonCallback :: proc(window: Window_Handle, cbfun: Mouse_Button_Proc) -> Mouse_Button_Proc ---; 144 | SetCursorPosCallback :: proc(window: Window_Handle, cbfun: Cursor_Pos_Proc) -> Cursor_Pos_Proc ---; 145 | SetScrollCallback :: proc(window: Window_Handle, cbfun: Scroll_Proc) -> Scroll_Proc ---; 146 | SetCharCallback :: proc(window: Window_Handle, cbfun: Char_Proc) -> Char_Proc ---; 147 | SetCharModsCallback :: proc(window: Window_Handle, cbfun: Char_Mods_Proc) -> Char_Mods_Proc ---; 148 | SetCursorEnterCallback :: proc(window: Window_Handle, cbfun: Cursor_Enter_Proc) -> Cursor_Enter_Proc ---; 149 | SetJoystickCallback :: proc(window: Window_Handle, cbfun: Joystick_Proc) -> Joystick_Proc ---; 150 | 151 | SetErrorCallback :: proc(cbfun: Error_Proc) -> Error_Proc ---; 152 | 153 | } 154 | 155 | -------------------------------------------------------------------------------- /src/glfw/constants.odin: -------------------------------------------------------------------------------- 1 | package glfw_bindings 2 | 3 | /*** Constants ***/ 4 | /* Versions */ 5 | VERSION_MAJOR :: 3; 6 | VERSION_MINOR :: 3; 7 | VERSION_REVISION :: 0; 8 | 9 | /* Booleans */ 10 | TRUE :: 1; 11 | FALSE :: 0; 12 | 13 | /* Button/Key states */ 14 | RELEASE :: 0; 15 | PRESS :: 1; 16 | REPEAT :: 2; 17 | 18 | /* Joystick hat states. */ 19 | HAT_CENTERED :: 0; 20 | HAT_UP :: 1; 21 | HAT_RIGHT :: 2; 22 | HAT_DOWN :: 4; 23 | HAT_LEFT :: 8; 24 | HAT_RIGHT_UP ::(HAT_RIGHT | HAT_UP); 25 | HAT_RIGHT_DOWN ::(HAT_RIGHT | HAT_DOWN); 26 | HAT_LEFT_UP ::(HAT_LEFT | HAT_UP); 27 | HAT_LEFT_DOWN ::(HAT_LEFT | HAT_DOWN); 28 | 29 | /* The unknown key */ 30 | KEY_UNKNOWN :: -1; 31 | 32 | /** Printable keys **/ 33 | 34 | /* Named printable keys */ 35 | KEY_SPACE :: 32; 36 | KEY_APOSTROPHE :: 39; /* ' */ 37 | KEY_COMMA :: 44; /* , */ 38 | KEY_MINUS :: 45; /* - */ 39 | KEY_PERIOD :: 46; /* . */ 40 | KEY_SLASH :: 47; /* / */ 41 | KEY_SEMICOLON :: 59; /* ; */ 42 | KEY_EQUAL :: 61; /* :: */ 43 | KEY_LEFT_BRACKET :: 91; /* [ */ 44 | KEY_BACKSLASH :: 92; /* \ */ 45 | KEY_RIGHT_BRACKET :: 93; /* ] */ 46 | KEY_GRAVE_ACCENT :: 96; /* ` */ 47 | KEY_WORLD_1 :: 161; /* non-US #1 */ 48 | KEY_WORLD_2 :: 162; /* non-US #2 */ 49 | 50 | /* Alphanumeric characters */ 51 | KEY_0 :: 48; 52 | KEY_1 :: 49; 53 | KEY_2 :: 50; 54 | KEY_3 :: 51; 55 | KEY_4 :: 52; 56 | KEY_5 :: 53; 57 | KEY_6 :: 54; 58 | KEY_7 :: 55; 59 | KEY_8 :: 56; 60 | KEY_9 :: 57; 61 | 62 | KEY_A :: 65; 63 | KEY_B :: 66; 64 | KEY_C :: 67; 65 | KEY_D :: 68; 66 | KEY_E :: 69; 67 | KEY_F :: 70; 68 | KEY_G :: 71; 69 | KEY_H :: 72; 70 | KEY_I :: 73; 71 | KEY_J :: 74; 72 | KEY_K :: 75; 73 | KEY_L :: 76; 74 | KEY_M :: 77; 75 | KEY_N :: 78; 76 | KEY_O :: 79; 77 | KEY_P :: 80; 78 | KEY_Q :: 81; 79 | KEY_R :: 82; 80 | KEY_S :: 83; 81 | KEY_T :: 84; 82 | KEY_U :: 85; 83 | KEY_V :: 86; 84 | KEY_W :: 87; 85 | KEY_X :: 88; 86 | KEY_Y :: 89; 87 | KEY_Z :: 90; 88 | 89 | 90 | /** Function keys **/ 91 | 92 | /* Named non-printable keys */ 93 | KEY_ESCAPE :: 256; 94 | KEY_ENTER :: 257; 95 | KEY_TAB :: 258; 96 | KEY_BACKSPACE :: 259; 97 | KEY_INSERT :: 260; 98 | KEY_DELETE :: 261; 99 | KEY_RIGHT :: 262; 100 | KEY_LEFT :: 263; 101 | KEY_DOWN :: 264; 102 | KEY_UP :: 265; 103 | KEY_PAGE_UP :: 266; 104 | KEY_PAGE_DOWN :: 267; 105 | KEY_HOME :: 268; 106 | KEY_END :: 269; 107 | KEY_CAPS_LOCK :: 280; 108 | KEY_SCROLL_LOCK :: 281; 109 | KEY_NUM_LOCK :: 282; 110 | KEY_PRINT_SCREEN :: 283; 111 | KEY_PAUSE :: 284; 112 | 113 | /* Function keys */ 114 | KEY_F1 :: 290; 115 | KEY_F2 :: 291; 116 | KEY_F3 :: 292; 117 | KEY_F4 :: 293; 118 | KEY_F5 :: 294; 119 | KEY_F6 :: 295; 120 | KEY_F7 :: 296; 121 | KEY_F8 :: 297; 122 | KEY_F9 :: 298; 123 | KEY_F10 :: 299; 124 | KEY_F11 :: 300; 125 | KEY_F12 :: 301; 126 | KEY_F13 :: 302; 127 | KEY_F14 :: 303; 128 | KEY_F15 :: 304; 129 | KEY_F16 :: 305; 130 | KEY_F17 :: 306; 131 | KEY_F18 :: 307; 132 | KEY_F19 :: 308; 133 | KEY_F20 :: 309; 134 | KEY_F21 :: 310; 135 | KEY_F22 :: 311; 136 | KEY_F23 :: 312; 137 | KEY_F24 :: 313; 138 | KEY_F25 :: 314; 139 | 140 | /* Keypad numbers */ 141 | KEY_KP_0 :: 320; 142 | KEY_KP_1 :: 321; 143 | KEY_KP_2 :: 322; 144 | KEY_KP_3 :: 323; 145 | KEY_KP_4 :: 324; 146 | KEY_KP_5 :: 325; 147 | KEY_KP_6 :: 326; 148 | KEY_KP_7 :: 327; 149 | KEY_KP_8 :: 328; 150 | KEY_KP_9 :: 329; 151 | 152 | /* Keypad named function keys */ 153 | KEY_KP_DECIMAL :: 330; 154 | KEY_KP_DIVIDE :: 331; 155 | KEY_KP_MULTIPLY :: 332; 156 | KEY_KP_SUBTRACT :: 333; 157 | KEY_KP_ADD :: 334; 158 | KEY_KP_ENTER :: 335; 159 | KEY_KP_EQUAL :: 336; 160 | 161 | /* Modifier keys */ 162 | KEY_LEFT_SHIFT :: 340; 163 | KEY_LEFT_CONTROL :: 341; 164 | KEY_LEFT_ALT :: 342; 165 | KEY_LEFT_SUPER :: 343; 166 | KEY_RIGHT_SHIFT :: 344; 167 | KEY_RIGHT_CONTROL :: 345; 168 | KEY_RIGHT_ALT :: 346; 169 | KEY_RIGHT_SUPER :: 347; 170 | KEY_MENU :: 348; 171 | 172 | KEY_LAST :: KEY_MENU; 173 | 174 | /* Bitmask for modifier keys */ 175 | MOD_SHIFT :: 0x0001; 176 | MOD_CONTROL :: 0x0002; 177 | MOD_ALT :: 0x0004; 178 | MOD_SUPER :: 0x0008; 179 | MOD_CAPS_LOCK :: 0x0010; 180 | MOD_NUM_LOCK :: 0x0020; 181 | 182 | /* Mouse buttons */ 183 | MOUSE_BUTTON_1 :: 0; 184 | MOUSE_BUTTON_2 :: 1; 185 | MOUSE_BUTTON_3 :: 2; 186 | MOUSE_BUTTON_4 :: 3; 187 | MOUSE_BUTTON_5 :: 4; 188 | MOUSE_BUTTON_6 :: 5; 189 | MOUSE_BUTTON_7 :: 6; 190 | MOUSE_BUTTON_8 :: 7; 191 | 192 | /* Mousebutton aliases */ 193 | MOUSE_BUTTON_LAST :: MOUSE_BUTTON_8; 194 | MOUSE_BUTTON_LEFT :: MOUSE_BUTTON_1; 195 | MOUSE_BUTTON_RIGHT :: MOUSE_BUTTON_2; 196 | MOUSE_BUTTON_MIDDLE :: MOUSE_BUTTON_3; 197 | 198 | /* Joystick buttons */ 199 | JOYSTICK_1 :: 0; 200 | JOYSTICK_2 :: 1; 201 | JOYSTICK_3 :: 2; 202 | JOYSTICK_4 :: 3; 203 | JOYSTICK_5 :: 4; 204 | JOYSTICK_6 :: 5; 205 | JOYSTICK_7 :: 6; 206 | JOYSTICK_8 :: 7; 207 | JOYSTICK_9 :: 8; 208 | JOYSTICK_10 :: 9; 209 | JOYSTICK_11 :: 10; 210 | JOYSTICK_12 :: 11; 211 | JOYSTICK_13 :: 12; 212 | JOYSTICK_14 :: 13; 213 | JOYSTICK_15 :: 14; 214 | JOYSTICK_16 :: 15; 215 | 216 | JOYSTICK_LAST :: JOYSTICK_16; 217 | 218 | /* Gamepad buttons */ 219 | GAMEPAD_BUTTON_A :: 0; 220 | GAMEPAD_BUTTON_B :: 1; 221 | GAMEPAD_BUTTON_X :: 2; 222 | GAMEPAD_BUTTON_Y :: 3; 223 | GAMEPAD_BUTTON_LEFT_BUMPER :: 4; 224 | GAMEPAD_BUTTON_RIGHT_BUMPER :: 5; 225 | GAMEPAD_BUTTON_BACK :: 6; 226 | GAMEPAD_BUTTON_START :: 7; 227 | GAMEPAD_BUTTON_GUIDE :: 8; 228 | GAMEPAD_BUTTON_LEFT_THUMB :: 9; 229 | GAMEPAD_BUTTON_RIGHT_THUMB :: 10; 230 | GAMEPAD_BUTTON_DPAD_UP :: 11; 231 | GAMEPAD_BUTTON_DPAD_RIGHT :: 12; 232 | GAMEPAD_BUTTON_DPAD_DOWN :: 13; 233 | GAMEPAD_BUTTON_DPAD_LEFT :: 14; 234 | GAMEPAD_BUTTON_LAST :: GAMEPAD_BUTTON_DPAD_LEFT; 235 | 236 | GAMEPAD_BUTTON_CROSS :: GAMEPAD_BUTTON_A; 237 | GAMEPAD_BUTTON_CIRCLE :: GAMEPAD_BUTTON_B; 238 | GAMEPAD_BUTTON_SQUARE :: GAMEPAD_BUTTON_X; 239 | GAMEPAD_BUTTON_TRIANGLE :: GAMEPAD_BUTTON_Y; 240 | 241 | /* Gamepad axes */ 242 | GAMEPAD_AXIS_LEFT_X :: 0; 243 | GAMEPAD_AXIS_LEFT_Y :: 1; 244 | GAMEPAD_AXIS_RIGHT_X :: 2; 245 | GAMEPAD_AXIS_RIGHT_Y :: 3; 246 | GAMEPAD_AXIS_LEFT_TRIGGER :: 4; 247 | GAMEPAD_AXIS_RIGHT_TRIGGER :: 5; 248 | GAMEPAD_AXIS_LAST :: GAMEPAD_AXIS_RIGHT_TRIGGER; 249 | 250 | /* Error constants */ 251 | NO_ERROR :: 0x00000000; 252 | NOT_INITIALIZED :: 0x00010001; 253 | NO_CURRENT_CONTEXT :: 0x00010002; 254 | INVALID_ENUM :: 0x00010003; 255 | INVALID_VALUE :: 0x00010004; 256 | OUT_OF_MEMORY :: 0x00010005; 257 | API_UNAVAILABLE :: 0x00010006; 258 | VERSION_UNAVAILABLE :: 0x00010007; 259 | PLATFORM_ERROR :: 0x00010008; 260 | FORMAT_UNAVAILABLE :: 0x00010009; 261 | NO_WINDOW_CONTEXT :: 0x0001000A; 262 | 263 | /* Window attributes */ 264 | FOCUSED :: 0x00020001; 265 | ICONIFIED :: 0x00020002; 266 | RESIZABLE :: 0x00020003; 267 | VISIBLE :: 0x00020004; 268 | DECORATED :: 0x00020005; 269 | AUTO_ICONIFY :: 0x00020006; 270 | FLOATING :: 0x00020007; 271 | MAXIMIZED :: 0x00020008; 272 | CENTER_CURSOR :: 0x00020009; 273 | TRANSPARENT_FRAMEBUFFER :: 0x0002000A; 274 | HOVERED :: 0x0002000B; 275 | FOCUS_ON_SHOW :: 0x0002000C; 276 | 277 | /* Pixel window attributes */ 278 | RED_BITS :: 0x00021001; 279 | GREEN_BITS :: 0x00021002; 280 | BLUE_BITS :: 0x00021003; 281 | ALPHA_BITS :: 0x00021004; 282 | DEPTH_BITS :: 0x00021005; 283 | STENCIL_BITS :: 0x00021006; 284 | ACCUM_RED_BITS :: 0x00021007; 285 | ACCUM_GREEN_BITS :: 0x00021008; 286 | ACCUM_BLUE_BITS :: 0x00021009; 287 | ACCUM_ALPHA_BITS :: 0x0002100A; 288 | AUX_BUFFERS :: 0x0002100B; 289 | STEREO :: 0x0002100C; 290 | SAMPLES :: 0x0002100D; 291 | SRGB_CAPABLE :: 0x0002100E; 292 | REFRESH_RATE :: 0x0002100F; 293 | DOUBLEBUFFER :: 0x00021010; 294 | 295 | /* Context window attributes */ 296 | CLIENT_API :: 0x00022001; 297 | CONTEXT_VERSION_MAJOR :: 0x00022002; 298 | CONTEXT_VERSION_MINOR :: 0x00022003; 299 | CONTEXT_REVISION :: 0x00022004; 300 | CONTEXT_ROBUSTNESS :: 0x00022005; 301 | OPENGL_FORWARD_COMPAT :: 0x00022006; 302 | OPENGL_DEBUG_CONTEXT :: 0x00022007; 303 | OPENGL_PROFILE :: 0x00022008; 304 | CONTEXT_RELEASE_BEHAVIOR :: 0x00022009; 305 | CONTEXT_NO_ERROR :: 0x0002200A; 306 | CONTEXT_CREATION_API :: 0x0002200B; 307 | SCALE_TO_MONITOR :: 0x0002200C; 308 | 309 | /* Cross platform attributes */ 310 | COCOA_RETINA_FRAMEBUFFER :: 0x00023001; 311 | COCOA_FRAME_NAME :: 0x00023002; 312 | COCOA_GRAPHICS_SWITCHING :: 0x00023003; 313 | X11_CLASS_NAME :: 0x00024001; 314 | X11_INSTANCE_NAME :: 0x00024002; 315 | 316 | /* APIs */ 317 | NO_API :: 0; 318 | OPENGL_API :: 0x00030001; 319 | OPENGL_ES_API :: 0x00030002; 320 | 321 | /* Robustness? */ 322 | NO_ROBUSTNESS :: 0; 323 | NO_RESET_NOTIFICATION :: 0x00031001; 324 | LOSE_CONTEXT_ON_RESET :: 0x00031002; 325 | 326 | /* OpenGL Profiles */ 327 | OPENGL_ANY_PROFILE :: 0; 328 | OPENGL_CORE_PROFILE :: 0x00032001; 329 | OPENGL_COMPAT_PROFILE :: 0x00032002; 330 | 331 | /* Cursor draw state and whether keys are sticky */ 332 | CURSOR :: 0x00033001; 333 | STICKY_KEYS :: 0x00033002; 334 | STICKY_MOUSE_BUTTONS :: 0x00033003; 335 | LOCK_KEY_MODS :: 0x00033004; 336 | 337 | /* Cursor draw state */ 338 | CURSOR_NORMAL :: 0x00034001; 339 | CURSOR_HIDDEN :: 0x00034002; 340 | CURSOR_DISABLED :: 0x00034003; 341 | 342 | /* Behavior? */ 343 | ANY_RELEASE_BEHAVIOR :: 0; 344 | RELEASE_BEHAVIOR_FLUSH :: 0x00035001; 345 | RELEASE_BEHAVIOR_NONE :: 0x00035002; 346 | 347 | /* Context API ? */ 348 | NATIVE_CONTEXT_API :: 0x00036001; 349 | EGL_CONTEXT_API :: 0x00036002; 350 | OSMESA_CONTEXT_API :: 0x00036003; 351 | 352 | /* Types of cursors */ 353 | ARROW_CURSOR :: 0x00036001; 354 | IBEAM_CURSOR :: 0x00036002; 355 | CROSSHAIR_CURSOR :: 0x00036003; 356 | HAND_CURSOR :: 0x00036004; 357 | HRESIZE_CURSOR :: 0x00036005; 358 | VRESIZE_CURSOR :: 0x00036006; 359 | RESIZE_NWSE_CURSOR :: 0x00036007; 360 | RESIZE_NESW_CURSOR :: 0x00036008; 361 | 362 | /* Joystick? */ 363 | CONNECTED :: 0x00040001; 364 | DISCONNECTED :: 0x00040002; 365 | 366 | /* macOS specific init hint. */ 367 | JOYSTICK_HAT_BUTTONS :: 0x00050001; 368 | COCOA_CHDIR_RESOURCES :: 0x00051001; 369 | COCOA_MENUBAR :: 0x00051002; 370 | 371 | /* */ 372 | DONT_CARE :: -1; 373 | -------------------------------------------------------------------------------- /src/draw.odin: -------------------------------------------------------------------------------- 1 | package ld47 2 | 3 | import "core:mem" 4 | import "core:sort" 5 | 6 | /* 7 | 0 8 | | 9 | |(6:2)custom data 10 | | | 11 | 00000000 00000000 00000000 00000000 12 | | | 13 | (0:6)prim_kind| 14 | | 15 | (8:24)offset into buffer 16 | 17 | Each primitive is aligned to 4 bytes for the GPU 18 | */ 19 | Vertex :: distinct u32; 20 | Rect :: struct { 21 | pos: [2]f32, 22 | size: [2]f32, 23 | } 24 | Colour :: struct{r, g, b, a: u8}; 25 | Colour_White :: Colour{255, 255, 255, 255}; 26 | Colour_Black :: Colour{0, 0, 0, 255}; 27 | 28 | Draw_List :: struct { 29 | allocator: mem.Allocator, 30 | 31 | vertex_buffer: []Vertex, 32 | sorted_vertex_buffer: []Vertex, 33 | vertex_len: int, 34 | 35 | primitive_buffer: []byte, 36 | primitive_size: int, 37 | 38 | commands: [dynamic]Draw_Command, 39 | 40 | temp_path: [dynamic][2]f32, 41 | } 42 | 43 | 44 | Draw_Command :: struct { 45 | z_index: i32, 46 | vertex_offset: u32, 47 | vertex_count: u32, 48 | texture: Texture_Id, 49 | } 50 | 51 | 52 | create_draw_list :: proc(vertex_buffer_len, primitive_size_in_bytes: int) -> ^Draw_List { 53 | dl := new(Draw_List); 54 | dl.allocator = context.allocator; 55 | 56 | dl.vertex_buffer = mem.make_aligned([]Vertex, vertex_buffer_len, 16); 57 | dl.sorted_vertex_buffer = mem.make_aligned([]Vertex, vertex_buffer_len, 16); 58 | dl.vertex_len = 0; 59 | dl.primitive_buffer = mem.make_aligned([]byte, primitive_size_in_bytes, 16); 60 | dl.primitive_size = 0; 61 | 62 | reserve(&dl.commands, 64); 63 | reserve(&dl.temp_path, 64); 64 | 65 | return dl; 66 | } 67 | 68 | destroy_draw_list :: proc(dl: ^Draw_List){ 69 | context.allocator = dl.allocator; 70 | delete(dl.commands); 71 | delete(dl.temp_path); 72 | delete(dl.vertex_buffer); 73 | delete(dl.sorted_vertex_buffer); 74 | delete(dl.primitive_buffer); 75 | free(dl); 76 | } 77 | 78 | 79 | begin_draw_list :: proc(dl: ^Draw_List) { 80 | dl.vertex_len = 0; 81 | dl.primitive_size = 16; // Reserve the first 16 bytes for nothing 82 | 83 | clear(&dl.commands); 84 | 85 | add_draw_command_on_texture_change(dl, .White); 86 | } 87 | 88 | end_draw_list :: proc(dl: ^Draw_List) { 89 | // pop unused draw commands 90 | if len(dl.commands) != 0 { 91 | cmd := &dl.commands[len(dl.commands)-1]; 92 | if cmd.vertex_count == 0 { 93 | pop(&dl.commands); 94 | } 95 | } 96 | 97 | // sort commands 98 | 99 | sort.quick_sort_proc(dl.commands[:], proc(x, y: Draw_Command) -> int { 100 | switch { 101 | case x.z_index < y.z_index: return -1; 102 | case x.z_index > y.z_index: return +1; 103 | 104 | case x.vertex_offset < y.vertex_offset: return -1; 105 | case x.vertex_offset > y.vertex_offset: return +1; 106 | } 107 | 108 | return 0; 109 | }); 110 | 111 | new_commands := make([]Draw_Command, len(dl.commands), context.temp_allocator); 112 | 113 | command_index := 0; 114 | offset := u32(0); 115 | 116 | for cmd in dl.commands { 117 | if cmd.vertex_count == 0 { 118 | continue; 119 | } 120 | 121 | copy(dl.sorted_vertex_buffer[offset:], dl.vertex_buffer[cmd.vertex_offset:][:cmd.vertex_count]); 122 | 123 | use_new_command := true; 124 | if command_index > 0 { 125 | prev := &new_commands[command_index-1]; 126 | if prev.texture == cmd.texture { 127 | prev.vertex_count += cmd.vertex_count; 128 | use_new_command = false; 129 | } 130 | } 131 | 132 | if use_new_command { 133 | new_commands[command_index] = Draw_Command{ 134 | vertex_offset = offset, 135 | vertex_count = cmd.vertex_count, 136 | texture = cmd.texture, 137 | }; 138 | command_index += 1; 139 | } 140 | 141 | offset += cmd.vertex_count; 142 | } 143 | 144 | resize(&dl.commands, command_index); 145 | copy(dl.commands[:], new_commands[:]); 146 | assert(u32(dl.vertex_len) == offset); // sanity check 147 | } 148 | 149 | add_draw_command_on_texture_change :: proc(dl: ^Draw_List, texture: Texture_Id) { 150 | prev_z_index := i32(0); 151 | if len(dl.commands) != 0 { 152 | prev := &dl.commands[len(dl.commands)-1]; 153 | if prev.texture == texture { 154 | return; 155 | } 156 | prev_z_index = prev.z_index; 157 | } 158 | append(&dl.commands, Draw_Command{ 159 | z_index = prev_z_index, 160 | vertex_offset = u32(dl.vertex_len), 161 | vertex_count = 0, 162 | texture = texture, 163 | }); 164 | } 165 | add_draw_command_on_z_index :: proc(dl: ^Draw_List, z_index: i32) { 166 | prev_texture := Texture_Id(0); 167 | if len(dl.commands) != 0 { 168 | prev := &dl.commands[len(dl.commands)-1]; 169 | if prev.z_index == z_index { 170 | return; 171 | } 172 | prev_texture = prev.texture; 173 | } 174 | append(&dl.commands, Draw_Command{ 175 | z_index = z_index, 176 | vertex_offset = u32(dl.vertex_len), 177 | vertex_count = 0, 178 | texture = prev_texture, 179 | }); 180 | } 181 | 182 | 183 | PRIM_ALIGNMENT_SHIFT :: 2; // 2 == 4 Bytes, 4 == 16 Bytes 184 | PRIM_ALIGNMENT :: 1< (ptr: ^T, offset: u32) { 187 | if dl.primitive_size+size_of(T) > len(dl.primitive_buffer) { 188 | panic("draw list primitive buffer overflow"); 189 | } 190 | 191 | base := uintptr(raw_data(dl.primitive_buffer)); 192 | u_offset := uintptr(dl.primitive_size); 193 | ptr = (^T)(base + u_offset); 194 | 195 | dl.primitive_size += size_of(T); 196 | dl.primitive_size = mem.align_forward_int(dl.primitive_size, PRIM_ALIGNMENT); 197 | 198 | offset = u32(u_offset >> PRIM_ALIGNMENT_SHIFT) & 0x00ffffff; 199 | return; 200 | } 201 | 202 | prim_resize :: proc(dl: ^Draw_List, vertex_count: int) -> (vertex_write: []Vertex, ok: bool) { 203 | MAX_VERTEX_COUNT :: 1<<24; 204 | 205 | assert(0 <= vertex_count && vertex_count <= MAX_VERTEX_COUNT); 206 | 207 | n := dl.vertex_len; 208 | if len(dl.vertex_buffer) < n+vertex_count { 209 | return; 210 | } 211 | 212 | cmd := &dl.commands[len(dl.commands)-1]; 213 | cmd.vertex_count += u32(vertex_count); 214 | vertex_write = dl.vertex_buffer[n:][:vertex_count]; 215 | dl.vertex_len += vertex_count; 216 | ok = true; 217 | return; 218 | } 219 | 220 | 221 | Prim_Kind :: enum u8 { 222 | Invalid = 0, 223 | Rect = 1, 224 | Rect_Textured = 2, 225 | 226 | Poincare = 16, 227 | Entity = 17, 228 | Menu_Poincare = 18, 229 | }; 230 | 231 | #assert(int(max(Prim_Kind)) < 1<<6); 232 | 233 | Prim_Rect :: struct { 234 | pos: [2]f32, 235 | size: [2]f32, 236 | col: Colour, 237 | } 238 | 239 | Prim_Rect_Textured :: struct { 240 | pos: [2]f32, 241 | size: [2]f32, 242 | uv0: [2]f32, 243 | uv1: [2]f32, 244 | col: Colour, 245 | texture: Texture_Id, 246 | } 247 | 248 | Prim_Poincare :: struct { 249 | rect: Rect, 250 | } 251 | 252 | Prim_Entity_Kind :: enum u16 { 253 | Invalid = 0, 254 | Player = 1, 255 | Projectile = 2, 256 | Enemy = 3, 257 | } 258 | 259 | Prim_Entity :: struct { 260 | rect: Rect, 261 | pos: [2]f32, 262 | rot: f32, 263 | col: Colour, 264 | kind: Prim_Entity_Kind, 265 | vertices: u16, 266 | } 267 | 268 | 269 | 270 | 271 | add_rect :: proc(dl: ^Draw_List, pos, size: [2]f32, col: Colour) #no_bounds_check { 272 | add_draw_command_on_texture_change(dl, .White); 273 | 274 | vertex_write, ok := prim_resize(dl, 6); 275 | if !ok { 276 | return; 277 | } 278 | 279 | r, offset := new_prim(dl, Prim_Rect); 280 | r.pos = pos; 281 | r.size = size; 282 | r.col = col; 283 | 284 | v := Vertex(Prim_Kind.Rect); 285 | v |= Vertex(offset<<8); 286 | 287 | vertex_write[0] = v | (0 << 6); 288 | vertex_write[1] = v | (1 << 6); 289 | vertex_write[2] = v | (2 << 6); 290 | vertex_write[3] = v | (2 << 6); 291 | vertex_write[4] = v | (3 << 6); 292 | vertex_write[5] = v | (0 << 6); 293 | } 294 | 295 | add_rect_textured :: proc(dl: ^Draw_List, texture: Texture_Id, pos, size: [2]f32, uv0 := [2]f32{0, 0}, uv1 := [2]f32{1, 1}, col := Colour_White) #no_bounds_check { 296 | add_draw_command_on_texture_change(dl, texture); 297 | 298 | vertex_write, ok := prim_resize(dl, 6); 299 | if !ok { 300 | return; 301 | } 302 | 303 | r, offset := new_prim(dl, Prim_Rect_Textured); 304 | r.pos = pos; 305 | r.size = size; 306 | r.uv0 = uv0; 307 | r.uv1 = uv1; 308 | r.col = col; 309 | r.texture = texture; 310 | 311 | v := Vertex(Prim_Kind.Rect_Textured); 312 | v |= Vertex(offset<<8); 313 | 314 | vertex_write[0] = v | (0 << 6); 315 | vertex_write[1] = v | (1 << 6); 316 | vertex_write[2] = v | (2 << 6); 317 | vertex_write[3] = v | (2 << 6); 318 | vertex_write[4] = v | (3 << 6); 319 | vertex_write[5] = v | (0 << 6); 320 | } 321 | 322 | 323 | add_poincare :: proc(dl: ^Draw_List, rect: Rect) #no_bounds_check { 324 | add_draw_command_on_texture_change(dl, .White); 325 | 326 | vertex_write, ok := prim_resize(dl, 6); 327 | if !ok { 328 | return; 329 | } 330 | 331 | r, offset := new_prim(dl, Prim_Poincare); 332 | r.rect = rect; 333 | 334 | v := Vertex(Prim_Kind.Poincare); 335 | v |= Vertex(offset<<8); 336 | 337 | vertex_write[0] = v | (0 << 6); 338 | vertex_write[1] = v | (1 << 6); 339 | vertex_write[2] = v | (2 << 6); 340 | vertex_write[3] = v | (2 << 6); 341 | vertex_write[4] = v | (3 << 6); 342 | vertex_write[5] = v | (0 << 6); 343 | } 344 | 345 | 346 | 347 | add_menu_poincare :: proc(dl: ^Draw_List, rect: Rect) #no_bounds_check { 348 | add_draw_command_on_texture_change(dl, .White); 349 | 350 | vertex_write, ok := prim_resize(dl, 6); 351 | if !ok { 352 | return; 353 | } 354 | 355 | r, offset := new_prim(dl, Prim_Poincare); 356 | r.rect = rect; 357 | 358 | v := Vertex(Prim_Kind.Menu_Poincare); 359 | v |= Vertex(offset<<8); 360 | 361 | vertex_write[0] = v | (0 << 6); 362 | vertex_write[1] = v | (1 << 6); 363 | vertex_write[2] = v | (2 << 6); 364 | vertex_write[3] = v | (2 << 6); 365 | vertex_write[4] = v | (3 << 6); 366 | vertex_write[5] = v | (0 << 6); 367 | } 368 | 369 | add_entity :: proc(dl: ^Draw_List, rect: Rect, kind: Prim_Entity_Kind, pos: [2]f32, rot: f32, col: Colour, vertices: u16) #no_bounds_check { 370 | add_draw_command_on_texture_change(dl, .White); 371 | 372 | vertex_write, ok := prim_resize(dl, 6); 373 | if !ok { 374 | return; 375 | } 376 | 377 | r, offset := new_prim(dl, Prim_Entity); 378 | r.rect = rect; 379 | r.pos = pos; 380 | r.rot = rot; 381 | r.col = col; 382 | r.kind = kind; 383 | r.vertices = clamp(vertices, 3, 64); 384 | 385 | v := Vertex(Prim_Kind.Entity); 386 | v |= Vertex(offset<<8); 387 | 388 | vertex_write[0] = v | (0 << 6); 389 | vertex_write[1] = v | (1 << 6); 390 | vertex_write[2] = v | (2 << 6); 391 | vertex_write[3] = v | (2 << 6); 392 | vertex_write[4] = v | (3 << 6); 393 | vertex_write[5] = v | (0 << 6); 394 | } 395 | 396 | 397 | -------------------------------------------------------------------------------- /src/frag.glsl: -------------------------------------------------------------------------------- 1 | #version 450 core 2 | #extension GL_ARB_bindless_texture : require 3 | #extension GL_ARB_gpu_shader5 : require 4 | 5 | #define Prim_Kind_Invalid 0 6 | #define Prim_Kind_Rect 1 7 | #define Prim_Kind_Rect_Textured 2 8 | #define Prim_Kind_Poincare 16 9 | #define Prim_Kind_Entity 17 10 | #define Prim_Kind_Menu_Poincare 18 11 | 12 | 13 | #define PI 3.14159265 14 | #define TAU 6.28318531 15 | 16 | #define ARENA_RADIUS 0.862 17 | 18 | layout(location=1) uniform float u_time; 19 | 20 | #if 1 21 | #define N 5 22 | #define Q 4 23 | #elif 0 24 | #define N 3 25 | #define Q 8 26 | #else 27 | #define N 4 28 | #define Q 5 29 | #endif 30 | 31 | in flat uint v_prim_kind; 32 | 33 | in vec2 v_position; 34 | in vec2 v_position_ss; 35 | in vec2 v_size; 36 | in vec4 v_colour; 37 | in vec2 v_uv; 38 | 39 | in vec2 v_epos; 40 | in float v_erot; 41 | in flat uint v_ekind; 42 | in flat uint v_vcount; 43 | in flat uvec2 v_sampler; 44 | in flat uint v_texture_id; 45 | 46 | out vec4 o_colour; 47 | 48 | 49 | mat2 rot2(in float a) { 50 | float c = cos(a); 51 | float s = sin(a); 52 | return mat2(c, -s, s, c); 53 | } 54 | 55 | float hasher(in vec2 p) { 56 | return fract(111231 * sin(dot(p, vec2(127, 63)))); 57 | } 58 | 59 | void swap(inout int a, inout int b) { 60 | int tmp = a; a = b; b = tmp; 61 | } 62 | 63 | float smooth_floor(float x, float c) { 64 | 65 | float ix = floor(x); 66 | x -= ix; 67 | return (pow(x, c) - pow(1.0- x, c))*0.5 + ix; 68 | } 69 | 70 | 71 | vec3 init_domain() { 72 | float pi_div_n = PI/float(N); 73 | float pi_div_q = pi_div_n + PI/float(Q) - PI*0.5; 74 | 75 | vec2 t1 = vec2(cos(pi_div_n), sin(pi_div_n)); 76 | vec2 t2 = vec2(cos(pi_div_q), sin(pi_div_q)); 77 | 78 | float dist = t1.x - t2.x*t1.y/t2.y; 79 | float r = length(vec2(dist, 0) - t1); 80 | 81 | float d = max(dist*dist - r*r, 0.0); 82 | 83 | return vec3(dist, r, 1)/sqrt(d); 84 | } 85 | 86 | vec2 transform(vec2 p, vec2 circ, inout float count) { 87 | float ia = (floor(atan(p.x, p.y)/TAU*float(N)) + 0.5)/float(N); 88 | vec2 vert = rot2(ia*TAU)*vec2(0, circ.x); 89 | float r2 = circ.y*circ.y; 90 | vec2 pc = p - vert; 91 | float l2 = dot(pc, pc); 92 | if (l2 < r2) { 93 | p = pc*r2/l2 + vert; 94 | p = rot2(TAU/float(N)*(count + float(Q)))*p; 95 | count++; 96 | } 97 | return p; 98 | } 99 | 100 | float sdf_bezier(vec2 pos, vec2 A, vec2 B, vec2 C) { 101 | vec2 a = B - A; 102 | vec2 b = A - 2.0*B + C; 103 | vec2 c = a * 2.0; 104 | vec2 d = A - pos; 105 | 106 | float kk = 1.0/max(dot(b,b), 1e-6); 107 | float kx = kk * dot(a,b); 108 | float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0; 109 | float kz = kk * dot(d,a); 110 | 111 | float res = 0.0; 112 | 113 | float p = ky - kx*kx; 114 | float p3 = p*p*p; 115 | float q = kx*(2.0*kx*kx - 3.0*ky) + kz; 116 | float h = q*q + 4.0*p3; 117 | 118 | if (h >= 0.0) { 119 | h = sqrt(h); 120 | vec2 x = (vec2(h, -h) - q) * 0.5; 121 | vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0)); 122 | float t = uv.x + uv.y - kx; 123 | t = clamp(t, 0.0, 1.0); 124 | 125 | // 1 root 126 | vec2 qos = d + (c + b*t)*t; 127 | res = length(qos); 128 | } else { 129 | float z = sqrt(-p); 130 | float v = acos( q/(p*z*2.0) ) / 3.0; 131 | float m = cos(v); 132 | float n = sin(v)*1.732050808; 133 | vec3 t = vec3(m + m, -n - m, n - m) * z - kx; 134 | t = clamp(t, 0.0, 1.0); 135 | 136 | // 3 roots 137 | vec2 qos = d + (c + b*t.x)*t.x; 138 | float dis = dot(qos,qos); 139 | 140 | res = dis; 141 | 142 | qos = d + (c + b*t.y)*t.y; 143 | dis = dot(qos,qos); 144 | res = min(res,dis); 145 | 146 | qos = d + (c + b*t.z)*t.z; 147 | dis = dot(qos,qos); 148 | res = min(res,dis); 149 | 150 | res = sqrt(res); 151 | } 152 | 153 | return res; 154 | } 155 | 156 | float do_line_segment(vec2 p, vec4 a, vec4 b, float r) { 157 | vec2 mid = mix(a.xy, b.xy, 0.5); 158 | 159 | p = rot2(cos(u_time*0.05)) * p; 160 | 161 | float l = length(b.xy - a.xy)*1.732/6.0; 162 | if (abs(length(b.zw - a.zw)) < 0.01) { 163 | l = r; 164 | } 165 | mid += mix(a.zw, b.zw, 0.5)*l; 166 | float b1 = sdf_bezier(p, a.xy, a.xy + a.zw*l, mid); 167 | float b2 = sdf_bezier(p, mid, b.xy + b.zw*l, b.xy); 168 | return min(b1, b2); 169 | } 170 | 171 | 172 | vec2 inversion(in vec2 uv, vec2 p) { 173 | // STUPID SINGULARITIES 174 | if (length(p) < 0.05) { 175 | p += 0.05; 176 | } 177 | if (abs(p.x) > 0.95*sqrt(2.0) || abs(p.y) > 0.95*sqrt(2.0)) { 178 | p *= 0.95; 179 | } 180 | 181 | float k = 1.0/dot(p, p); 182 | vec2 ip = k*p; 183 | float t = (k - 1.0)/dot(uv - ip, uv - ip); 184 | uv = t*uv + (1.0 - t)*ip; 185 | uv.x = -uv.x; // preserve chirality 186 | 187 | return uv; 188 | } 189 | 190 | float polygon(vec2 p, float vertices, float radius, float rot_angle) { 191 | float segment_angle = TAU/vertices; 192 | float angle = atan(p.x, p.y) + rot_angle; 193 | float repeat = mod(angle, segment_angle) - segment_angle*0.5; 194 | float inner_radius = radius * cos(segment_angle*0.5); 195 | float circle = length(p); 196 | return cos(repeat) * circle - inner_radius; 197 | 198 | } 199 | 200 | vec3 poincare_truchet(vec2 uv) { 201 | uv *= 1.1; 202 | 203 | vec2 p = uv; 204 | 205 | vec2 op = p; 206 | 207 | { 208 | vec2 m = vec2(0, 0); 209 | float t = u_time; 210 | m.x = 0.8*cos(t*0.003); 211 | m.y = 0.8*sin(t*0.003); 212 | if (length(uv) < 1) { 213 | // m = vec2(0, 0); 214 | } 215 | p = inversion(p, m); 216 | } 217 | 218 | float count = 0.0; 219 | 220 | vec3 domain_info = init_domain(); 221 | 222 | for (int i = 0; i < 12; i++) { 223 | p = transform(p, domain_info.xy, count); 224 | } 225 | if (length(p) > 1.0) { 226 | p /= dot(p, p); 227 | } 228 | 229 | p /= domain_info.z; 230 | 231 | 232 | float shape = polygon(p, float(N), 0.9, 0); 233 | 234 | vec2 vertex_points[N]; 235 | float line_points[N]; 236 | 237 | const int N2 = N*2; 238 | vec4 mp[N2]; 239 | int shuff[N2]; 240 | 241 | float vert = 1e6; 242 | vec2 v0 = vec2(0, 1); 243 | 244 | for (int i = 0; i < N; i++) { 245 | vert = min(vert, length(p - v0) - 0.09); 246 | vertex_points[i] = v0; 247 | v0 = rot2(TAU/float(N)) * v0; 248 | } 249 | 250 | vec2 rp = rot2(float(count + 2.0) * TAU/float(N)) * p; 251 | float angle = mod(atan(rp.x, rp.y), TAU) * float(N2) / TAU; 252 | float polygon_seg = (smooth_floor(angle, 0.01) + 0.5) / float(N2); 253 | 254 | vec3 col_scheme = vec3(1); 255 | col_scheme = 0.4 + 0.6*cos(polygon_seg*TAU + vec3(1, 2, 3)); 256 | 257 | 258 | float smoothing_factor = 0.01; 259 | 260 | vec3 col = vec3(1.00, 1.00, 1.00); 261 | col = mix(col, vec3(0), 1.0 - smoothstep(0.0, smoothing_factor, shape)); 262 | col = mix(col, col_scheme, 1.0 - smoothstep(0.0, smoothing_factor, shape + 0.05)); 263 | col = pow(col, vec3(1.0/2.2)); 264 | 265 | 266 | float side_length = length(vertex_points[0] - vertex_points[1]); 267 | 268 | for (int i = 0; i < N; i++) { 269 | shuff[i*2] = i*2; 270 | shuff[i*2 + 1] = i*2 + 1; 271 | 272 | vec2 mpi = mix(vertex_points[i], vertex_points[(i + 1)%N], 0.5); 273 | vec2 tangent_i = normalize(mpi - vertex_points[i]); 274 | 275 | mp[i*2].xy = mpi - tangent_i*side_length/6.0; 276 | mp[i*2 + 1].xy = mpi + tangent_i*side_length/6.0; 277 | 278 | mp[i*2].zw = tangent_i.yx * vec2(1, -1); 279 | mp[i*2 + 1].zw = tangent_i.yx * vec2(1, -1); 280 | } 281 | 282 | for (int i = N2 - 1; i > 0; i--) { 283 | float fi = float(i); 284 | float rs = hasher(vec2(count) + domain_info.xy + domain_info.z + fi/float(N2)); 285 | int j = int(floor(rs*(fi + 0.9999))); 286 | swap(shuff[i], shuff[j]); 287 | } 288 | 289 | for (int i = 0; i < N; i++) { 290 | int j = shuff[i*2]; 291 | int jp = shuff[i*2 + 1]; 292 | 293 | float line_off = side_length*1.0; 294 | line_points[i] = do_line_segment(p, mp[j], mp[jp], line_off) - 0.03; 295 | } 296 | 297 | 298 | float ring_blend = smoothstep(0.0, 0.2, abs(length(uv) - 1.0) - 0.1); 299 | float pat = abs(fract(shape*12.0) - 0.5)*2.0 - 0.05; 300 | col = mix(col, vec3(0), ring_blend*(1.0 - smoothstep(0.0, 0.5, pat))*0.7); 301 | 302 | float lu = length(uv); 303 | 304 | for (int i = 0; i < N; i++) { 305 | pat = abs(fract(line_points[i]*12.0 + 0.5) - 0.5)*2 - 0.05; 306 | pat = mix(1.0, 0.0, ring_blend*(1.0 - smoothstep(0.0, 0.5, pat))*0.7); 307 | 308 | vec3 bg_col = col; 309 | vec3 c0 = col; 310 | c0 = mix(c0, vec3(0.0), 1.0 - smoothstep(0.0, smoothing_factor, line_points[i])); 311 | col = mix(col, c0, 1.0-step(length(uv), 1.0)); 312 | } 313 | 314 | 315 | float ring = abs(lu - 1.0) - 0.05; 316 | 317 | 318 | col = mix(col, vec3(0), 1.0 - smoothstep(0.0, smoothing_factor*0.5, ring)); 319 | 320 | col = abs(col); 321 | float coln = (col.r+col.g+col.b)/3.0; 322 | if (coln > 1) { 323 | col *= 1.0/coln; 324 | } 325 | 326 | // NOTE: Black and white on the inside 327 | if (dot(uv, uv) <= 1.0) { 328 | float x = max(max(col.r, col.g), col.b); 329 | col = vec3(x); 330 | } 331 | 332 | return col; 333 | } 334 | 335 | #define Prim_Entity_Invalid 0 336 | #define Prim_Entity_Player 1 337 | #define Prim_Entity_Projectile 2 338 | #define Prim_Entity_Enemy 3 339 | 340 | #define PLAYER_RADIUS 0.05 341 | #define PROJECTILE_RADIUS 0.02 342 | #define ENEMY_RADIUS_BASE 0.02 343 | 344 | 345 | float sdf_segment(in vec2 p, in vec2 a, in vec2 b, in float r) { 346 | vec2 pa = p-a; 347 | vec2 ba = b-a; 348 | float h = clamp(dot(pa, ba)/dot(ba, ba), 0.0, 1.0); 349 | return step(length(pa - ba*h), r); 350 | } 351 | 352 | void render_entity(inout vec4 colour, in vec2 uv, in vec2 pos, in float rot, in uint kind) { 353 | float r = 0.0; 354 | float vertices = float(v_vcount); 355 | vec2 p = inversion(uv, pos); 356 | float d = 0; 357 | switch (kind) { 358 | case Prim_Entity_Player: 359 | r = PLAYER_RADIUS; 360 | d = polygon(p, vertices, r, rot); 361 | break; 362 | case Prim_Entity_Projectile: 363 | r = PROJECTILE_RADIUS; 364 | d = polygon(p, vertices, r, rot); 365 | break; 366 | case Prim_Entity_Enemy: 367 | r = ENEMY_RADIUS_BASE * pow(vertices-3+1, 0.2); 368 | d = polygon(p, vertices, r, rot); 369 | break; 370 | default: 371 | return; 372 | } 373 | 374 | 375 | vec3 c = v_colour.rgb; 376 | colour.rgb = mix(colour.rgb, vec3(0), step(d, r)); 377 | colour.rgb = mix(colour.rgb, c, step(d, 0.86*r)); 378 | colour.a = mix(colour.a, v_colour.a, step(d, r)); 379 | 380 | if (kind == Prim_Entity_Player) { 381 | vec2 fire_dir = vec2(cos(rot), sin(rot)); 382 | fire_dir = normalize(inversion(pos + fire_dir*PLAYER_RADIUS, pos)); 383 | vec2 a = pos; 384 | vec2 b = pos + fire_dir*PLAYER_RADIUS*2; 385 | float d = sdf_segment(uv, a, b, 0.005); 386 | colour.rgb = mix(colour.rgb, vec3(0.1, 1, 0.2), d); 387 | colour.a = mix(colour.a, 1, d); 388 | } 389 | } 390 | 391 | 392 | vec3 psychedelic_text(vec2 uv) { 393 | uv = sin(uv*19.0) + cos(uv*13.0); 394 | 395 | vec3 col = 0.5 + 0.5*sin(PI * (1.2*uv.x+1.7*uv.y + u_time) + vec3(0.0, +2.0, -2.0)); 396 | col /= max(max(col.r, col.g), col.b); 397 | col = pow(col, vec3(0.05)); 398 | return col; 399 | } 400 | 401 | vec3 menu_truchet(vec2 uv) { 402 | uv *= 1.1; 403 | 404 | vec2 p = uv; 405 | 406 | vec2 op = p; 407 | 408 | { 409 | vec2 m = vec2(0, 0); 410 | float t = u_time; 411 | m.x = 0.8*cos(t*0.003); 412 | m.y = 0.8*sin(t*0.003); 413 | if (length(uv) < 1) { 414 | // m = vec2(0, 0); 415 | } 416 | p = inversion(p, m); 417 | } 418 | 419 | float count = 0.0; 420 | 421 | vec3 domain_info = init_domain(); 422 | 423 | for (int i = 0; i < 12; i++) { 424 | p = transform(p, domain_info.xy, count); 425 | } 426 | if (length(p) > 1.0) { 427 | p /= dot(p, p); 428 | } 429 | 430 | p /= domain_info.z; 431 | 432 | 433 | float shape_r = 0; 434 | shape_r = 0.9;; 435 | float shape = polygon(p, float(N), shape_r, 0); 436 | 437 | vec2 vertex_points[N]; 438 | float line_points[N]; 439 | 440 | const int N2 = N*2; 441 | vec4 mp[N2]; 442 | int shuff[N2]; 443 | 444 | float vert = 1e6; 445 | vec2 v0 = vec2(0, 1); 446 | 447 | for (int i = 0; i < N; i++) { 448 | vert = min(vert, length(p - v0) - 0.09); 449 | vertex_points[i] = v0; 450 | v0 = rot2(TAU/float(N)) * v0; 451 | } 452 | 453 | vec2 rp = rot2(float(count + 2.0) * TAU/float(N)) * p; 454 | float angle = mod(atan(rp.x, rp.y), TAU) * float(N2) / TAU; 455 | float polygon_seg = (smooth_floor(angle, 0.01) + 0.5) / float(N2); 456 | 457 | vec3 col_scheme = vec3(1); 458 | col_scheme = 0.4 + 0.6*cos(polygon_seg*TAU + vec3(1, 2, 3)); 459 | 460 | float smoothing_factor = 0.01; 461 | 462 | vec3 col = vec3(1.00, 1.00, 1.00); 463 | col = mix(col, vec3(0), 1.0 - smoothstep(0.0, smoothing_factor, shape)); 464 | col = mix(col, col_scheme, 1.0 - smoothstep(0.0, smoothing_factor, shape + 0.05)); 465 | col = pow(col, vec3(1.0/2.2)); 466 | 467 | 468 | float side_length = length(vertex_points[0] - vertex_points[1]); 469 | 470 | for (int i = 0; i < N; i++) { 471 | shuff[i*2] = i*2; 472 | shuff[i*2 + 1] = i*2 + 1; 473 | 474 | vec2 mpi = mix(vertex_points[i], vertex_points[(i + 1)%N], 0.5); 475 | vec2 tangent_i = normalize(mpi - vertex_points[i]); 476 | 477 | mp[i*2].xy = mpi - tangent_i*side_length/6.0; 478 | mp[i*2 + 1].xy = mpi + tangent_i*side_length/6.0; 479 | 480 | mp[i*2].zw = tangent_i.yx * vec2(1, -1); 481 | mp[i*2 + 1].zw = tangent_i.yx * vec2(1, -1); 482 | } 483 | 484 | for (int i = N2 - 1; i > 0; i--) { 485 | float fi = float(i); 486 | float rs = hasher(vec2(count) + domain_info.xy + domain_info.z + fi/float(N2)); 487 | int j = int(floor(rs*(fi + 0.9999))); 488 | swap(shuff[i], shuff[j]); 489 | } 490 | 491 | for (int i = 0; i < N; i++) { 492 | int j = shuff[i*2]; 493 | int jp = shuff[i*2 + 1]; 494 | 495 | float line_off = side_length*1.0; 496 | line_points[i] = do_line_segment(p, mp[j], mp[jp], line_off) - 0.03; 497 | } 498 | 499 | 500 | float ring_blend = smoothstep(0.0, 0.2, abs(length(uv) - 1.0) - 0.1); 501 | float pat = abs(fract(shape*12.0) - 0.5)*2.0 - 0.05; 502 | col = mix(col, vec3(0), ring_blend*(1.0 - smoothstep(0.0, 0.5, pat))*0.7); 503 | 504 | float lu = length(uv); 505 | 506 | for (int i = 0; i < N; i++) { 507 | pat = abs(fract(line_points[i]*12.0 + 0.5) - 0.5)*2 - 0.05; 508 | pat = mix(1.0, 0.0, ring_blend*(1.0 - smoothstep(0.0, 0.5, pat))*0.7); 509 | 510 | vec3 bg_col = col; 511 | vec3 c0 = col; 512 | c0 = mix(c0, vec3(0.0), 1.0 - smoothstep(0.0, smoothing_factor, line_points[i])); 513 | col = mix(col, c0, 1.0-step(length(uv), 1.0)); 514 | } 515 | 516 | 517 | float ring = abs(lu - 1.0) - 0.05; 518 | 519 | col = mix(col, vec3(0), 1.0 - smoothstep(0.0, smoothing_factor*0.5, ring)); 520 | 521 | col = abs(col); 522 | float coln = (col.r+col.g+col.b)/3.0; 523 | if (coln > 1) { 524 | col *= 1.0/coln; 525 | } 526 | 527 | col = pow(col, vec3(2)); 528 | 529 | return col; 530 | } 531 | 532 | void main() { 533 | vec4 colour = v_colour; 534 | vec2 uv = v_uv; 535 | 536 | colour *= texture(sampler2D(v_sampler), uv).rgba; 537 | 538 | if (v_prim_kind == Prim_Kind_Menu_Poincare) { 539 | colour.rgb *= menu_truchet(uv); 540 | } else if (v_prim_kind == Prim_Kind_Poincare) { 541 | colour.rgb *= poincare_truchet(uv); 542 | } else if (v_prim_kind == Prim_Kind_Entity) { 543 | colour = vec4(0); 544 | if (length(uv) <= ARENA_RADIUS) { 545 | render_entity(colour, uv, v_epos, v_erot, v_ekind); 546 | render_entity(colour, uv, v_epos - normalize(v_epos)*2*ARENA_RADIUS, v_erot, v_ekind); 547 | } 548 | } else if (v_texture_id == 2) { 549 | colour.rgb *= psychedelic_text(v_position_ss); 550 | } 551 | 552 | 553 | 554 | o_colour = colour; 555 | } 556 | -------------------------------------------------------------------------------- /src/odin-gl/helpers.odin: -------------------------------------------------------------------------------- 1 | package gl 2 | 3 | // Helper for loading shaders into a program 4 | 5 | import "core:os"; 6 | import "core:fmt"; 7 | 8 | Shader_Type :: enum i32 { 9 | NONE = 0x0000, 10 | FRAGMENT_SHADER = 0x8B30, 11 | VERTEX_SHADER = 0x8B31, 12 | GEOMETRY_SHADER = 0x8DD9, 13 | COMPUTE_SHADER = 0x91B9, 14 | TESS_EVALUATION_SHADER = 0x8E87, 15 | TESS_CONTROL_SHADER = 0x8E88, 16 | SHADER_LINK = -1, // @Note: Not an OpenGL constant, but used for error checking. 17 | } 18 | 19 | 20 | @private 21 | last_compile_error_message: []byte; 22 | @private 23 | last_link_error_message: []byte; 24 | 25 | @private 26 | last_compile_error_type: Shader_Type; 27 | @private 28 | last_link_error_type: Shader_Type; 29 | 30 | get_last_error_messages :: proc() -> (string, Shader_Type, string, Shader_Type) { 31 | return cast(string)last_compile_error_message[:max(0, len(last_compile_error_message)-1)], last_compile_error_type, cast(string)last_link_error_message[:max(0, len(last_link_error_message)-1)], last_link_error_type; 32 | } 33 | 34 | get_last_error_message :: proc() -> (string, Shader_Type) { 35 | return cast(string)last_compile_error_message[:max(0, len(last_compile_error_message)-1)], last_compile_error_type; 36 | } 37 | 38 | // Shader checking and linking checking are identical 39 | // except for calling differently named GL functions 40 | // it's a bit ugly looking, but meh 41 | when ODIN_DEBUG { 42 | import "core:runtime" 43 | @private 44 | check_error :: proc(id: u32, type_: Shader_Type, status: u32, 45 | iv_func: proc "c" (u32, u32, ^i32, runtime.Source_Code_Location), 46 | log_func: proc "c" (u32, i32, ^i32, ^u8, runtime.Source_Code_Location), loc := #caller_location) -> bool { 47 | result, info_log_length: i32; 48 | iv_func(id, status, &result, loc); 49 | iv_func(id, INFO_LOG_LENGTH, &info_log_length, loc); 50 | 51 | if result == 0 { 52 | if log_func == GetShaderInfoLog { 53 | delete(last_compile_error_message); 54 | last_compile_error_message = make([]byte, info_log_length); 55 | last_compile_error_type = type_; 56 | 57 | log_func(id, i32(info_log_length), nil, &last_compile_error_message[0], loc); 58 | //fmt.printf_err("Error in %v:\n%s", type_, string(last_compile_error_message[0:len(last_compile_error_message)-1])); 59 | } else { 60 | 61 | delete(last_link_error_message); 62 | last_link_error_message = make([]byte, info_log_length); 63 | last_compile_error_type = type_; 64 | 65 | log_func(id, i32(info_log_length), nil, &last_link_error_message[0], loc); 66 | //fmt.printf_err("Error in %v:\n%s", type_, string(last_link_error_message[0:len(last_link_error_message)-1])); 67 | } 68 | 69 | return true; 70 | } 71 | 72 | return false; 73 | } 74 | } else { 75 | @private 76 | check_error :: proc(id: u32, type_: Shader_Type, status: u32, 77 | iv_func: proc "c" (u32, u32, ^i32), 78 | log_func: proc "c" (u32, i32, ^i32, ^u8)) -> bool { 79 | result, info_log_length: i32; 80 | iv_func(id, status, &result); 81 | iv_func(id, INFO_LOG_LENGTH, &info_log_length); 82 | 83 | if result == 0 { 84 | if log_func == GetShaderInfoLog { 85 | delete(last_compile_error_message); 86 | last_compile_error_message = make([]u8, info_log_length); 87 | last_link_error_type = type_; 88 | 89 | log_func(id, i32(info_log_length), nil, &last_compile_error_message[0]); 90 | fmt.eprintf("Error in %v:\n%s", type_, string(last_compile_error_message[0:len(last_compile_error_message)-1])); 91 | } else { 92 | delete(last_link_error_message); 93 | last_link_error_message = make([]u8, info_log_length); 94 | last_link_error_type = type_; 95 | 96 | log_func(id, i32(info_log_length), nil, &last_link_error_message[0]); 97 | fmt.eprintf("Error in %v:\n%s", type_, string(last_link_error_message[0:len(last_link_error_message)-1])); 98 | 99 | } 100 | 101 | return true; 102 | } 103 | 104 | return false; 105 | } 106 | } 107 | 108 | // Compiling shaders are identical for any shader (vertex, geometry, fragment, tesselation, (maybe compute too)) 109 | @private 110 | compile_shader_from_source :: proc(shader_data: string, shader_type: Shader_Type) -> (u32, bool) { 111 | shader_id := CreateShader(cast(u32)shader_type); 112 | length := i32(len(shader_data)); 113 | shader_data_copy := shader_data; 114 | ShaderSource(shader_id, 1, (^^u8)(&shader_data_copy), &length); 115 | CompileShader(shader_id); 116 | 117 | if check_error(shader_id, shader_type, COMPILE_STATUS, GetShaderiv, GetShaderInfoLog) { 118 | return 0, false; 119 | } 120 | 121 | return shader_id, true; 122 | } 123 | 124 | // only used once, but I'd just make a subprocedure(?) for consistency 125 | @private 126 | create_and_link_program :: proc(shader_ids: []u32, binary_retrievable := false) -> (u32, bool) { 127 | program_id := CreateProgram(); 128 | for id in shader_ids { 129 | AttachShader(program_id, id); 130 | } 131 | if binary_retrievable { 132 | ProgramParameteri(program_id, PROGRAM_BINARY_RETRIEVABLE_HINT, TRUE); 133 | } 134 | LinkProgram(program_id); 135 | 136 | 137 | if check_error(program_id, Shader_Type.SHADER_LINK, LINK_STATUS, GetProgramiv, GetProgramInfoLog) { 138 | return 0, false; 139 | } 140 | 141 | return program_id, true; 142 | } 143 | 144 | load_compute_file :: proc(filename: string, binary_retrievable := false) -> (u32, bool) { 145 | cs_data, success_cs := os.read_entire_file(filename); 146 | if !success_cs do return 0, false; 147 | defer delete(cs_data); 148 | 149 | // Create the shaders 150 | compute_shader_id, ok1 := compile_shader_from_source(string(cs_data), Shader_Type(COMPUTE_SHADER)); 151 | 152 | if !ok1 { 153 | return 0, false; 154 | } 155 | 156 | program_id, ok2 := create_and_link_program([]u32{compute_shader_id}, binary_retrievable); 157 | if !ok2 { 158 | return 0, false; 159 | } 160 | 161 | return program_id, true; 162 | } 163 | 164 | load_compute_source :: proc(cs_data: string, binary_retrievable := false) -> (u32, bool) { 165 | // Create the shaders 166 | compute_shader_id, ok1 := compile_shader_from_source(cs_data, Shader_Type(COMPUTE_SHADER)); 167 | 168 | if !ok1 { 169 | return 0, false; 170 | } 171 | 172 | program_id, ok2 := create_and_link_program([]u32{compute_shader_id}, binary_retrievable); 173 | if !ok2 { 174 | return 0, false; 175 | } 176 | 177 | return program_id, true; 178 | } 179 | 180 | load_shaders_file :: proc(vs_filename, fs_filename: string, binary_retrievable := false) -> (u32, bool) { 181 | vs_data, success_vs := os.read_entire_file(vs_filename); 182 | if !success_vs do return 0, false; 183 | defer delete(vs_data); 184 | fs_data, success_fs := os.read_entire_file(fs_filename); 185 | if !success_fs do return 0, false; 186 | defer delete(fs_data); 187 | 188 | 189 | return load_shaders_source(string(vs_data), string(fs_data), binary_retrievable); 190 | 191 | } 192 | 193 | load_shaders_source :: proc(vs_source, fs_source: string, binary_retrievable := false) -> (u32, bool) { 194 | 195 | 196 | // actual function from here 197 | vertex_shader_id, ok1 := compile_shader_from_source(vs_source, Shader_Type.VERTEX_SHADER); 198 | defer DeleteShader(vertex_shader_id); 199 | 200 | fragment_shader_id, ok2 := compile_shader_from_source(fs_source, Shader_Type.FRAGMENT_SHADER); 201 | defer DeleteShader(fragment_shader_id); 202 | 203 | if !ok1 || !ok2 { 204 | return 0, false; 205 | } 206 | 207 | program_id, ok := create_and_link_program([]u32{vertex_shader_id, fragment_shader_id}, binary_retrievable); 208 | if !ok { 209 | return 0, false; 210 | } 211 | 212 | return program_id, true; 213 | } 214 | 215 | load_shaders :: proc{load_shaders_file}; 216 | 217 | 218 | when os.OS == "windows" { 219 | update_shader_if_changed :: proc(vertex_name, fragment_name: string, program: u32, last_vertex_time, last_fragment_time: os.File_Time) -> (u32, os.File_Time, os.File_Time, bool) { 220 | current_vertex_time, _ := os.last_write_time_by_name(vertex_name); 221 | current_fragment_time, _ := os.last_write_time_by_name(fragment_name); 222 | old_program := program; 223 | 224 | updated := false; 225 | if current_vertex_time != last_vertex_time || current_fragment_time != last_fragment_time { 226 | new_program, success := load_shaders(vertex_name, fragment_name); 227 | if success { 228 | DeleteProgram(old_program); 229 | old_program = new_program; 230 | fmt.println("Updated shaders"); 231 | updated = true; 232 | } else { 233 | fmt.println("Failed to update shaders"); 234 | } 235 | } 236 | 237 | return old_program, current_vertex_time, current_fragment_time, updated; 238 | } 239 | 240 | update_shader_if_changed_compute :: proc(compute_name: string, program: u32, last_compute_time: os.File_Time) -> (u32, os.File_Time, bool) { 241 | current_compute_time, _ := os.last_write_time_by_name(compute_name); 242 | old_program := program; 243 | 244 | updated := false; 245 | if current_compute_time != last_compute_time { 246 | new_program, success := load_compute_file(compute_name); 247 | if success { 248 | DeleteProgram(old_program); 249 | old_program = new_program; 250 | fmt.println("Updated shaders"); 251 | updated = true; 252 | } else { 253 | fmt.println("Failed to update shaders"); 254 | } 255 | } 256 | 257 | return old_program, current_compute_time, updated; 258 | } 259 | } 260 | 261 | 262 | import "core:strings" 263 | 264 | 265 | Uniform_Type :: enum i32 { 266 | FLOAT = 0x1406, 267 | FLOAT_VEC2 = 0x8B50, 268 | FLOAT_VEC3 = 0x8B51, 269 | FLOAT_VEC4 = 0x8B52, 270 | 271 | DOUBLE = 0x140A, 272 | DOUBLE_VEC2 = 0x8FFC, 273 | DOUBLE_VEC3 = 0x8FFD, 274 | DOUBLE_VEC4 = 0x8FFE, 275 | 276 | INT = 0x1404, 277 | INT_VEC2 = 0x8B53, 278 | INT_VEC3 = 0x8B54, 279 | INT_VEC4 = 0x8B55, 280 | 281 | UNSIGNED_INT = 0x1405, 282 | UNSIGNED_INT_VEC2 = 0x8DC6, 283 | UNSIGNED_INT_VEC3 = 0x8DC7, 284 | UNSIGNED_INT_VEC4 = 0x8DC8, 285 | 286 | BOOL = 0x8B56, 287 | BOOL_VEC2 = 0x8B57, 288 | BOOL_VEC3 = 0x8B58, 289 | BOOL_VEC4 = 0x8B59, 290 | 291 | FLOAT_MAT2 = 0x8B5A, 292 | FLOAT_MAT3 = 0x8B5B, 293 | FLOAT_MAT4 = 0x8B5C, 294 | FLOAT_MAT2x3 = 0x8B65, 295 | FLOAT_MAT2x4 = 0x8B66, 296 | FLOAT_MAT3x2 = 0x8B67, 297 | FLOAT_MAT3x4 = 0x8B68, 298 | FLOAT_MAT4x2 = 0x8B69, 299 | FLOAT_MAT4x3 = 0x8B6A, 300 | 301 | DOUBLE_MAT2 = 0x8F46, 302 | DOUBLE_MAT3 = 0x8F47, 303 | DOUBLE_MAT4 = 0x8F48, 304 | DOUBLE_MAT2x3 = 0x8F49, 305 | DOUBLE_MAT2x4 = 0x8F4A, 306 | DOUBLE_MAT3x2 = 0x8F4B, 307 | DOUBLE_MAT3x4 = 0x8F4C, 308 | DOUBLE_MAT4x2 = 0x8F4D, 309 | DOUBLE_MAT4x3 = 0x8F4E, 310 | 311 | SAMPLER_1D = 0x8B5D, 312 | SAMPLER_2D = 0x8B5E, 313 | SAMPLER_3D = 0x8B5F, 314 | SAMPLER_CUBE = 0x8B60, 315 | SAMPLER_1D_SHADOW = 0x8B61, 316 | SAMPLER_2D_SHADOW = 0x8B62, 317 | SAMPLER_1D_ARRAY = 0x8DC0, 318 | SAMPLER_2D_ARRAY = 0x8DC1, 319 | SAMPLER_1D_ARRAY_SHADOW = 0x8DC3, 320 | SAMPLER_2D_ARRAY_SHADOW = 0x8DC4, 321 | SAMPLER_2D_MULTISAMPLE = 0x9108, 322 | SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B, 323 | SAMPLER_CUBE_SHADOW = 0x8DC5, 324 | SAMPLER_BUFFER = 0x8DC2, 325 | SAMPLER_2D_RECT = 0x8B63, 326 | SAMPLER_2D_RECT_SHADOW = 0x8B64, 327 | 328 | INT_SAMPLER_1D = 0x8DC9, 329 | INT_SAMPLER_2D = 0x8DCA, 330 | INT_SAMPLER_3D = 0x8DCB, 331 | INT_SAMPLER_CUBE = 0x8DCC, 332 | INT_SAMPLER_1D_ARRAY = 0x8DCE, 333 | INT_SAMPLER_2D_ARRAY = 0x8DCF, 334 | INT_SAMPLER_2D_MULTISAMPLE = 0x9109, 335 | INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C, 336 | INT_SAMPLER_BUFFER = 0x8DD0, 337 | INT_SAMPLER_2D_RECT = 0x8DCD, 338 | 339 | UNSIGNED_INT_SAMPLER_1D = 0x8DD1, 340 | UNSIGNED_INT_SAMPLER_2D = 0x8DD2, 341 | UNSIGNED_INT_SAMPLER_3D = 0x8DD3, 342 | UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4, 343 | UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6, 344 | UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7, 345 | UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A, 346 | UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D, 347 | UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8, 348 | UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5, 349 | 350 | IMAGE_1D = 0x904C, 351 | IMAGE_2D = 0x904D, 352 | IMAGE_3D = 0x904E, 353 | IMAGE_2D_RECT = 0x904F, 354 | IMAGE_CUBE = 0x9050, 355 | IMAGE_BUFFER = 0x9051, 356 | IMAGE_1D_ARRAY = 0x9052, 357 | IMAGE_2D_ARRAY = 0x9053, 358 | IMAGE_CUBE_MAP_ARRAY = 0x9054, 359 | IMAGE_2D_MULTISAMPLE = 0x9055, 360 | IMAGE_2D_MULTISAMPLE_ARRAY = 0x9056, 361 | 362 | INT_IMAGE_1D = 0x9057, 363 | INT_IMAGE_2D = 0x9058, 364 | INT_IMAGE_3D = 0x9059, 365 | INT_IMAGE_2D_RECT = 0x905A, 366 | INT_IMAGE_CUBE = 0x905B, 367 | INT_IMAGE_BUFFER = 0x905C, 368 | INT_IMAGE_1D_ARRAY = 0x905D, 369 | INT_IMAGE_2D_ARRAY = 0x905E, 370 | INT_IMAGE_CUBE_MAP_ARRAY = 0x905F, 371 | INT_IMAGE_2D_MULTISAMPLE = 0x9060, 372 | INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9061, 373 | 374 | UNSIGNED_INT_IMAGE_1D = 0x9062, 375 | UNSIGNED_INT_IMAGE_2D = 0x9063, 376 | UNSIGNED_INT_IMAGE_3D = 0x9064, 377 | UNSIGNED_INT_IMAGE_2D_RECT = 0x9065, 378 | UNSIGNED_INT_IMAGE_CUBE = 0x9066, 379 | UNSIGNED_INT_IMAGE_BUFFER = 0x9067, 380 | UNSIGNED_INT_IMAGE_1D_ARRAY = 0x9068, 381 | UNSIGNED_INT_IMAGE_2D_ARRAY = 0x9069, 382 | UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY = 0x906A, 383 | UNSIGNED_INT_IMAGE_2D_MULTISAMPLE = 0x906B, 384 | UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x906C, 385 | 386 | UNSIGNED_INT_ATOMIC_COUNTER = 0x92DB, 387 | } 388 | 389 | Uniform_Info :: struct { 390 | location: i32, 391 | size: i32, 392 | kind: Uniform_Type, 393 | name: string, // NOTE: This will need to be freed 394 | } 395 | 396 | Uniforms :: map[string]Uniform_Info; 397 | 398 | destroy_uniforms :: proc(u: Uniforms) { 399 | for _, v in u { 400 | delete(v.name); 401 | } 402 | delete(u); 403 | } 404 | 405 | get_uniforms_from_program :: proc(program: u32) -> (uniforms: Uniforms) { 406 | uniform_count: i32; 407 | GetProgramiv(program, ACTIVE_UNIFORMS, &uniform_count); 408 | 409 | if uniform_count > 0 do reserve(&uniforms, int(uniform_count)); 410 | 411 | for i in 0..uniform_count-1 { 412 | using uniform_info: Uniform_Info; 413 | 414 | length: i32; 415 | cname: [256]u8; 416 | GetActiveUniform(program, u32(i), 256, &length, &size, cast(^u32)&kind, &cname[0]); 417 | 418 | location = GetUniformLocation(program, cstring(&cname[0])); 419 | name = strings.clone(string(cname[:length])); // @NOTE: These need to be freed 420 | uniforms[name] = uniform_info; 421 | } 422 | 423 | return uniforms; 424 | } 425 | 426 | get_uniform_location :: proc(program: u32, name: cstring) -> i32 { 427 | return GetUniformLocation(program, name); 428 | } 429 | 430 | get_attribute_location :: proc(program: u32, name: cstring) -> i32 { 431 | return GetAttribLocation(program, name); 432 | } 433 | -------------------------------------------------------------------------------- /src/main.odin: -------------------------------------------------------------------------------- 1 | package ld47 2 | 3 | import "core:os" 4 | import "core:fmt" 5 | import "core:mem" 6 | import "core:strings" 7 | import "core:math" 8 | import "core:runtime" 9 | import "core:math/linalg" 10 | import "core:math/rand" 11 | import glfw "shared:glfw" 12 | import gl "shared:odin-gl" 13 | 14 | cfmt :: proc(format: string, args: ..any) -> cstring { 15 | str := fmt.tprintf(format, ..args); 16 | return strings.unsafe_string_to_cstring(str); 17 | } 18 | 19 | GAME_TITLE :: "Hyperbolic Space Fighters Extreme!"; 20 | CREDITS_NAME :: "Ginger Bill"; 21 | CREDITS_COMPO :: "Ludum Dare Forty Seven"; 22 | 23 | vertex_shader := string(#load("vert.glsl")); 24 | fragment_shader := string(#load("frag.glsl")); 25 | 26 | VERTEX_BUFFER_LEN :: 1<<20; 27 | PRIMITIVE_BUFFER_SIZE_IN_BYTES :: 1<<24; 28 | 29 | vao: u32; 30 | ebo: u32; 31 | prim_ssbo: u32; 32 | texture_ubo: u32; 33 | program: u32; 34 | 35 | camera_pos: [2]f32; 36 | player_pos := [2]f32{0, 0}; 37 | player_angle := f32(math.TAU*0.125); 38 | MAX_PLAYER_HEALTH :: 100; 39 | player_health := f32(MAX_PLAYER_HEALTH); 40 | player_score: i32; 41 | 42 | PLAYER_RADIUS :: 0.05; 43 | PROJECTILE_RADIUS :: 0.02; 44 | ENEMY_BASE_RADIUS :: 0.02; 45 | PROJECTILE_LIFETIME :: 3.0; 46 | 47 | PLAYER_COLOUR :: Colour{255, 128, 0, 255}; 48 | PROJECTILE_COLOUR :: Colour{255, 0, 0, 255}; 49 | ENEMY_COLOUR :: Colour{13, 54, 240, 255}; 50 | 51 | 52 | PROJECTILE_SPAWN_RATE :: 0.2; 53 | last_projectime_time: f64 = -PROJECTILE_SPAWN_RATE; 54 | 55 | 56 | Enemy :: struct { 57 | pos: [2]f32, 58 | vel: [2]f32, 59 | rot: f32, 60 | health: i32, // vertices = health + 2 61 | marked_to_be_split: b32, 62 | } 63 | 64 | Projectile :: struct { 65 | pos: [2]f32, 66 | vel: [2]f32, 67 | rot: f32, 68 | spawn_time: f32, 69 | } 70 | 71 | 72 | Game_State :: enum { 73 | Menu_Main, 74 | Game, 75 | Paused, 76 | Death, 77 | } 78 | 79 | 80 | game_state: Game_State; 81 | 82 | enemies: [dynamic]Enemy; 83 | projectiles: [dynamic]Projectile; 84 | 85 | 86 | prev_time: f64; 87 | curr_time: f64; 88 | 89 | 90 | default_context :: proc "contextless" () -> runtime.Context { 91 | context = runtime.default_context(); 92 | context.assertion_failure_proc = assertion_failure_proc; 93 | return context; 94 | } 95 | 96 | 97 | render_draw_list :: proc(window: glfw.Window_Handle, dl: ^Draw_List, w, h: f32) { 98 | aspect_ratio := f32(max(w, 1))/f32(max(h, 1)); 99 | 100 | gl.Viewport(0, 0, i32(w), i32(h)); 101 | gl.ClearColor(1.0, 1.0, 1.0, 1.0); 102 | gl.Clear(gl.COLOR_BUFFER_BIT); 103 | 104 | gl.Enable(gl.BLEND); 105 | gl.BlendEquation(gl.FUNC_ADD); 106 | gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 107 | gl.Disable(gl.CULL_FACE); 108 | gl.Disable(gl.DEPTH_TEST); 109 | 110 | gl.BindVertexArray(vao); 111 | 112 | vertex_bufer_size_in_bytes := size_of(Vertex)*min(dl.vertex_len, len(dl.vertex_buffer)); 113 | primitive_buffer_size_in_bytes := min(dl.primitive_size, len(dl.primitive_buffer)); 114 | 115 | gl.NamedBufferSubData(ebo, 0, vertex_bufer_size_in_bytes, raw_data(dl.sorted_vertex_buffer)); 116 | gl.NamedBufferSubData(prim_ssbo, 0, primitive_buffer_size_in_bytes, raw_data(dl.primitive_buffer)); 117 | gl.NamedBufferSubData(texture_ubo, 0, size_of(g_textures), &g_textures); 118 | 119 | gl.BindBuffer(gl.ARRAY_BUFFER, 0); 120 | gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo); 121 | gl.BindBuffer(gl.SHADER_STORAGE_BUFFER, prim_ssbo); 122 | gl.BindBuffer(gl.UNIFORM_BUFFER, texture_ubo); 123 | 124 | gl.UseProgram(program); 125 | gl.Uniform4f(gl.GetUniformLocation(program, "u_screen_rect"), camera_pos.x, camera_pos.y, w, h); 126 | gl.Uniform1f(gl.GetUniformLocation(program, "u_time"), f32(glfw.GetTime())); // use the real world time for animations 127 | // gl.Uniform4f(gl.GetUniformLocation(program, "u_screen_rect"), camera_pos.x, camera_pos.y, camera_zoom*aspect_ratio, camera_zoom); 128 | 129 | gl.DrawElements(gl.TRIANGLES, i32(dl.vertex_len), gl.UNSIGNED_INT, nil); 130 | } 131 | 132 | spawn_projectile :: proc(instant: bool) { 133 | if len(projectiles) == cap(projectiles) { 134 | return; 135 | } 136 | dt := curr_time - last_projectime_time; 137 | if dt < PROJECTILE_SPAWN_RATE { 138 | return; 139 | } 140 | last_projectime_time = curr_time; 141 | 142 | fire_dir := [2]f32{math.cos(player_angle), math.sin(player_angle)}; 143 | fire_dir = linalg.normalize0(inversion(player_pos + fire_dir*PLAYER_RADIUS, player_pos)); 144 | 145 | p: Projectile; 146 | p.pos = player_pos + fire_dir*PLAYER_RADIUS; 147 | p.vel = fire_dir * 2.0; 148 | p.spawn_time = f32(curr_time); 149 | 150 | append(&projectiles, p); 151 | } 152 | 153 | rand_pos :: proc(init_pos := [2]f32{0, 0}) -> (pos: [2]f32) { 154 | r := rand.float32_range(0.3, 0.9); 155 | t := rand.float32_range(0.0, math.TAU); 156 | pos.x = r*math.cos(t); 157 | pos.y = r*math.sin(t); 158 | pos += init_pos; 159 | return bound_position(pos); 160 | } 161 | 162 | spawn_enemy :: proc(pos: [2]f32, health: Maybe(i32) = nil) { 163 | if len(enemies) >= 256 { 164 | return; 165 | } 166 | 167 | e: Enemy; 168 | e.pos = pos; 169 | e.vel.x = f32(rand.norm_float64()); 170 | e.vel.y = f32(rand.norm_float64()); 171 | e.vel = linalg.normalize0(e.vel); 172 | e.vel *= rand.float32_range(0.1, 0.4); 173 | e.rot = rand.float32_range(0, math.TAU); 174 | if health != nil { 175 | e.health = health.?; 176 | } else { 177 | e.health = 3 + rand.int31_max(5); 178 | } 179 | 180 | append(&enemies, e); 181 | } 182 | 183 | 184 | inversion :: proc(uv, p: [2]f32) -> [2]f32 { 185 | uv, p := uv, p; 186 | if linalg.length(p) < 0.05 { 187 | p += 0.05; 188 | } 189 | if abs(p.x) > 0.98*math.SQRT_TWO || abs(p.y) > 0.98*math.SQRT_TWO { 190 | p *= 0.98; 191 | } 192 | 193 | k := 1.0/linalg.dot(p, p); 194 | ip := k*p; 195 | t := (k - 1.0)/linalg.dot(uv - ip, uv - ip); 196 | uv = t*uv + (1.0 - t)*ip; 197 | uv.x = -uv.x; // preserve chirality 198 | return uv; 199 | } 200 | 201 | ARENA_RADIUS :: 0.862; 202 | 203 | bound_position :: proc(pos: [2]f32) -> [2]f32 { 204 | d := linalg.length(pos); 205 | if d > ARENA_RADIUS { 206 | return (math.mod(d, ARENA_RADIUS)-ARENA_RADIUS) * linalg.normalize0(pos); 207 | } 208 | return pos; 209 | } 210 | 211 | 212 | update_hyperbolic_position :: proc(pos, vel: [2]f32, dt: f32) -> (new_pos, new_vel: [2]f32) { 213 | p0 := pos; 214 | v0 := vel; 215 | 216 | step := v0 * dt; 217 | if linalg.length(p0) < 0.1 { 218 | new_pos = bound_position(p0 + step); 219 | new_vel = v0; 220 | return; 221 | } 222 | 223 | 224 | p1, v1 := p0, v0; 225 | vn := linalg.length(v0); 226 | 227 | r := linalg.length(p0); 228 | 229 | p1[0] += math.cosh(p0[0])*step[0] / (1 + math.sinh(r)); 230 | p1[1] += math.cosh(p0[1])*step[1] / (1 + math.sinh(r)); 231 | 232 | p1[0] += vn*math.sinh(step[0]); 233 | p1[1] += vn*math.sinh(step[1]); 234 | 235 | 236 | dp := linalg.normalize0(p1-p0); 237 | new_vel = dp*vn; 238 | new_pos = bound_position(p0 + new_vel*dt); 239 | return; 240 | } 241 | 242 | update_game :: proc(window: glfw.Window_Handle, dt: f32) { 243 | switch game_state { 244 | case .Menu_Main: 245 | if glfw.JoystickIsGamepad(0) { 246 | // NOTE(bill): assume XBox controller 247 | state: glfw.Gamepad_State; 248 | glfw.GetGamepadState(0, &state); 249 | for b in state.buttons { 250 | if b { 251 | game_state = .Game; 252 | start_new_game(); 253 | return; 254 | } 255 | } 256 | } 257 | case .Paused: 258 | return; 259 | case .Game: 260 | // okay 261 | case .Death: 262 | // NOTE(bill): assume XBox controller 263 | state: glfw.Gamepad_State; 264 | glfw.GetGamepadState(0, &state); 265 | for b in state.buttons { 266 | if b { 267 | game_state = .Game; 268 | start_new_game(); 269 | return; 270 | } 271 | } 272 | case: 273 | return; 274 | } 275 | 276 | @static random_enemy_timer: f32; 277 | random_enemy_timer += dt; 278 | 279 | if random_enemy_timer > 6.0 { 280 | if abs(f32(rand.norm_float64())) > 2.0 { 281 | spawn_enemy(rand_pos(player_pos)); 282 | random_enemy_timer = 0; 283 | } 284 | } else if len(enemies) == 0 { 285 | for i in 0..<3 { 286 | spawn_enemy(rand_pos()); 287 | } 288 | } 289 | 290 | if game_state == .Game { // player 291 | move_dir: [2]f32; 292 | if glfw.GetKey(window, glfw.KEY_W) { move_dir.y -= 1; } 293 | if glfw.GetKey(window, glfw.KEY_S) { move_dir.y += 1; } 294 | if glfw.GetKey(window, glfw.KEY_A) { move_dir.x -= 1; } 295 | if glfw.GetKey(window, glfw.KEY_D) { move_dir.x += 1; } 296 | 297 | if glfw.GetKey(window, glfw.KEY_UP) { move_dir.y -= 1; } 298 | if glfw.GetKey(window, glfw.KEY_DOWN) { move_dir.y += 1; } 299 | if glfw.GetKey(window, glfw.KEY_LEFT) { move_dir.x -= 1; } 300 | if glfw.GetKey(window, glfw.KEY_RIGHT) { move_dir.x += 1; } 301 | 302 | move_dir = linalg.normalize0(move_dir); 303 | 304 | if glfw.JoystickIsGamepad(0) { 305 | // NOTE(bill): assume XBox controller 306 | state: glfw.Gamepad_State; 307 | glfw.GetGamepadState(0, &state); 308 | dp := [2]f32{state.axes[0], state.axes[1]}; 309 | if linalg.length(dp) > 0.1 { 310 | move_dir += dp; 311 | } 312 | if state.buttons[11] { move_dir.y -= 1.0; } 313 | if state.buttons[12] { move_dir.x += 1.0; } 314 | if state.buttons[13] { move_dir.y += 1.0; } 315 | if state.buttons[14] { move_dir.x -= 1.0; } 316 | 317 | if state.buttons[0] { 318 | spawn_projectile(false); 319 | } 320 | 321 | // for b, i in state.buttons { 322 | // if b { 323 | // fmt.println("button", i); 324 | // } 325 | // } 326 | } 327 | md := linalg.length(move_dir); 328 | if md > 1.0 { 329 | move_dir *= 1.0/md; 330 | } 331 | 332 | 333 | player_pos += move_dir * dt * 2.0; 334 | player_pos = bound_position(player_pos); 335 | } 336 | 337 | for p in &projectiles { 338 | p.pos, p.vel = update_hyperbolic_position(p.pos, p.vel, dt); 339 | } 340 | 341 | for p in &enemies { 342 | p.pos, p.vel = update_hyperbolic_position(p.pos, p.vel, dt); 343 | } 344 | 345 | for p in &projectiles { 346 | if p.spawn_time < 0 { 347 | continue; 348 | } 349 | for e in &enemies { 350 | d := linalg.length(p.pos - e.pos); 351 | enemy_radius := ENEMY_BASE_RADIUS * math.pow(f32(e.health)+1, 0.5); 352 | if d < PROJECTILE_RADIUS + enemy_radius { 353 | p.spawn_time = -1e6; 354 | if !e.marked_to_be_split { 355 | player_score += e.health; 356 | fmt.println("Score:", player_score); 357 | } 358 | e.marked_to_be_split = true; 359 | break; 360 | } 361 | } 362 | } 363 | 364 | 365 | for e in &enemies { 366 | d := linalg.length(player_pos - e.pos); 367 | enemy_radius := ENEMY_BASE_RADIUS * math.pow(f32(e.health)+1, 0.5); 368 | if d < PLAYER_RADIUS + enemy_radius { 369 | player_health -= 60.0 * dt; 370 | } 371 | } 372 | 373 | 374 | for i := len(projectiles)-1; i >= 0; i -= 1 { 375 | p := &projectiles[i]; 376 | if f32(curr_time) - p.spawn_time >= PROJECTILE_LIFETIME { 377 | ordered_remove(&projectiles, i); 378 | } 379 | } 380 | 381 | en := len(enemies); 382 | for i := 0; i < en; i += 1 { 383 | e := &enemies[i]; 384 | if e.marked_to_be_split { 385 | p0 := e.pos + linalg.normalize0(e.vel)*ENEMY_BASE_RADIUS*2; 386 | p1 := e.pos - linalg.normalize0(e.vel)*ENEMY_BASE_RADIUS*2; 387 | spawn_enemy(p0, e.health-1); 388 | if e.health > 3 { 389 | spawn_enemy(p1, e.health-1); 390 | } 391 | e.health = 0; 392 | } 393 | } 394 | 395 | 396 | for i := len(enemies)-1; i >= 0; i -= 1 { 397 | e := &enemies[i]; 398 | if e.health <= 0 { 399 | ordered_remove(&enemies, i); 400 | } 401 | } 402 | 403 | if player_health <= 0 { 404 | game_state = .Death; 405 | } 406 | } 407 | 408 | start_new_game :: proc() { 409 | player_pos = {0, 0}; 410 | player_angle = f32(math.TAU*0.125); 411 | player_health = f32(MAX_PLAYER_HEALTH); 412 | player_score = 0; 413 | clear(&projectiles); 414 | clear(&enemies); 415 | for i in 0..<3 { 416 | spawn_enemy(rand_pos()); 417 | } 418 | 419 | } 420 | 421 | 422 | 423 | key_callback :: proc "c" (window: glfw.Window_Handle, key, scancode, action, mods: i32) { 424 | context = default_context(); 425 | 426 | switch game_state { 427 | case .Menu_Main: 428 | if action == glfw.PRESS { 429 | game_state = .Game; 430 | start_new_game(); 431 | } 432 | 433 | case .Game: 434 | switch key { 435 | case glfw.KEY_SPACE: 436 | switch action { 437 | case glfw.PRESS: 438 | spawn_projectile(true); 439 | case glfw.REPEAT: 440 | spawn_projectile(false); 441 | } 442 | 443 | case glfw.KEY_ESCAPE, glfw.KEY_P: 444 | if action == glfw.PRESS { 445 | game_state = .Paused; 446 | } 447 | } 448 | 449 | case .Paused: 450 | switch key { 451 | case glfw.KEY_ESCAPE, glfw.KEY_P: 452 | if action == glfw.PRESS { 453 | game_state = .Game; 454 | } 455 | } 456 | 457 | case .Death: 458 | switch key { 459 | case glfw.KEY_ESCAPE: 460 | if action == glfw.PRESS { 461 | game_state = .Menu_Main; 462 | } 463 | case: 464 | if action == glfw.PRESS { 465 | game_state = .Game; 466 | start_new_game(); 467 | } 468 | } 469 | } 470 | } 471 | 472 | 473 | framebuffer_size_callback :: proc "c" (window: glfw.Window_Handle, width, height: i32) { 474 | context = default_context(); 475 | 476 | // Freeze game logic 477 | curr_time = glfw.GetTime(); 478 | prev_time = curr_time; 479 | 480 | dl := (^Draw_List)(glfw.GetWindowUserPointer(window)); 481 | w, h := f32(width), f32(height); 482 | draw_scene(window, dl, w, h); 483 | glfw.SwapBuffers(window); 484 | } 485 | 486 | glyph_uv :: proc(c: byte) -> (uv0, uv1: [2]f32) { 487 | index := u8(0); 488 | switch c { 489 | case 'a'..'z': index = c-'a'; 490 | case 'A'..'Z': index = c-'A'; 491 | case '.': index = 24+2; 492 | case ',': index = 24+3; 493 | case '\'', '"': index = 24+4; 494 | case '!': index = 24+5; 495 | case '?': index = 24+6; 496 | case '0'..'9': index = c-'0'; // yes, it's that trippy 497 | case: 498 | return; 499 | } 500 | 501 | x := f32(index & 7); 502 | y := f32(index >> 3); 503 | uv0.x = x * 0.125; 504 | uv0.y = y * 0.250; 505 | uv1.x = uv0.x + 0.125; 506 | uv1.y = uv0.y + 0.250; 507 | return; 508 | } 509 | 510 | draw_text :: proc(dl: ^Draw_List, size: f32, pos: [2]f32, text: string) { 511 | p := pos; 512 | for t in text { 513 | if t == 'i' || t == 'I' { 514 | p.x -= size*0.15; 515 | } 516 | add_rect_textured(dl, .Font_Atlas, p + size*0.05, {size*0.5, size*1.0}, glyph_uv(byte(t)), {18, 18, 18, 255}); 517 | add_rect_textured(dl, .Font_Atlas, p, {size*0.5, size}, glyph_uv(byte(t)), Colour_White); 518 | 519 | 520 | if t == 'i' || t == 'I' { 521 | p.x -= size*0.1; 522 | } 523 | p.x += size * 0.55; 524 | } 525 | } 526 | 527 | text_dim :: proc(size: f32, text: string) -> (dim: [2]f32) { 528 | dim.y = size; 529 | for t in text { 530 | if t == 'i' || t == 'I' { 531 | dim.x -= size*0.25; 532 | } 533 | dim.x += size*0.55; 534 | } 535 | return; 536 | } 537 | 538 | centre_text :: proc(rect: Rect, size: f32, text: string) -> (pos: [2]f32) { 539 | dim := text_dim(size, text); 540 | pos = rect.pos + rect.size*0.5 - dim*0.5; 541 | return; 542 | } 543 | 544 | do_button :: proc(dl: ^Draw_List, text: string) -> bool { 545 | return false; 546 | } 547 | 548 | draw_scene :: proc(window: glfw.Window_Handle, dl: ^Draw_List, w, h: f32) { 549 | begin_draw_list(dl); 550 | rr := rand.create(1337); 551 | fb_size := [2]f32{w, h}; 552 | ar := fb_size.x/fb_size.y; 553 | vpr := Rect{{0, 0}, fb_size}; 554 | 555 | 556 | TITLE_SIZE := math.round(min(fb_size.x, fb_size.y) * 0.125); 557 | FONT_SIZE := math.round(min(fb_size.x, fb_size.y) * 0.25); 558 | SCORE_SIZE := math.round(min(fb_size.x, fb_size.y) * 0.08); 559 | 560 | switch game_state { 561 | case .Menu_Main: 562 | add_menu_poincare(dl, vpr); 563 | 564 | dim := centre_text(vpr, FONT_SIZE * 0.35, GAME_TITLE); 565 | dim.y = 0.35*fb_size.y; 566 | draw_text(dl, FONT_SIZE * 0.35, dim, GAME_TITLE); 567 | 568 | dim = centre_text(vpr, FONT_SIZE * 0.2, CREDITS_NAME); 569 | dim.y = 0.5*fb_size.y; 570 | draw_text(dl, FONT_SIZE * 0.2, dim, CREDITS_NAME); 571 | 572 | dim = centre_text(vpr, FONT_SIZE * 0.2, CREDITS_COMPO); 573 | dim.y = 0.6*fb_size.y; 574 | draw_text(dl, FONT_SIZE * 0.2, dim, CREDITS_COMPO); 575 | 576 | CONTINUE :: "Press Any Key!"; 577 | dim = centre_text(vpr, FONT_SIZE * 0.2, CONTINUE); 578 | dim.y = 0.7*fb_size.y; 579 | draw_text(dl, FONT_SIZE * 0.2, dim, CONTINUE); 580 | 581 | case .Game, .Paused, .Death: 582 | 583 | add_poincare(dl, vpr); 584 | 585 | { 586 | p := clamp(f32(curr_time - last_projectime_time)/PROJECTILE_SPAWN_RATE, 0, 1); 587 | pos := [2]f32{0.01, 0.01}; 588 | size := [2]f32{0.2, 0.1}; 589 | border := [2]f32{0.01 / ar, 0.01}; 590 | 591 | add_rect(dl, pos * fb_size, size * fb_size, {20, 30, 40, 255}); 592 | pos += border; 593 | size -= border*2; 594 | add_rect(dl, pos * fb_size, size * fb_size, {255, 255, 255, 255}); 595 | add_rect(dl, pos * fb_size, {size.x * p, size.y} * fb_size, {32, 255, 64, 255}); 596 | } 597 | 598 | { 599 | p := clamp(f32(player_health)/MAX_PLAYER_HEALTH, 0, 1); 600 | pos := [2]f32{0.01, 0.12}; 601 | size := [2]f32{0.2, 0.1}; 602 | border := [2]f32{0.01 / ar, 0.01}; 603 | 604 | add_rect(dl, pos * fb_size, size * fb_size, {20, 30, 40, 255}); 605 | pos += border; 606 | size -= border*2; 607 | add_rect(dl, pos * fb_size, size * fb_size, {255, 255, 255, 255}); 608 | add_rect(dl, pos * fb_size, {size.x * p, size.y} * fb_size, {255, 64, 32, 255}); 609 | } 610 | 611 | 612 | for p in projectiles { 613 | col := PROJECTILE_COLOUR; 614 | lt := PROJECTILE_LIFETIME - (f32(curr_time) - p.spawn_time); 615 | FADE_TIME :: 0.3; 616 | if lt < FADE_TIME { 617 | a := f32(col.a)/255.0; 618 | a = math.lerp(f32(0), a, lt/FADE_TIME); 619 | col.a = u8(255.0*clamp(a, 0, 1)); 620 | } 621 | add_entity(dl, vpr, .Projectile, p.pos, p.rot, col, 6); 622 | } 623 | 624 | if player_health > 0 { 625 | add_entity(dl, vpr, .Player, player_pos, player_angle, PLAYER_COLOUR, 3); 626 | } 627 | 628 | 629 | for e in enemies { 630 | add_entity(dl, vpr, .Enemy, e.pos, e.rot, ENEMY_COLOUR, u16(max(e.health, 0)+2)); 631 | } 632 | 633 | if game_state == .Paused { 634 | add_rect(dl, {0, 0}, fb_size, {2, 2, 4, 160}); 635 | title_dim := centre_text(vpr, FONT_SIZE * 0.35, GAME_TITLE); 636 | title_dim.y = 0.1*fb_size.y; 637 | draw_text(dl, FONT_SIZE * 0.35, title_dim, GAME_TITLE); 638 | draw_text(dl, FONT_SIZE, centre_text(vpr, FONT_SIZE, "PAUSED"), "PAUSED"); 639 | } else if game_state == .Death { 640 | add_rect(dl, {0, 0}, fb_size, {2, 2, 4, 160}); 641 | YOU_DIED :: "YOU_DIED!"; 642 | ANY_KEY :: "Any Key to Continue"; 643 | draw_text(dl, FONT_SIZE, centre_text(vpr, FONT_SIZE, YOU_DIED), YOU_DIED); 644 | dim := centre_text(vpr, SCORE_SIZE, ANY_KEY); 645 | dim.y = 0.7*fb_size.y; 646 | draw_text(dl, SCORE_SIZE, dim, ANY_KEY); 647 | 648 | } 649 | 650 | 651 | score := fmt.tprintf("Score '%d'", player_score); 652 | score_dim := text_dim(SCORE_SIZE, score); 653 | draw_text(dl, SCORE_SIZE, fb_size*0.95 - score_dim, score); 654 | 655 | } 656 | 657 | end_draw_list(dl); 658 | 659 | render_draw_list(window, dl, w, h); 660 | } 661 | 662 | foreign import user32 "system:User32.lib" 663 | @(default_calling_convention="std") 664 | foreign user32 { 665 | MessageBoxA :: proc(hWnd: rawptr, text: cstring, caption: cstring, utype: u32) -> i32 --- 666 | } 667 | 668 | assertion_failure_proc :: proc(prefix, message: string, loc := #caller_location) { 669 | 670 | 671 | runtime.print_caller_location(loc); 672 | runtime.print_string(" "); 673 | runtime.print_string(prefix); 674 | if len(message) > 0 { 675 | runtime.print_string(": "); 676 | runtime.print_string(message); 677 | } 678 | runtime.print_byte('\n'); 679 | 680 | MessageBoxA(nil, 681 | "An internal error occured. You may need to update your graphics drivers.\nThis game requires OpenGL 4.5", 682 | "Hyperbolic Assertion Error", 683 | 0x41010); 684 | os.exit(1); 685 | } 686 | 687 | 688 | 689 | 690 | main :: proc() { 691 | context = default_context(); 692 | 693 | glfw.Init(); 694 | defer glfw.Terminate(); 695 | 696 | glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 4); 697 | glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 5); 698 | glfw.WindowHint(glfw.OPENGL_CORE_PROFILE, 1); 699 | window := glfw.CreateWindow(854, 480, GAME_TITLE + "", nil, nil); 700 | assert(window != nil); 701 | defer glfw.DestroyWindow(window); 702 | 703 | glfw.MakeContextCurrent(window); 704 | 705 | glfw.SwapInterval(0); 706 | 707 | glfw.SetKeyCallback(window, key_callback); 708 | glfw.SetFramebufferSizeCallback(window, framebuffer_size_callback); 709 | 710 | gl.load_up_to(4, 5, proc(p: rawptr, name: cstring) { 711 | (^rawptr)(p)^ = glfw.GetProcAddress(name); 712 | }); 713 | 714 | gl_GetTextureHandle = auto_cast glfw.GetProcAddress("glGetTextureHandleARB"); 715 | if gl_GetTextureHandle == nil { 716 | gl_GetTextureHandle = auto_cast glfw.GetProcAddress("glGetTextureHandleNV"); 717 | } 718 | gl_MakeTextureHandleResident = auto_cast glfw.GetProcAddress("glMakeTextureHandleResidentARB"); 719 | if gl_MakeTextureHandleResident == nil { 720 | gl_MakeTextureHandleResident = auto_cast glfw.GetProcAddress("glMakeTextureHandleResidentNV"); 721 | } 722 | 723 | if gl_GetTextureHandle == nil || gl_MakeTextureHandleResident == nil { 724 | fmt.eprintln("Required OpenGL extensions:"); 725 | fmt.eprintln("\tglGetTextureHandleARB"); 726 | fmt.eprintln("\tglMakeTextureHandleResidentARB"); 727 | os.exit(1); 728 | } 729 | 730 | gl.GenVertexArrays(1, &vao); 731 | gl.BindVertexArray(vao); 732 | 733 | gl.CreateBuffers(1, &ebo); 734 | gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo); 735 | 736 | gl.CreateBuffers(1, &prim_ssbo); 737 | gl.BindBuffer(gl.SHADER_STORAGE_BUFFER, prim_ssbo); 738 | gl.BindBufferBase(gl.SHADER_STORAGE_BUFFER, 0, prim_ssbo); 739 | 740 | gl.NamedBufferData(ebo, VERTEX_BUFFER_LEN*size_of(Vertex), nil, gl.STREAM_DRAW); 741 | gl.NamedBufferData(prim_ssbo, PRIMITIVE_BUFFER_SIZE_IN_BYTES, nil, gl.STREAM_DRAW); 742 | 743 | gl.GenBuffers(1, &texture_ubo); 744 | gl.BindBufferBase(gl.UNIFORM_BUFFER, 0, texture_ubo); 745 | gl.NamedBufferData(texture_ubo, size_of(g_textures), nil, gl.STATIC_DRAW); 746 | gl.BindBufferRange(gl.UNIFORM_BUFFER, 0, texture_ubo, 0, size_of(g_textures)); 747 | 748 | init_textures(); 749 | 750 | program_ok: bool; 751 | program, program_ok = gl.load_shaders_source(vertex_shader, fragment_shader); 752 | if !program_ok { 753 | panic("failed to load and compiler shaders"); 754 | } 755 | 756 | dl := create_draw_list(VERTEX_BUFFER_LEN, PRIMITIVE_BUFFER_SIZE_IN_BYTES); 757 | defer destroy_draw_list(dl); 758 | 759 | glfw.SetWindowUserPointer(window, dl); 760 | 761 | 762 | enemies = make([dynamic]Enemy, 0, 512); 763 | projectiles = make([dynamic]Projectile, 0, 1024); 764 | 765 | start_new_game(); 766 | 767 | TIME_STEP :: 1.0/360.0; 768 | 769 | window_title_accum := f32(0); 770 | time_accum := f32(0); 771 | time_count := f64(0); 772 | prev_time = glfw.GetTime(); 773 | 774 | for !glfw.WindowShouldClose(window) { 775 | glfw.PollEvents(); 776 | 777 | curr_time = glfw.GetTime(); 778 | dt := f32(curr_time-prev_time); 779 | prev_time = curr_time; 780 | 781 | window_title_accum += dt; 782 | time_accum += dt; 783 | for window_title_accum >= 0.5 { 784 | glfw.SetWindowTitle(window, cfmt(GAME_TITLE + " - Ginger Bill - Ludum Dare 47 - %.3f ms/f, %.3f fps", 1000*dt, 1.0/dt)); 785 | window_title_accum -= 0.5; 786 | } 787 | 788 | for time_accum >= TIME_STEP { 789 | time_accum -= TIME_STEP; 790 | update_game(window, TIME_STEP); 791 | } 792 | 793 | 794 | iw, ih: i32; 795 | glfw.GetFramebufferSize(window, &iw, &ih); 796 | draw_scene(window, dl, f32(iw), f32(ih)); 797 | 798 | glfw.SwapBuffers(window); 799 | } 800 | 801 | fmt.println("Thank you playing my game!"); 802 | fmt.println("Author: Ginger Bill (2020)"); 803 | fmt.println("Ludum Dare 47"); 804 | } 805 | -------------------------------------------------------------------------------- /src/odin-gl/constants.odin: -------------------------------------------------------------------------------- 1 | package gl 2 | 3 | FALSE :: 0; 4 | TRUE :: 1; 5 | 6 | DEPTH_BUFFER_BIT :: 0x00000100; 7 | STENCIL_BUFFER_BIT :: 0x00000400; 8 | COLOR_BUFFER_BIT :: 0x00004000; 9 | POINTS :: 0x0000; 10 | LINES :: 0x0001; 11 | LINE_LOOP :: 0x0002; 12 | LINE_STRIP :: 0x0003; 13 | TRIANGLES :: 0x0004; 14 | TRIANGLE_STRIP :: 0x0005; 15 | TRIANGLE_FAN :: 0x0006; 16 | QUADS :: 0x0007; 17 | NEVER :: 0x0200; 18 | LESS :: 0x0201; 19 | EQUAL :: 0x0202; 20 | LEQUAL :: 0x0203; 21 | GREATER :: 0x0204; 22 | NOTEQUAL :: 0x0205; 23 | GEQUAL :: 0x0206; 24 | ALWAYS :: 0x0207; 25 | ZERO :: 0; 26 | ONE :: 1; 27 | SRC_COLOR :: 0x0300; 28 | ONE_MINUS_SRC_COLOR :: 0x0301; 29 | SRC_ALPHA :: 0x0302; 30 | ONE_MINUS_SRC_ALPHA :: 0x0303; 31 | DST_ALPHA :: 0x0304; 32 | ONE_MINUS_DST_ALPHA :: 0x0305; 33 | DST_COLOR :: 0x0306; 34 | ONE_MINUS_DST_COLOR :: 0x0307; 35 | SRC_ALPHA_SATURATE :: 0x0308; 36 | NONE :: 0; 37 | FRONT_LEFT :: 0x0400; 38 | FRONT_RIGHT :: 0x0401; 39 | BACK_LEFT :: 0x0402; 40 | BACK_RIGHT :: 0x0403; 41 | FRONT :: 0x0404; 42 | BACK :: 0x0405; 43 | LEFT :: 0x0406; 44 | RIGHT :: 0x0407; 45 | FRONT_AND_BACK :: 0x0408; 46 | NO_ERROR :: 0; 47 | INVALID_ENUM :: 0x0500; 48 | INVALID_VALUE :: 0x0501; 49 | INVALID_OPERATION :: 0x0502; 50 | OUT_OF_MEMORY :: 0x0505; 51 | CW :: 0x0900; 52 | CCW :: 0x0901; 53 | POINT_SIZE :: 0x0B11; 54 | POINT_SIZE_RANGE :: 0x0B12; 55 | POINT_SIZE_GRANULARITY :: 0x0B13; 56 | LINE_SMOOTH :: 0x0B20; 57 | LINE_WIDTH :: 0x0B21; 58 | LINE_WIDTH_RANGE :: 0x0B22; 59 | LINE_WIDTH_GRANULARITY :: 0x0B23; 60 | POLYGON_MODE :: 0x0B40; 61 | POLYGON_SMOOTH :: 0x0B41; 62 | CULL_FACE :: 0x0B44; 63 | CULL_FACE_MODE :: 0x0B45; 64 | FRONT_FACE :: 0x0B46; 65 | DEPTH_RANGE :: 0x0B70; 66 | DEPTH_TEST :: 0x0B71; 67 | DEPTH_WRITEMASK :: 0x0B72; 68 | DEPTH_CLEAR_VALUE :: 0x0B73; 69 | DEPTH_FUNC :: 0x0B74; 70 | STENCIL_TEST :: 0x0B90; 71 | STENCIL_CLEAR_VALUE :: 0x0B91; 72 | STENCIL_FUNC :: 0x0B92; 73 | STENCIL_VALUE_MASK :: 0x0B93; 74 | STENCIL_FAIL :: 0x0B94; 75 | STENCIL_PASS_DEPTH_FAIL :: 0x0B95; 76 | STENCIL_PASS_DEPTH_PASS :: 0x0B96; 77 | STENCIL_REF :: 0x0B97; 78 | STENCIL_WRITEMASK :: 0x0B98; 79 | VIEWPORT :: 0x0BA2; 80 | DITHER :: 0x0BD0; 81 | BLEND_DST :: 0x0BE0; 82 | BLEND_SRC :: 0x0BE1; 83 | BLEND :: 0x0BE2; 84 | LOGIC_OP_MODE :: 0x0BF0; 85 | COLOR_LOGIC_OP :: 0x0BF2; 86 | DRAW_BUFFER :: 0x0C01; 87 | READ_BUFFER :: 0x0C02; 88 | SCISSOR_BOX :: 0x0C10; 89 | SCISSOR_TEST :: 0x0C11; 90 | COLOR_CLEAR_VALUE :: 0x0C22; 91 | COLOR_WRITEMASK :: 0x0C23; 92 | DOUBLEBUFFER :: 0x0C32; 93 | STEREO :: 0x0C33; 94 | LINE_SMOOTH_HINT :: 0x0C52; 95 | POLYGON_SMOOTH_HINT :: 0x0C53; 96 | UNPACK_SWAP_BYTES :: 0x0CF0; 97 | UNPACK_LSB_FIRST :: 0x0CF1; 98 | UNPACK_ROW_LENGTH :: 0x0CF2; 99 | UNPACK_SKIP_ROWS :: 0x0CF3; 100 | UNPACK_SKIP_PIXELS :: 0x0CF4; 101 | UNPACK_ALIGNMENT :: 0x0CF5; 102 | PACK_SWAP_BYTES :: 0x0D00; 103 | PACK_LSB_FIRST :: 0x0D01; 104 | PACK_ROW_LENGTH :: 0x0D02; 105 | PACK_SKIP_ROWS :: 0x0D03; 106 | PACK_SKIP_PIXELS :: 0x0D04; 107 | PACK_ALIGNMENT :: 0x0D05; 108 | MAX_TEXTURE_SIZE :: 0x0D33; 109 | MAX_VIEWPORT_DIMS :: 0x0D3A; 110 | SUBPIXEL_BITS :: 0x0D50; 111 | TEXTURE_1D :: 0x0DE0; 112 | TEXTURE_2D :: 0x0DE1; 113 | POLYGON_OFFSET_UNITS :: 0x2A00; 114 | POLYGON_OFFSET_POINT :: 0x2A01; 115 | POLYGON_OFFSET_LINE :: 0x2A02; 116 | POLYGON_OFFSET_FILL :: 0x8037; 117 | POLYGON_OFFSET_FACTOR :: 0x8038; 118 | TEXTURE_BINDING_1D :: 0x8068; 119 | TEXTURE_BINDING_2D :: 0x8069; 120 | TEXTURE_WIDTH :: 0x1000; 121 | TEXTURE_HEIGHT :: 0x1001; 122 | TEXTURE_INTERNAL_FORMAT :: 0x1003; 123 | TEXTURE_BORDER_COLOR :: 0x1004; 124 | TEXTURE_RED_SIZE :: 0x805C; 125 | TEXTURE_GREEN_SIZE :: 0x805D; 126 | TEXTURE_BLUE_SIZE :: 0x805E; 127 | TEXTURE_ALPHA_SIZE :: 0x805F; 128 | DONT_CARE :: 0x1100; 129 | FASTEST :: 0x1101; 130 | NICEST :: 0x1102; 131 | BYTE :: 0x1400; 132 | UNSIGNED_BYTE :: 0x1401; 133 | SHORT :: 0x1402; 134 | UNSIGNED_SHORT :: 0x1403; 135 | INT :: 0x1404; 136 | UNSIGNED_INT :: 0x1405; 137 | FLOAT :: 0x1406; 138 | DOUBLE :: 0x140A; 139 | STACK_OVERFLOW :: 0x0503; 140 | STACK_UNDERFLOW :: 0x0504; 141 | CLEAR :: 0x1500; 142 | AND :: 0x1501; 143 | AND_REVERSE :: 0x1502; 144 | COPY :: 0x1503; 145 | AND_INVERTED :: 0x1504; 146 | NOOP :: 0x1505; 147 | XOR :: 0x1506; 148 | OR :: 0x1507; 149 | NOR :: 0x1508; 150 | EQUIV :: 0x1509; 151 | INVERT :: 0x150A; 152 | OR_REVERSE :: 0x150B; 153 | COPY_INVERTED :: 0x150C; 154 | OR_INVERTED :: 0x150D; 155 | NAND :: 0x150E; 156 | SET :: 0x150F; 157 | TEXTURE :: 0x1702; 158 | COLOR :: 0x1800; 159 | DEPTH :: 0x1801; 160 | STENCIL :: 0x1802; 161 | STENCIL_INDEX :: 0x1901; 162 | DEPTH_COMPONENT :: 0x1902; 163 | RED :: 0x1903; 164 | GREEN :: 0x1904; 165 | BLUE :: 0x1905; 166 | ALPHA :: 0x1906; 167 | RGB :: 0x1907; 168 | RGBA :: 0x1908; 169 | POINT :: 0x1B00; 170 | LINE :: 0x1B01; 171 | FILL :: 0x1B02; 172 | KEEP :: 0x1E00; 173 | REPLACE :: 0x1E01; 174 | INCR :: 0x1E02; 175 | DECR :: 0x1E03; 176 | VENDOR :: 0x1F00; 177 | RENDERER :: 0x1F01; 178 | VERSION :: 0x1F02; 179 | EXTENSIONS :: 0x1F03; 180 | NEAREST :: 0x2600; 181 | LINEAR :: 0x2601; 182 | NEAREST_MIPMAP_NEAREST :: 0x2700; 183 | LINEAR_MIPMAP_NEAREST :: 0x2701; 184 | NEAREST_MIPMAP_LINEAR :: 0x2702; 185 | LINEAR_MIPMAP_LINEAR :: 0x2703; 186 | TEXTURE_MAG_FILTER :: 0x2800; 187 | TEXTURE_MIN_FILTER :: 0x2801; 188 | TEXTURE_WRAP_S :: 0x2802; 189 | TEXTURE_WRAP_T :: 0x2803; 190 | PROXY_TEXTURE_1D :: 0x8063; 191 | PROXY_TEXTURE_2D :: 0x8064; 192 | REPEAT :: 0x2901; 193 | R3_G3_B2 :: 0x2A10; 194 | RGB4 :: 0x804F; 195 | RGB5 :: 0x8050; 196 | RGB8 :: 0x8051; 197 | RGB10 :: 0x8052; 198 | RGB12 :: 0x8053; 199 | RGB16 :: 0x8054; 200 | RGBA2 :: 0x8055; 201 | RGBA4 :: 0x8056; 202 | RGB5_A1 :: 0x8057; 203 | RGBA8 :: 0x8058; 204 | RGB10_A2 :: 0x8059; 205 | RGBA12 :: 0x805A; 206 | RGBA16 :: 0x805B; 207 | VERTEX_ARRAY :: 0x8074; 208 | 209 | UNSIGNED_BYTE_3_3_2 :: 0x8032; 210 | UNSIGNED_SHORT_4_4_4_4 :: 0x8033; 211 | UNSIGNED_SHORT_5_5_5_1 :: 0x8034; 212 | UNSIGNED_INT_8_8_8_8 :: 0x8035; 213 | UNSIGNED_INT_10_10_10_2 :: 0x8036; 214 | TEXTURE_BINDING_3D :: 0x806A; 215 | PACK_SKIP_IMAGES :: 0x806B; 216 | PACK_IMAGE_HEIGHT :: 0x806C; 217 | UNPACK_SKIP_IMAGES :: 0x806D; 218 | UNPACK_IMAGE_HEIGHT :: 0x806E; 219 | TEXTURE_3D :: 0x806F; 220 | PROXY_TEXTURE_3D :: 0x8070; 221 | TEXTURE_DEPTH :: 0x8071; 222 | TEXTURE_WRAP_R :: 0x8072; 223 | MAX_3D_TEXTURE_SIZE :: 0x8073; 224 | UNSIGNED_BYTE_2_3_3_REV :: 0x8362; 225 | UNSIGNED_SHORT_5_6_5 :: 0x8363; 226 | UNSIGNED_SHORT_5_6_5_REV :: 0x8364; 227 | UNSIGNED_SHORT_4_4_4_4_REV :: 0x8365; 228 | UNSIGNED_SHORT_1_5_5_5_REV :: 0x8366; 229 | UNSIGNED_INT_8_8_8_8_REV :: 0x8367; 230 | UNSIGNED_INT_2_10_10_10_REV :: 0x8368; 231 | BGR :: 0x80E0; 232 | BGRA :: 0x80E1; 233 | MAX_ELEMENTS_VERTICES :: 0x80E8; 234 | MAX_ELEMENTS_INDICES :: 0x80E9; 235 | CLAMP_TO_EDGE :: 0x812F; 236 | TEXTURE_MIN_LOD :: 0x813A; 237 | TEXTURE_MAX_LOD :: 0x813B; 238 | TEXTURE_BASE_LEVEL :: 0x813C; 239 | TEXTURE_MAX_LEVEL :: 0x813D; 240 | SMOOTH_POINT_SIZE_RANGE :: 0x0B12; 241 | SMOOTH_POINT_SIZE_GRANULARITY :: 0x0B13; 242 | SMOOTH_LINE_WIDTH_RANGE :: 0x0B22; 243 | SMOOTH_LINE_WIDTH_GRANULARITY :: 0x0B23; 244 | ALIASED_LINE_WIDTH_RANGE :: 0x846E; 245 | 246 | TEXTURE0 :: 0x84C0; 247 | TEXTURE1 :: 0x84C1; 248 | TEXTURE2 :: 0x84C2; 249 | TEXTURE3 :: 0x84C3; 250 | TEXTURE4 :: 0x84C4; 251 | TEXTURE5 :: 0x84C5; 252 | TEXTURE6 :: 0x84C6; 253 | TEXTURE7 :: 0x84C7; 254 | TEXTURE8 :: 0x84C8; 255 | TEXTURE9 :: 0x84C9; 256 | TEXTURE10 :: 0x84CA; 257 | TEXTURE11 :: 0x84CB; 258 | TEXTURE12 :: 0x84CC; 259 | TEXTURE13 :: 0x84CD; 260 | TEXTURE14 :: 0x84CE; 261 | TEXTURE15 :: 0x84CF; 262 | TEXTURE16 :: 0x84D0; 263 | TEXTURE17 :: 0x84D1; 264 | TEXTURE18 :: 0x84D2; 265 | TEXTURE19 :: 0x84D3; 266 | TEXTURE20 :: 0x84D4; 267 | TEXTURE21 :: 0x84D5; 268 | TEXTURE22 :: 0x84D6; 269 | TEXTURE23 :: 0x84D7; 270 | TEXTURE24 :: 0x84D8; 271 | TEXTURE25 :: 0x84D9; 272 | TEXTURE26 :: 0x84DA; 273 | TEXTURE27 :: 0x84DB; 274 | TEXTURE28 :: 0x84DC; 275 | TEXTURE29 :: 0x84DD; 276 | TEXTURE30 :: 0x84DE; 277 | TEXTURE31 :: 0x84DF; 278 | ACTIVE_TEXTURE :: 0x84E0; 279 | MULTISAMPLE :: 0x809D; 280 | SAMPLE_ALPHA_TO_COVERAGE :: 0x809E; 281 | SAMPLE_ALPHA_TO_ONE :: 0x809F; 282 | SAMPLE_COVERAGE :: 0x80A0; 283 | SAMPLE_BUFFERS :: 0x80A8; 284 | SAMPLES :: 0x80A9; 285 | SAMPLE_COVERAGE_VALUE :: 0x80AA; 286 | SAMPLE_COVERAGE_INVERT :: 0x80AB; 287 | TEXTURE_CUBE_MAP :: 0x8513; 288 | TEXTURE_BINDING_CUBE_MAP :: 0x8514; 289 | TEXTURE_CUBE_MAP_POSITIVE_X :: 0x8515; 290 | TEXTURE_CUBE_MAP_NEGATIVE_X :: 0x8516; 291 | TEXTURE_CUBE_MAP_POSITIVE_Y :: 0x8517; 292 | TEXTURE_CUBE_MAP_NEGATIVE_Y :: 0x8518; 293 | TEXTURE_CUBE_MAP_POSITIVE_Z :: 0x8519; 294 | TEXTURE_CUBE_MAP_NEGATIVE_Z :: 0x851A; 295 | PROXY_TEXTURE_CUBE_MAP :: 0x851B; 296 | MAX_CUBE_MAP_TEXTURE_SIZE :: 0x851C; 297 | COMPRESSED_RGB :: 0x84ED; 298 | COMPRESSED_RGBA :: 0x84EE; 299 | TEXTURE_COMPRESSION_HINT :: 0x84EF; 300 | TEXTURE_COMPRESSED_IMAGE_SIZE :: 0x86A0; 301 | TEXTURE_COMPRESSED :: 0x86A1; 302 | NUM_COMPRESSED_TEXTURE_FORMATS :: 0x86A2; 303 | COMPRESSED_TEXTURE_FORMATS :: 0x86A3; 304 | CLAMP_TO_BORDER :: 0x812D; 305 | 306 | BLEND_DST_RGB :: 0x80C8; 307 | BLEND_SRC_RGB :: 0x80C9; 308 | BLEND_DST_ALPHA :: 0x80CA; 309 | BLEND_SRC_ALPHA :: 0x80CB; 310 | POINT_FADE_THRESHOLD_SIZE :: 0x8128; 311 | DEPTH_COMPONENT16 :: 0x81A5; 312 | DEPTH_COMPONENT24 :: 0x81A6; 313 | DEPTH_COMPONENT32 :: 0x81A7; 314 | MIRRORED_REPEAT :: 0x8370; 315 | MAX_TEXTURE_LOD_BIAS :: 0x84FD; 316 | TEXTURE_LOD_BIAS :: 0x8501; 317 | INCR_WRAP :: 0x8507; 318 | DECR_WRAP :: 0x8508; 319 | TEXTURE_DEPTH_SIZE :: 0x884A; 320 | TEXTURE_COMPARE_MODE :: 0x884C; 321 | TEXTURE_COMPARE_FUNC :: 0x884D; 322 | FUNC_ADD :: 0x8006; 323 | FUNC_SUBTRACT :: 0x800A; 324 | FUNC_REVERSE_SUBTRACT :: 0x800B; 325 | MIN :: 0x8007; 326 | MAX :: 0x8008; 327 | CONSTANT_COLOR :: 0x8001; 328 | ONE_MINUS_CONSTANT_COLOR :: 0x8002; 329 | CONSTANT_ALPHA :: 0x8003; 330 | ONE_MINUS_CONSTANT_ALPHA :: 0x8004; 331 | 332 | BUFFER_SIZE :: 0x8764; 333 | BUFFER_USAGE :: 0x8765; 334 | QUERY_COUNTER_BITS :: 0x8864; 335 | CURRENT_QUERY :: 0x8865; 336 | QUERY_RESULT :: 0x8866; 337 | QUERY_RESULT_AVAILABLE :: 0x8867; 338 | ARRAY_BUFFER :: 0x8892; 339 | ELEMENT_ARRAY_BUFFER :: 0x8893; 340 | ARRAY_BUFFER_BINDING :: 0x8894; 341 | ELEMENT_ARRAY_BUFFER_BINDING :: 0x8895; 342 | VERTEX_ATTRIB_ARRAY_BUFFER_BINDING :: 0x889F; 343 | READ_ONLY :: 0x88B8; 344 | WRITE_ONLY :: 0x88B9; 345 | READ_WRITE :: 0x88BA; 346 | BUFFER_ACCESS :: 0x88BB; 347 | BUFFER_MAPPED :: 0x88BC; 348 | BUFFER_MAP_POINTER :: 0x88BD; 349 | STREAM_DRAW :: 0x88E0; 350 | STREAM_READ :: 0x88E1; 351 | STREAM_COPY :: 0x88E2; 352 | STATIC_DRAW :: 0x88E4; 353 | STATIC_READ :: 0x88E5; 354 | STATIC_COPY :: 0x88E6; 355 | DYNAMIC_DRAW :: 0x88E8; 356 | DYNAMIC_READ :: 0x88E9; 357 | DYNAMIC_COPY :: 0x88EA; 358 | SAMPLES_PASSED :: 0x8914; 359 | SRC1_ALPHA :: 0x8589; 360 | 361 | BLEND_EQUATION_RGB :: 0x8009; 362 | VERTEX_ATTRIB_ARRAY_ENABLED :: 0x8622; 363 | VERTEX_ATTRIB_ARRAY_SIZE :: 0x8623; 364 | VERTEX_ATTRIB_ARRAY_STRIDE :: 0x8624; 365 | VERTEX_ATTRIB_ARRAY_TYPE :: 0x8625; 366 | CURRENT_VERTEX_ATTRIB :: 0x8626; 367 | VERTEX_PROGRAM_POINT_SIZE :: 0x8642; 368 | VERTEX_ATTRIB_ARRAY_POINTER :: 0x8645; 369 | STENCIL_BACK_FUNC :: 0x8800; 370 | STENCIL_BACK_FAIL :: 0x8801; 371 | STENCIL_BACK_PASS_DEPTH_FAIL :: 0x8802; 372 | STENCIL_BACK_PASS_DEPTH_PASS :: 0x8803; 373 | MAX_DRAW_BUFFERS :: 0x8824; 374 | DRAW_BUFFER0 :: 0x8825; 375 | DRAW_BUFFER1 :: 0x8826; 376 | DRAW_BUFFER2 :: 0x8827; 377 | DRAW_BUFFER3 :: 0x8828; 378 | DRAW_BUFFER4 :: 0x8829; 379 | DRAW_BUFFER5 :: 0x882A; 380 | DRAW_BUFFER6 :: 0x882B; 381 | DRAW_BUFFER7 :: 0x882C; 382 | DRAW_BUFFER8 :: 0x882D; 383 | DRAW_BUFFER9 :: 0x882E; 384 | DRAW_BUFFER10 :: 0x882F; 385 | DRAW_BUFFER11 :: 0x8830; 386 | DRAW_BUFFER12 :: 0x8831; 387 | DRAW_BUFFER13 :: 0x8832; 388 | DRAW_BUFFER14 :: 0x8833; 389 | DRAW_BUFFER15 :: 0x8834; 390 | BLEND_EQUATION_ALPHA :: 0x883D; 391 | MAX_VERTEX_ATTRIBS :: 0x8869; 392 | VERTEX_ATTRIB_ARRAY_NORMALIZED :: 0x886A; 393 | MAX_TEXTURE_IMAGE_UNITS :: 0x8872; 394 | FRAGMENT_SHADER :: 0x8B30; 395 | VERTEX_SHADER :: 0x8B31; 396 | MAX_FRAGMENT_UNIFORM_COMPONENTS :: 0x8B49; 397 | MAX_VERTEX_UNIFORM_COMPONENTS :: 0x8B4A; 398 | MAX_VARYING_FLOATS :: 0x8B4B; 399 | MAX_VERTEX_TEXTURE_IMAGE_UNITS :: 0x8B4C; 400 | MAX_COMBINED_TEXTURE_IMAGE_UNITS :: 0x8B4D; 401 | SHADER_TYPE :: 0x8B4F; 402 | FLOAT_VEC2 :: 0x8B50; 403 | FLOAT_VEC3 :: 0x8B51; 404 | FLOAT_VEC4 :: 0x8B52; 405 | INT_VEC2 :: 0x8B53; 406 | INT_VEC3 :: 0x8B54; 407 | INT_VEC4 :: 0x8B55; 408 | BOOL :: 0x8B56; 409 | BOOL_VEC2 :: 0x8B57; 410 | BOOL_VEC3 :: 0x8B58; 411 | BOOL_VEC4 :: 0x8B59; 412 | FLOAT_MAT2 :: 0x8B5A; 413 | FLOAT_MAT3 :: 0x8B5B; 414 | FLOAT_MAT4 :: 0x8B5C; 415 | SAMPLER_1D :: 0x8B5D; 416 | SAMPLER_2D :: 0x8B5E; 417 | SAMPLER_3D :: 0x8B5F; 418 | SAMPLER_CUBE :: 0x8B60; 419 | SAMPLER_1D_SHADOW :: 0x8B61; 420 | SAMPLER_2D_SHADOW :: 0x8B62; 421 | DELETE_STATUS :: 0x8B80; 422 | COMPILE_STATUS :: 0x8B81; 423 | LINK_STATUS :: 0x8B82; 424 | VALIDATE_STATUS :: 0x8B83; 425 | INFO_LOG_LENGTH :: 0x8B84; 426 | ATTACHED_SHADERS :: 0x8B85; 427 | ACTIVE_UNIFORMS :: 0x8B86; 428 | ACTIVE_UNIFORM_MAX_LENGTH :: 0x8B87; 429 | SHADER_SOURCE_LENGTH :: 0x8B88; 430 | ACTIVE_ATTRIBUTES :: 0x8B89; 431 | ACTIVE_ATTRIBUTE_MAX_LENGTH :: 0x8B8A; 432 | FRAGMENT_SHADER_DERIVATIVE_HINT :: 0x8B8B; 433 | SHADING_LANGUAGE_VERSION :: 0x8B8C; 434 | CURRENT_PROGRAM :: 0x8B8D; 435 | POINT_SPRITE_COORD_ORIGIN :: 0x8CA0; 436 | LOWER_LEFT :: 0x8CA1; 437 | UPPER_LEFT :: 0x8CA2; 438 | STENCIL_BACK_REF :: 0x8CA3; 439 | STENCIL_BACK_VALUE_MASK :: 0x8CA4; 440 | STENCIL_BACK_WRITEMASK :: 0x8CA5; 441 | 442 | PIXEL_PACK_BUFFER :: 0x88EB; 443 | PIXEL_UNPACK_BUFFER :: 0x88EC; 444 | PIXEL_PACK_BUFFER_BINDING :: 0x88ED; 445 | PIXEL_UNPACK_BUFFER_BINDING :: 0x88EF; 446 | FLOAT_MAT2x3 :: 0x8B65; 447 | FLOAT_MAT2x4 :: 0x8B66; 448 | FLOAT_MAT3x2 :: 0x8B67; 449 | FLOAT_MAT3x4 :: 0x8B68; 450 | FLOAT_MAT4x2 :: 0x8B69; 451 | FLOAT_MAT4x3 :: 0x8B6A; 452 | SRGB :: 0x8C40; 453 | SRGB8 :: 0x8C41; 454 | SRGB_ALPHA :: 0x8C42; 455 | SRGB8_ALPHA8 :: 0x8C43; 456 | COMPRESSED_SRGB :: 0x8C48; 457 | COMPRESSED_SRGB_ALPHA :: 0x8C49; 458 | 459 | COMPARE_REF_TO_TEXTURE :: 0x884E; 460 | CLIP_DISTANCE0 :: 0x3000; 461 | CLIP_DISTANCE1 :: 0x3001; 462 | CLIP_DISTANCE2 :: 0x3002; 463 | CLIP_DISTANCE3 :: 0x3003; 464 | CLIP_DISTANCE4 :: 0x3004; 465 | CLIP_DISTANCE5 :: 0x3005; 466 | CLIP_DISTANCE6 :: 0x3006; 467 | CLIP_DISTANCE7 :: 0x3007; 468 | MAX_CLIP_DISTANCES :: 0x0D32; 469 | MAJOR_VERSION :: 0x821B; 470 | MINOR_VERSION :: 0x821C; 471 | NUM_EXTENSIONS :: 0x821D; 472 | CONTEXT_FLAGS :: 0x821E; 473 | COMPRESSED_RED :: 0x8225; 474 | COMPRESSED_RG :: 0x8226; 475 | CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT :: 0x00000001; 476 | RGBA32F :: 0x8814; 477 | RGB32F :: 0x8815; 478 | RGBA16F :: 0x881A; 479 | RGB16F :: 0x881B; 480 | VERTEX_ATTRIB_ARRAY_INTEGER :: 0x88FD; 481 | MAX_ARRAY_TEXTURE_LAYERS :: 0x88FF; 482 | MIN_PROGRAM_TEXEL_OFFSET :: 0x8904; 483 | MAX_PROGRAM_TEXEL_OFFSET :: 0x8905; 484 | CLAMP_READ_COLOR :: 0x891C; 485 | FIXED_ONLY :: 0x891D; 486 | MAX_VARYING_COMPONENTS :: 0x8B4B; 487 | TEXTURE_1D_ARRAY :: 0x8C18; 488 | PROXY_TEXTURE_1D_ARRAY :: 0x8C19; 489 | TEXTURE_2D_ARRAY :: 0x8C1A; 490 | PROXY_TEXTURE_2D_ARRAY :: 0x8C1B; 491 | TEXTURE_BINDING_1D_ARRAY :: 0x8C1C; 492 | TEXTURE_BINDING_2D_ARRAY :: 0x8C1D; 493 | R11F_G11F_B10F :: 0x8C3A; 494 | UNSIGNED_INT_10F_11F_11F_REV :: 0x8C3B; 495 | RGB9_E5 :: 0x8C3D; 496 | UNSIGNED_INT_5_9_9_9_REV :: 0x8C3E; 497 | TEXTURE_SHARED_SIZE :: 0x8C3F; 498 | TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH :: 0x8C76; 499 | TRANSFORM_FEEDBACK_BUFFER_MODE :: 0x8C7F; 500 | MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS :: 0x8C80; 501 | TRANSFORM_FEEDBACK_VARYINGS :: 0x8C83; 502 | TRANSFORM_FEEDBACK_BUFFER_START :: 0x8C84; 503 | TRANSFORM_FEEDBACK_BUFFER_SIZE :: 0x8C85; 504 | PRIMITIVES_GENERATED :: 0x8C87; 505 | TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN :: 0x8C88; 506 | RASTERIZER_DISCARD :: 0x8C89; 507 | MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS :: 0x8C8A; 508 | MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS :: 0x8C8B; 509 | INTERLEAVED_ATTRIBS :: 0x8C8C; 510 | SEPARATE_ATTRIBS :: 0x8C8D; 511 | TRANSFORM_FEEDBACK_BUFFER :: 0x8C8E; 512 | TRANSFORM_FEEDBACK_BUFFER_BINDING :: 0x8C8F; 513 | RGBA32UI :: 0x8D70; 514 | RGB32UI :: 0x8D71; 515 | RGBA16UI :: 0x8D76; 516 | RGB16UI :: 0x8D77; 517 | RGBA8UI :: 0x8D7C; 518 | RGB8UI :: 0x8D7D; 519 | RGBA32I :: 0x8D82; 520 | RGB32I :: 0x8D83; 521 | RGBA16I :: 0x8D88; 522 | RGB16I :: 0x8D89; 523 | RGBA8I :: 0x8D8E; 524 | RGB8I :: 0x8D8F; 525 | RED_INTEGER :: 0x8D94; 526 | GREEN_INTEGER :: 0x8D95; 527 | BLUE_INTEGER :: 0x8D96; 528 | RGB_INTEGER :: 0x8D98; 529 | RGBA_INTEGER :: 0x8D99; 530 | BGR_INTEGER :: 0x8D9A; 531 | BGRA_INTEGER :: 0x8D9B; 532 | SAMPLER_1D_ARRAY :: 0x8DC0; 533 | SAMPLER_2D_ARRAY :: 0x8DC1; 534 | SAMPLER_1D_ARRAY_SHADOW :: 0x8DC3; 535 | SAMPLER_2D_ARRAY_SHADOW :: 0x8DC4; 536 | SAMPLER_CUBE_SHADOW :: 0x8DC5; 537 | UNSIGNED_INT_VEC2 :: 0x8DC6; 538 | UNSIGNED_INT_VEC3 :: 0x8DC7; 539 | UNSIGNED_INT_VEC4 :: 0x8DC8; 540 | INT_SAMPLER_1D :: 0x8DC9; 541 | INT_SAMPLER_2D :: 0x8DCA; 542 | INT_SAMPLER_3D :: 0x8DCB; 543 | INT_SAMPLER_CUBE :: 0x8DCC; 544 | INT_SAMPLER_1D_ARRAY :: 0x8DCE; 545 | INT_SAMPLER_2D_ARRAY :: 0x8DCF; 546 | UNSIGNED_INT_SAMPLER_1D :: 0x8DD1; 547 | UNSIGNED_INT_SAMPLER_2D :: 0x8DD2; 548 | UNSIGNED_INT_SAMPLER_3D :: 0x8DD3; 549 | UNSIGNED_INT_SAMPLER_CUBE :: 0x8DD4; 550 | UNSIGNED_INT_SAMPLER_1D_ARRAY :: 0x8DD6; 551 | UNSIGNED_INT_SAMPLER_2D_ARRAY :: 0x8DD7; 552 | QUERY_WAIT :: 0x8E13; 553 | QUERY_NO_WAIT :: 0x8E14; 554 | QUERY_BY_REGION_WAIT :: 0x8E15; 555 | QUERY_BY_REGION_NO_WAIT :: 0x8E16; 556 | BUFFER_ACCESS_FLAGS :: 0x911F; 557 | BUFFER_MAP_LENGTH :: 0x9120; 558 | BUFFER_MAP_OFFSET :: 0x9121; 559 | DEPTH_COMPONENT32F :: 0x8CAC; 560 | DEPTH32F_STENCIL8 :: 0x8CAD; 561 | FLOAT_32_UNSIGNED_INT_24_8_REV :: 0x8DAD; 562 | INVALID_FRAMEBUFFER_OPERATION :: 0x0506; 563 | FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING :: 0x8210; 564 | FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE :: 0x8211; 565 | FRAMEBUFFER_ATTACHMENT_RED_SIZE :: 0x8212; 566 | FRAMEBUFFER_ATTACHMENT_GREEN_SIZE :: 0x8213; 567 | FRAMEBUFFER_ATTACHMENT_BLUE_SIZE :: 0x8214; 568 | FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE :: 0x8215; 569 | FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE :: 0x8216; 570 | FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE :: 0x8217; 571 | FRAMEBUFFER_DEFAULT :: 0x8218; 572 | FRAMEBUFFER_UNDEFINED :: 0x8219; 573 | DEPTH_STENCIL_ATTACHMENT :: 0x821A; 574 | MAX_RENDERBUFFER_SIZE :: 0x84E8; 575 | DEPTH_STENCIL :: 0x84F9; 576 | UNSIGNED_INT_24_8 :: 0x84FA; 577 | DEPTH24_STENCIL8 :: 0x88F0; 578 | TEXTURE_STENCIL_SIZE :: 0x88F1; 579 | TEXTURE_RED_TYPE :: 0x8C10; 580 | TEXTURE_GREEN_TYPE :: 0x8C11; 581 | TEXTURE_BLUE_TYPE :: 0x8C12; 582 | TEXTURE_ALPHA_TYPE :: 0x8C13; 583 | TEXTURE_DEPTH_TYPE :: 0x8C16; 584 | UNSIGNED_NORMALIZED :: 0x8C17; 585 | FRAMEBUFFER_BINDING :: 0x8CA6; 586 | DRAW_FRAMEBUFFER_BINDING :: 0x8CA6; 587 | RENDERBUFFER_BINDING :: 0x8CA7; 588 | READ_FRAMEBUFFER :: 0x8CA8; 589 | DRAW_FRAMEBUFFER :: 0x8CA9; 590 | READ_FRAMEBUFFER_BINDING :: 0x8CAA; 591 | RENDERBUFFER_SAMPLES :: 0x8CAB; 592 | FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE :: 0x8CD0; 593 | FRAMEBUFFER_ATTACHMENT_OBJECT_NAME :: 0x8CD1; 594 | FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL :: 0x8CD2; 595 | FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE :: 0x8CD3; 596 | FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER :: 0x8CD4; 597 | FRAMEBUFFER_COMPLETE :: 0x8CD5; 598 | FRAMEBUFFER_INCOMPLETE_ATTACHMENT :: 0x8CD6; 599 | FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT :: 0x8CD7; 600 | FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER :: 0x8CDB; 601 | FRAMEBUFFER_INCOMPLETE_READ_BUFFER :: 0x8CDC; 602 | FRAMEBUFFER_UNSUPPORTED :: 0x8CDD; 603 | MAX_COLOR_ATTACHMENTS :: 0x8CDF; 604 | COLOR_ATTACHMENT0 :: 0x8CE0; 605 | COLOR_ATTACHMENT1 :: 0x8CE1; 606 | COLOR_ATTACHMENT2 :: 0x8CE2; 607 | COLOR_ATTACHMENT3 :: 0x8CE3; 608 | COLOR_ATTACHMENT4 :: 0x8CE4; 609 | COLOR_ATTACHMENT5 :: 0x8CE5; 610 | COLOR_ATTACHMENT6 :: 0x8CE6; 611 | COLOR_ATTACHMENT7 :: 0x8CE7; 612 | COLOR_ATTACHMENT8 :: 0x8CE8; 613 | COLOR_ATTACHMENT9 :: 0x8CE9; 614 | COLOR_ATTACHMENT10 :: 0x8CEA; 615 | COLOR_ATTACHMENT11 :: 0x8CEB; 616 | COLOR_ATTACHMENT12 :: 0x8CEC; 617 | COLOR_ATTACHMENT13 :: 0x8CED; 618 | COLOR_ATTACHMENT14 :: 0x8CEE; 619 | COLOR_ATTACHMENT15 :: 0x8CEF; 620 | COLOR_ATTACHMENT16 :: 0x8CF0; 621 | COLOR_ATTACHMENT17 :: 0x8CF1; 622 | COLOR_ATTACHMENT18 :: 0x8CF2; 623 | COLOR_ATTACHMENT19 :: 0x8CF3; 624 | COLOR_ATTACHMENT20 :: 0x8CF4; 625 | COLOR_ATTACHMENT21 :: 0x8CF5; 626 | COLOR_ATTACHMENT22 :: 0x8CF6; 627 | COLOR_ATTACHMENT23 :: 0x8CF7; 628 | COLOR_ATTACHMENT24 :: 0x8CF8; 629 | COLOR_ATTACHMENT25 :: 0x8CF9; 630 | COLOR_ATTACHMENT26 :: 0x8CFA; 631 | COLOR_ATTACHMENT27 :: 0x8CFB; 632 | COLOR_ATTACHMENT28 :: 0x8CFC; 633 | COLOR_ATTACHMENT29 :: 0x8CFD; 634 | COLOR_ATTACHMENT30 :: 0x8CFE; 635 | COLOR_ATTACHMENT31 :: 0x8CFF; 636 | DEPTH_ATTACHMENT :: 0x8D00; 637 | STENCIL_ATTACHMENT :: 0x8D20; 638 | FRAMEBUFFER :: 0x8D40; 639 | RENDERBUFFER :: 0x8D41; 640 | RENDERBUFFER_WIDTH :: 0x8D42; 641 | RENDERBUFFER_HEIGHT :: 0x8D43; 642 | RENDERBUFFER_INTERNAL_FORMAT :: 0x8D44; 643 | STENCIL_INDEX1 :: 0x8D46; 644 | STENCIL_INDEX4 :: 0x8D47; 645 | STENCIL_INDEX8 :: 0x8D48; 646 | STENCIL_INDEX16 :: 0x8D49; 647 | RENDERBUFFER_RED_SIZE :: 0x8D50; 648 | RENDERBUFFER_GREEN_SIZE :: 0x8D51; 649 | RENDERBUFFER_BLUE_SIZE :: 0x8D52; 650 | RENDERBUFFER_ALPHA_SIZE :: 0x8D53; 651 | RENDERBUFFER_DEPTH_SIZE :: 0x8D54; 652 | RENDERBUFFER_STENCIL_SIZE :: 0x8D55; 653 | FRAMEBUFFER_INCOMPLETE_MULTISAMPLE :: 0x8D56; 654 | MAX_SAMPLES :: 0x8D57; 655 | FRAMEBUFFER_SRGB :: 0x8DB9; 656 | HALF_FLOAT :: 0x140B; 657 | MAP_READ_BIT :: 0x0001; 658 | MAP_WRITE_BIT :: 0x0002; 659 | MAP_INVALIDATE_RANGE_BIT :: 0x0004; 660 | MAP_INVALIDATE_BUFFER_BIT :: 0x0008; 661 | MAP_FLUSH_EXPLICIT_BIT :: 0x0010; 662 | MAP_UNSYNCHRONIZED_BIT :: 0x0020; 663 | COMPRESSED_RED_RGTC1 :: 0x8DBB; 664 | COMPRESSED_SIGNED_RED_RGTC1 :: 0x8DBC; 665 | COMPRESSED_RG_RGTC2 :: 0x8DBD; 666 | COMPRESSED_SIGNED_RG_RGTC2 :: 0x8DBE; 667 | RG :: 0x8227; 668 | RG_INTEGER :: 0x8228; 669 | R8 :: 0x8229; 670 | R16 :: 0x822A; 671 | RG8 :: 0x822B; 672 | RG16 :: 0x822C; 673 | R16F :: 0x822D; 674 | R32F :: 0x822E; 675 | RG16F :: 0x822F; 676 | RG32F :: 0x8230; 677 | R8I :: 0x8231; 678 | R8UI :: 0x8232; 679 | R16I :: 0x8233; 680 | R16UI :: 0x8234; 681 | R32I :: 0x8235; 682 | R32UI :: 0x8236; 683 | RG8I :: 0x8237; 684 | RG8UI :: 0x8238; 685 | RG16I :: 0x8239; 686 | RG16UI :: 0x823A; 687 | RG32I :: 0x823B; 688 | RG32UI :: 0x823C; 689 | VERTEX_ARRAY_BINDING :: 0x85B5; 690 | 691 | SAMPLER_2D_RECT :: 0x8B63; 692 | SAMPLER_2D_RECT_SHADOW :: 0x8B64; 693 | SAMPLER_BUFFER :: 0x8DC2; 694 | INT_SAMPLER_2D_RECT :: 0x8DCD; 695 | INT_SAMPLER_BUFFER :: 0x8DD0; 696 | UNSIGNED_INT_SAMPLER_2D_RECT :: 0x8DD5; 697 | UNSIGNED_INT_SAMPLER_BUFFER :: 0x8DD8; 698 | TEXTURE_BUFFER :: 0x8C2A; 699 | MAX_TEXTURE_BUFFER_SIZE :: 0x8C2B; 700 | TEXTURE_BINDING_BUFFER :: 0x8C2C; 701 | TEXTURE_BUFFER_DATA_STORE_BINDING :: 0x8C2D; 702 | TEXTURE_RECTANGLE :: 0x84F5; 703 | TEXTURE_BINDING_RECTANGLE :: 0x84F6; 704 | PROXY_TEXTURE_RECTANGLE :: 0x84F7; 705 | MAX_RECTANGLE_TEXTURE_SIZE :: 0x84F8; 706 | R8_SNORM :: 0x8F94; 707 | RG8_SNORM :: 0x8F95; 708 | RGB8_SNORM :: 0x8F96; 709 | RGBA8_SNORM :: 0x8F97; 710 | R16_SNORM :: 0x8F98; 711 | RG16_SNORM :: 0x8F99; 712 | RGB16_SNORM :: 0x8F9A; 713 | RGBA16_SNORM :: 0x8F9B; 714 | SIGNED_NORMALIZED :: 0x8F9C; 715 | PRIMITIVE_RESTART :: 0x8F9D; 716 | PRIMITIVE_RESTART_INDEX :: 0x8F9E; 717 | COPY_READ_BUFFER :: 0x8F36; 718 | COPY_WRITE_BUFFER :: 0x8F37; 719 | UNIFORM_BUFFER :: 0x8A11; 720 | UNIFORM_BUFFER_BINDING :: 0x8A28; 721 | UNIFORM_BUFFER_START :: 0x8A29; 722 | UNIFORM_BUFFER_SIZE :: 0x8A2A; 723 | MAX_VERTEX_UNIFORM_BLOCKS :: 0x8A2B; 724 | MAX_GEOMETRY_UNIFORM_BLOCKS :: 0x8A2C; 725 | MAX_FRAGMENT_UNIFORM_BLOCKS :: 0x8A2D; 726 | MAX_COMBINED_UNIFORM_BLOCKS :: 0x8A2E; 727 | MAX_UNIFORM_BUFFER_BINDINGS :: 0x8A2F; 728 | MAX_UNIFORM_BLOCK_SIZE :: 0x8A30; 729 | MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS :: 0x8A31; 730 | MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS :: 0x8A32; 731 | MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS :: 0x8A33; 732 | UNIFORM_BUFFER_OFFSET_ALIGNMENT :: 0x8A34; 733 | ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH :: 0x8A35; 734 | ACTIVE_UNIFORM_BLOCKS :: 0x8A36; 735 | UNIFORM_TYPE :: 0x8A37; 736 | UNIFORM_SIZE :: 0x8A38; 737 | UNIFORM_NAME_LENGTH :: 0x8A39; 738 | UNIFORM_BLOCK_INDEX :: 0x8A3A; 739 | UNIFORM_OFFSET :: 0x8A3B; 740 | UNIFORM_ARRAY_STRIDE :: 0x8A3C; 741 | UNIFORM_MATRIX_STRIDE :: 0x8A3D; 742 | UNIFORM_IS_ROW_MAJOR :: 0x8A3E; 743 | UNIFORM_BLOCK_BINDING :: 0x8A3F; 744 | UNIFORM_BLOCK_DATA_SIZE :: 0x8A40; 745 | UNIFORM_BLOCK_NAME_LENGTH :: 0x8A41; 746 | UNIFORM_BLOCK_ACTIVE_UNIFORMS :: 0x8A42; 747 | UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES :: 0x8A43; 748 | UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER :: 0x8A44; 749 | UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER :: 0x8A45; 750 | UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER :: 0x8A46; 751 | INVALID_INDEX :: 0xFFFFFFFF; 752 | 753 | CONTEXT_CORE_PROFILE_BIT :: 0x00000001; 754 | CONTEXT_COMPATIBILITY_PROFILE_BIT :: 0x00000002; 755 | LINES_ADJACENCY :: 0x000A; 756 | LINE_STRIP_ADJACENCY :: 0x000B; 757 | TRIANGLES_ADJACENCY :: 0x000C; 758 | TRIANGLE_STRIP_ADJACENCY :: 0x000D; 759 | PROGRAM_POINT_SIZE :: 0x8642; 760 | MAX_GEOMETRY_TEXTURE_IMAGE_UNITS :: 0x8C29; 761 | FRAMEBUFFER_ATTACHMENT_LAYERED :: 0x8DA7; 762 | FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS :: 0x8DA8; 763 | GEOMETRY_SHADER :: 0x8DD9; 764 | GEOMETRY_VERTICES_OUT :: 0x8916; 765 | GEOMETRY_INPUT_TYPE :: 0x8917; 766 | GEOMETRY_OUTPUT_TYPE :: 0x8918; 767 | MAX_GEOMETRY_UNIFORM_COMPONENTS :: 0x8DDF; 768 | MAX_GEOMETRY_OUTPUT_VERTICES :: 0x8DE0; 769 | MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS :: 0x8DE1; 770 | MAX_VERTEX_OUTPUT_COMPONENTS :: 0x9122; 771 | MAX_GEOMETRY_INPUT_COMPONENTS :: 0x9123; 772 | MAX_GEOMETRY_OUTPUT_COMPONENTS :: 0x9124; 773 | MAX_FRAGMENT_INPUT_COMPONENTS :: 0x9125; 774 | CONTEXT_PROFILE_MASK :: 0x9126; 775 | DEPTH_CLAMP :: 0x864F; 776 | QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION :: 0x8E4C; 777 | FIRST_VERTEX_CONVENTION :: 0x8E4D; 778 | LAST_VERTEX_CONVENTION :: 0x8E4E; 779 | PROVOKING_VERTEX :: 0x8E4F; 780 | TEXTURE_CUBE_MAP_SEAMLESS :: 0x884F; 781 | MAX_SERVER_WAIT_TIMEOUT :: 0x9111; 782 | OBJECT_TYPE :: 0x9112; 783 | SYNC_CONDITION :: 0x9113; 784 | SYNC_STATUS :: 0x9114; 785 | SYNC_FLAGS :: 0x9115; 786 | SYNC_FENCE :: 0x9116; 787 | SYNC_GPU_COMMANDS_COMPLETE :: 0x9117; 788 | UNSIGNALED :: 0x9118; 789 | SIGNALED :: 0x9119; 790 | ALREADY_SIGNALED :: 0x911A; 791 | TIMEOUT_EXPIRED :: 0x911B; 792 | CONDITION_SATISFIED :: 0x911C; 793 | WAIT_FAILED :: 0x911D; 794 | TIMEOUT_IGNORED :: 0xFFFFFFFFFFFFFFFF; 795 | SYNC_FLUSH_COMMANDS_BIT :: 0x00000001; 796 | SAMPLE_POSITION :: 0x8E50; 797 | SAMPLE_MASK :: 0x8E51; 798 | SAMPLE_MASK_VALUE :: 0x8E52; 799 | MAX_SAMPLE_MASK_WORDS :: 0x8E59; 800 | TEXTURE_2D_MULTISAMPLE :: 0x9100; 801 | PROXY_TEXTURE_2D_MULTISAMPLE :: 0x9101; 802 | TEXTURE_2D_MULTISAMPLE_ARRAY :: 0x9102; 803 | PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY :: 0x9103; 804 | TEXTURE_BINDING_2D_MULTISAMPLE :: 0x9104; 805 | TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY :: 0x9105; 806 | TEXTURE_SAMPLES :: 0x9106; 807 | TEXTURE_FIXED_SAMPLE_LOCATIONS :: 0x9107; 808 | SAMPLER_2D_MULTISAMPLE :: 0x9108; 809 | INT_SAMPLER_2D_MULTISAMPLE :: 0x9109; 810 | UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE :: 0x910A; 811 | SAMPLER_2D_MULTISAMPLE_ARRAY :: 0x910B; 812 | INT_SAMPLER_2D_MULTISAMPLE_ARRAY :: 0x910C; 813 | UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY :: 0x910D; 814 | MAX_COLOR_TEXTURE_SAMPLES :: 0x910E; 815 | MAX_DEPTH_TEXTURE_SAMPLES :: 0x910F; 816 | MAX_INTEGER_SAMPLES :: 0x9110; 817 | 818 | VERTEX_ATTRIB_ARRAY_DIVISOR :: 0x88FE; 819 | SRC1_COLOR :: 0x88F9; 820 | ONE_MINUS_SRC1_COLOR :: 0x88FA; 821 | ONE_MINUS_SRC1_ALPHA :: 0x88FB; 822 | MAX_DUAL_SOURCE_DRAW_BUFFERS :: 0x88FC; 823 | ANY_SAMPLES_PASSED :: 0x8C2F; 824 | SAMPLER_BINDING :: 0x8919; 825 | RGB10_A2UI :: 0x906F; 826 | TEXTURE_SWIZZLE_R :: 0x8E42; 827 | TEXTURE_SWIZZLE_G :: 0x8E43; 828 | TEXTURE_SWIZZLE_B :: 0x8E44; 829 | TEXTURE_SWIZZLE_A :: 0x8E45; 830 | TEXTURE_SWIZZLE_RGBA :: 0x8E46; 831 | TIME_ELAPSED :: 0x88BF; 832 | TIMESTAMP :: 0x8E28; 833 | INT_2_10_10_10_REV :: 0x8D9F; 834 | 835 | SAMPLE_SHADING :: 0x8C36; 836 | MIN_SAMPLE_SHADING_VALUE :: 0x8C37; 837 | MIN_PROGRAM_TEXTURE_GATHER_OFFSET :: 0x8E5E; 838 | MAX_PROGRAM_TEXTURE_GATHER_OFFSET :: 0x8E5F; 839 | TEXTURE_CUBE_MAP_ARRAY :: 0x9009; 840 | TEXTURE_BINDING_CUBE_MAP_ARRAY :: 0x900A; 841 | PROXY_TEXTURE_CUBE_MAP_ARRAY :: 0x900B; 842 | SAMPLER_CUBE_MAP_ARRAY :: 0x900C; 843 | SAMPLER_CUBE_MAP_ARRAY_SHADOW :: 0x900D; 844 | INT_SAMPLER_CUBE_MAP_ARRAY :: 0x900E; 845 | UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY :: 0x900F; 846 | DRAW_INDIRECT_BUFFER :: 0x8F3F; 847 | DRAW_INDIRECT_BUFFER_BINDING :: 0x8F43; 848 | GEOMETRY_SHADER_INVOCATIONS :: 0x887F; 849 | MAX_GEOMETRY_SHADER_INVOCATIONS :: 0x8E5A; 850 | MIN_FRAGMENT_INTERPOLATION_OFFSET :: 0x8E5B; 851 | MAX_FRAGMENT_INTERPOLATION_OFFSET :: 0x8E5C; 852 | FRAGMENT_INTERPOLATION_OFFSET_BITS :: 0x8E5D; 853 | MAX_VERTEX_STREAMS :: 0x8E71; 854 | DOUBLE_VEC2 :: 0x8FFC; 855 | DOUBLE_VEC3 :: 0x8FFD; 856 | DOUBLE_VEC4 :: 0x8FFE; 857 | DOUBLE_MAT2 :: 0x8F46; 858 | DOUBLE_MAT3 :: 0x8F47; 859 | DOUBLE_MAT4 :: 0x8F48; 860 | DOUBLE_MAT2x3 :: 0x8F49; 861 | DOUBLE_MAT2x4 :: 0x8F4A; 862 | DOUBLE_MAT3x2 :: 0x8F4B; 863 | DOUBLE_MAT3x4 :: 0x8F4C; 864 | DOUBLE_MAT4x2 :: 0x8F4D; 865 | DOUBLE_MAT4x3 :: 0x8F4E; 866 | ACTIVE_SUBROUTINES :: 0x8DE5; 867 | ACTIVE_SUBROUTINE_UNIFORMS :: 0x8DE6; 868 | ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS :: 0x8E47; 869 | ACTIVE_SUBROUTINE_MAX_LENGTH :: 0x8E48; 870 | ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH :: 0x8E49; 871 | MAX_SUBROUTINES :: 0x8DE7; 872 | MAX_SUBROUTINE_UNIFORM_LOCATIONS :: 0x8DE8; 873 | NUM_COMPATIBLE_SUBROUTINES :: 0x8E4A; 874 | COMPATIBLE_SUBROUTINES :: 0x8E4B; 875 | PATCHES :: 0x000E; 876 | PATCH_VERTICES :: 0x8E72; 877 | PATCH_DEFAULT_INNER_LEVEL :: 0x8E73; 878 | PATCH_DEFAULT_OUTER_LEVEL :: 0x8E74; 879 | TESS_CONTROL_OUTPUT_VERTICES :: 0x8E75; 880 | TESS_GEN_MODE :: 0x8E76; 881 | TESS_GEN_SPACING :: 0x8E77; 882 | TESS_GEN_VERTEX_ORDER :: 0x8E78; 883 | TESS_GEN_POINT_MODE :: 0x8E79; 884 | ISOLINES :: 0x8E7A; 885 | FRACTIONAL_ODD :: 0x8E7B; 886 | FRACTIONAL_EVEN :: 0x8E7C; 887 | MAX_PATCH_VERTICES :: 0x8E7D; 888 | MAX_TESS_GEN_LEVEL :: 0x8E7E; 889 | MAX_TESS_CONTROL_UNIFORM_COMPONENTS :: 0x8E7F; 890 | MAX_TESS_EVALUATION_UNIFORM_COMPONENTS :: 0x8E80; 891 | MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS :: 0x8E81; 892 | MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS :: 0x8E82; 893 | MAX_TESS_CONTROL_OUTPUT_COMPONENTS :: 0x8E83; 894 | MAX_TESS_PATCH_COMPONENTS :: 0x8E84; 895 | MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS :: 0x8E85; 896 | MAX_TESS_EVALUATION_OUTPUT_COMPONENTS :: 0x8E86; 897 | MAX_TESS_CONTROL_UNIFORM_BLOCKS :: 0x8E89; 898 | MAX_TESS_EVALUATION_UNIFORM_BLOCKS :: 0x8E8A; 899 | MAX_TESS_CONTROL_INPUT_COMPONENTS :: 0x886C; 900 | MAX_TESS_EVALUATION_INPUT_COMPONENTS :: 0x886D; 901 | MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS :: 0x8E1E; 902 | MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS :: 0x8E1F; 903 | UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER :: 0x84F0; 904 | UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER :: 0x84F1; 905 | TESS_EVALUATION_SHADER :: 0x8E87; 906 | TESS_CONTROL_SHADER :: 0x8E88; 907 | TRANSFORM_FEEDBACK :: 0x8E22; 908 | TRANSFORM_FEEDBACK_BUFFER_PAUSED :: 0x8E23; 909 | TRANSFORM_FEEDBACK_BUFFER_ACTIVE :: 0x8E24; 910 | TRANSFORM_FEEDBACK_BINDING :: 0x8E25; 911 | MAX_TRANSFORM_FEEDBACK_BUFFERS :: 0x8E70; 912 | 913 | FIXED :: 0x140C; 914 | IMPLEMENTATION_COLOR_READ_TYPE :: 0x8B9A; 915 | IMPLEMENTATION_COLOR_READ_FORMAT :: 0x8B9B; 916 | LOW_FLOAT :: 0x8DF0; 917 | MEDIUM_FLOAT :: 0x8DF1; 918 | HIGH_FLOAT :: 0x8DF2; 919 | LOW_INT :: 0x8DF3; 920 | MEDIUM_INT :: 0x8DF4; 921 | HIGH_INT :: 0x8DF5; 922 | SHADER_COMPILER :: 0x8DFA; 923 | SHADER_BINARY_FORMATS :: 0x8DF8; 924 | NUM_SHADER_BINARY_FORMATS :: 0x8DF9; 925 | MAX_VERTEX_UNIFORM_VECTORS :: 0x8DFB; 926 | MAX_VARYING_VECTORS :: 0x8DFC; 927 | MAX_FRAGMENT_UNIFORM_VECTORS :: 0x8DFD; 928 | RGB565 :: 0x8D62; 929 | PROGRAM_BINARY_RETRIEVABLE_HINT :: 0x8257; 930 | PROGRAM_BINARY_LENGTH :: 0x8741; 931 | NUM_PROGRAM_BINARY_FORMATS :: 0x87FE; 932 | PROGRAM_BINARY_FORMATS :: 0x87FF; 933 | VERTEX_SHADER_BIT :: 0x00000001; 934 | FRAGMENT_SHADER_BIT :: 0x00000002; 935 | GEOMETRY_SHADER_BIT :: 0x00000004; 936 | TESS_CONTROL_SHADER_BIT :: 0x00000008; 937 | TESS_EVALUATION_SHADER_BIT :: 0x00000010; 938 | ALL_SHADER_BITS :: 0xFFFFFFFF; 939 | PROGRAM_SEPARABLE :: 0x8258; 940 | ACTIVE_PROGRAM :: 0x8259; 941 | PROGRAM_PIPELINE_BINDING :: 0x825A; 942 | MAX_VIEWPORTS :: 0x825B; 943 | VIEWPORT_SUBPIXEL_BITS :: 0x825C; 944 | VIEWPORT_BOUNDS_RANGE :: 0x825D; 945 | LAYER_PROVOKING_VERTEX :: 0x825E; 946 | VIEWPORT_INDEX_PROVOKING_VERTEX :: 0x825F; 947 | UNDEFINED_VERTEX :: 0x8260; 948 | 949 | COPY_READ_BUFFER_BINDING :: 0x8F36; 950 | COPY_WRITE_BUFFER_BINDING :: 0x8F37; 951 | TRANSFORM_FEEDBACK_ACTIVE :: 0x8E24; 952 | TRANSFORM_FEEDBACK_PAUSED :: 0x8E23; 953 | UNPACK_COMPRESSED_BLOCK_WIDTH :: 0x9127; 954 | UNPACK_COMPRESSED_BLOCK_HEIGHT :: 0x9128; 955 | UNPACK_COMPRESSED_BLOCK_DEPTH :: 0x9129; 956 | UNPACK_COMPRESSED_BLOCK_SIZE :: 0x912A; 957 | PACK_COMPRESSED_BLOCK_WIDTH :: 0x912B; 958 | PACK_COMPRESSED_BLOCK_HEIGHT :: 0x912C; 959 | PACK_COMPRESSED_BLOCK_DEPTH :: 0x912D; 960 | PACK_COMPRESSED_BLOCK_SIZE :: 0x912E; 961 | NUM_SAMPLE_COUNTS :: 0x9380; 962 | MIN_MAP_BUFFER_ALIGNMENT :: 0x90BC; 963 | ATOMIC_COUNTER_BUFFER :: 0x92C0; 964 | ATOMIC_COUNTER_BUFFER_BINDING :: 0x92C1; 965 | ATOMIC_COUNTER_BUFFER_START :: 0x92C2; 966 | ATOMIC_COUNTER_BUFFER_SIZE :: 0x92C3; 967 | ATOMIC_COUNTER_BUFFER_DATA_SIZE :: 0x92C4; 968 | ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS :: 0x92C5; 969 | ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES :: 0x92C6; 970 | ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER :: 0x92C7; 971 | ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER :: 0x92C8; 972 | ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER :: 0x92C9; 973 | ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER :: 0x92CA; 974 | ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER :: 0x92CB; 975 | MAX_VERTEX_ATOMIC_COUNTER_BUFFERS :: 0x92CC; 976 | MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS :: 0x92CD; 977 | MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS :: 0x92CE; 978 | MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS :: 0x92CF; 979 | MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS :: 0x92D0; 980 | MAX_COMBINED_ATOMIC_COUNTER_BUFFERS :: 0x92D1; 981 | MAX_VERTEX_ATOMIC_COUNTERS :: 0x92D2; 982 | MAX_TESS_CONTROL_ATOMIC_COUNTERS :: 0x92D3; 983 | MAX_TESS_EVALUATION_ATOMIC_COUNTERS :: 0x92D4; 984 | MAX_GEOMETRY_ATOMIC_COUNTERS :: 0x92D5; 985 | MAX_FRAGMENT_ATOMIC_COUNTERS :: 0x92D6; 986 | MAX_COMBINED_ATOMIC_COUNTERS :: 0x92D7; 987 | MAX_ATOMIC_COUNTER_BUFFER_SIZE :: 0x92D8; 988 | MAX_ATOMIC_COUNTER_BUFFER_BINDINGS :: 0x92DC; 989 | ACTIVE_ATOMIC_COUNTER_BUFFERS :: 0x92D9; 990 | UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX :: 0x92DA; 991 | UNSIGNED_INT_ATOMIC_COUNTER :: 0x92DB; 992 | VERTEX_ATTRIB_ARRAY_BARRIER_BIT :: 0x00000001; 993 | ELEMENT_ARRAY_BARRIER_BIT :: 0x00000002; 994 | UNIFORM_BARRIER_BIT :: 0x00000004; 995 | TEXTURE_FETCH_BARRIER_BIT :: 0x00000008; 996 | SHADER_IMAGE_ACCESS_BARRIER_BIT :: 0x00000020; 997 | COMMAND_BARRIER_BIT :: 0x00000040; 998 | PIXEL_BUFFER_BARRIER_BIT :: 0x00000080; 999 | TEXTURE_UPDATE_BARRIER_BIT :: 0x00000100; 1000 | BUFFER_UPDATE_BARRIER_BIT :: 0x00000200; 1001 | FRAMEBUFFER_BARRIER_BIT :: 0x00000400; 1002 | TRANSFORM_FEEDBACK_BARRIER_BIT :: 0x00000800; 1003 | ATOMIC_COUNTER_BARRIER_BIT :: 0x00001000; 1004 | ALL_BARRIER_BITS :: 0xFFFFFFFF; 1005 | MAX_IMAGE_UNITS :: 0x8F38; 1006 | MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS :: 0x8F39; 1007 | IMAGE_BINDING_NAME :: 0x8F3A; 1008 | IMAGE_BINDING_LEVEL :: 0x8F3B; 1009 | IMAGE_BINDING_LAYERED :: 0x8F3C; 1010 | IMAGE_BINDING_LAYER :: 0x8F3D; 1011 | IMAGE_BINDING_ACCESS :: 0x8F3E; 1012 | IMAGE_1D :: 0x904C; 1013 | IMAGE_2D :: 0x904D; 1014 | IMAGE_3D :: 0x904E; 1015 | IMAGE_2D_RECT :: 0x904F; 1016 | IMAGE_CUBE :: 0x9050; 1017 | IMAGE_BUFFER :: 0x9051; 1018 | IMAGE_1D_ARRAY :: 0x9052; 1019 | IMAGE_2D_ARRAY :: 0x9053; 1020 | IMAGE_CUBE_MAP_ARRAY :: 0x9054; 1021 | IMAGE_2D_MULTISAMPLE :: 0x9055; 1022 | IMAGE_2D_MULTISAMPLE_ARRAY :: 0x9056; 1023 | INT_IMAGE_1D :: 0x9057; 1024 | INT_IMAGE_2D :: 0x9058; 1025 | INT_IMAGE_3D :: 0x9059; 1026 | INT_IMAGE_2D_RECT :: 0x905A; 1027 | INT_IMAGE_CUBE :: 0x905B; 1028 | INT_IMAGE_BUFFER :: 0x905C; 1029 | INT_IMAGE_1D_ARRAY :: 0x905D; 1030 | INT_IMAGE_2D_ARRAY :: 0x905E; 1031 | INT_IMAGE_CUBE_MAP_ARRAY :: 0x905F; 1032 | INT_IMAGE_2D_MULTISAMPLE :: 0x9060; 1033 | INT_IMAGE_2D_MULTISAMPLE_ARRAY :: 0x9061; 1034 | UNSIGNED_INT_IMAGE_1D :: 0x9062; 1035 | UNSIGNED_INT_IMAGE_2D :: 0x9063; 1036 | UNSIGNED_INT_IMAGE_3D :: 0x9064; 1037 | UNSIGNED_INT_IMAGE_2D_RECT :: 0x9065; 1038 | UNSIGNED_INT_IMAGE_CUBE :: 0x9066; 1039 | UNSIGNED_INT_IMAGE_BUFFER :: 0x9067; 1040 | UNSIGNED_INT_IMAGE_1D_ARRAY :: 0x9068; 1041 | UNSIGNED_INT_IMAGE_2D_ARRAY :: 0x9069; 1042 | UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY :: 0x906A; 1043 | UNSIGNED_INT_IMAGE_2D_MULTISAMPLE :: 0x906B; 1044 | UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY :: 0x906C; 1045 | MAX_IMAGE_SAMPLES :: 0x906D; 1046 | IMAGE_BINDING_FORMAT :: 0x906E; 1047 | IMAGE_FORMAT_COMPATIBILITY_TYPE :: 0x90C7; 1048 | IMAGE_FORMAT_COMPATIBILITY_BY_SIZE :: 0x90C8; 1049 | IMAGE_FORMAT_COMPATIBILITY_BY_CLASS :: 0x90C9; 1050 | MAX_VERTEX_IMAGE_UNIFORMS :: 0x90CA; 1051 | MAX_TESS_CONTROL_IMAGE_UNIFORMS :: 0x90CB; 1052 | MAX_TESS_EVALUATION_IMAGE_UNIFORMS :: 0x90CC; 1053 | MAX_GEOMETRY_IMAGE_UNIFORMS :: 0x90CD; 1054 | MAX_FRAGMENT_IMAGE_UNIFORMS :: 0x90CE; 1055 | MAX_COMBINED_IMAGE_UNIFORMS :: 0x90CF; 1056 | COMPRESSED_RGBA_BPTC_UNORM :: 0x8E8C; 1057 | COMPRESSED_SRGB_ALPHA_BPTC_UNORM :: 0x8E8D; 1058 | COMPRESSED_RGB_BPTC_SIGNED_FLOAT :: 0x8E8E; 1059 | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT :: 0x8E8F; 1060 | TEXTURE_IMMUTABLE_FORMAT :: 0x912F; 1061 | 1062 | NUM_SHADING_LANGUAGE_VERSIONS :: 0x82E9; 1063 | VERTEX_ATTRIB_ARRAY_LONG :: 0x874E; 1064 | COMPRESSED_RGB8_ETC2 :: 0x9274; 1065 | COMPRESSED_SRGB8_ETC2 :: 0x9275; 1066 | COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 :: 0x9276; 1067 | COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 :: 0x9277; 1068 | COMPRESSED_RGBA8_ETC2_EAC :: 0x9278; 1069 | COMPRESSED_SRGB8_ALPHA8_ETC2_EAC :: 0x9279; 1070 | COMPRESSED_R11_EAC :: 0x9270; 1071 | COMPRESSED_SIGNED_R11_EAC :: 0x9271; 1072 | COMPRESSED_RG11_EAC :: 0x9272; 1073 | COMPRESSED_SIGNED_RG11_EAC :: 0x9273; 1074 | PRIMITIVE_RESTART_FIXED_INDEX :: 0x8D69; 1075 | ANY_SAMPLES_PASSED_CONSERVATIVE :: 0x8D6A; 1076 | MAX_ELEMENT_INDEX :: 0x8D6B; 1077 | COMPUTE_SHADER :: 0x91B9; 1078 | MAX_COMPUTE_UNIFORM_BLOCKS :: 0x91BB; 1079 | MAX_COMPUTE_TEXTURE_IMAGE_UNITS :: 0x91BC; 1080 | MAX_COMPUTE_IMAGE_UNIFORMS :: 0x91BD; 1081 | MAX_COMPUTE_SHARED_MEMORY_SIZE :: 0x8262; 1082 | MAX_COMPUTE_UNIFORM_COMPONENTS :: 0x8263; 1083 | MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS :: 0x8264; 1084 | MAX_COMPUTE_ATOMIC_COUNTERS :: 0x8265; 1085 | MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS :: 0x8266; 1086 | MAX_COMPUTE_WORK_GROUP_INVOCATIONS :: 0x90EB; 1087 | MAX_COMPUTE_WORK_GROUP_COUNT :: 0x91BE; 1088 | MAX_COMPUTE_WORK_GROUP_SIZE :: 0x91BF; 1089 | COMPUTE_WORK_GROUP_SIZE :: 0x8267; 1090 | UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER :: 0x90EC; 1091 | ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER :: 0x90ED; 1092 | DISPATCH_INDIRECT_BUFFER :: 0x90EE; 1093 | DISPATCH_INDIRECT_BUFFER_BINDING :: 0x90EF; 1094 | COMPUTE_SHADER_BIT :: 0x00000020; 1095 | DEBUG_OUTPUT_SYNCHRONOUS :: 0x8242; 1096 | DEBUG_NEXT_LOGGED_MESSAGE_LENGTH :: 0x8243; 1097 | DEBUG_CALLBACK_FUNCTION :: 0x8244; 1098 | DEBUG_CALLBACK_USER_PARAM :: 0x8245; 1099 | DEBUG_SOURCE_API :: 0x8246; 1100 | DEBUG_SOURCE_WINDOW_SYSTEM :: 0x8247; 1101 | DEBUG_SOURCE_SHADER_COMPILER :: 0x8248; 1102 | DEBUG_SOURCE_THIRD_PARTY :: 0x8249; 1103 | DEBUG_SOURCE_APPLICATION :: 0x824A; 1104 | DEBUG_SOURCE_OTHER :: 0x824B; 1105 | DEBUG_TYPE_ERROR :: 0x824C; 1106 | DEBUG_TYPE_DEPRECATED_BEHAVIOR :: 0x824D; 1107 | DEBUG_TYPE_UNDEFINED_BEHAVIOR :: 0x824E; 1108 | DEBUG_TYPE_PORTABILITY :: 0x824F; 1109 | DEBUG_TYPE_PERFORMANCE :: 0x8250; 1110 | DEBUG_TYPE_OTHER :: 0x8251; 1111 | MAX_DEBUG_MESSAGE_LENGTH :: 0x9143; 1112 | MAX_DEBUG_LOGGED_MESSAGES :: 0x9144; 1113 | DEBUG_LOGGED_MESSAGES :: 0x9145; 1114 | DEBUG_SEVERITY_HIGH :: 0x9146; 1115 | DEBUG_SEVERITY_MEDIUM :: 0x9147; 1116 | DEBUG_SEVERITY_LOW :: 0x9148; 1117 | DEBUG_TYPE_MARKER :: 0x8268; 1118 | DEBUG_TYPE_PUSH_GROUP :: 0x8269; 1119 | DEBUG_TYPE_POP_GROUP :: 0x826A; 1120 | DEBUG_SEVERITY_NOTIFICATION :: 0x826B; 1121 | MAX_DEBUG_GROUP_STACK_DEPTH :: 0x826C; 1122 | DEBUG_GROUP_STACK_DEPTH :: 0x826D; 1123 | BUFFER :: 0x82E0; 1124 | SHADER :: 0x82E1; 1125 | PROGRAM :: 0x82E2; 1126 | QUERY :: 0x82E3; 1127 | PROGRAM_PIPELINE :: 0x82E4; 1128 | SAMPLER :: 0x82E6; 1129 | MAX_LABEL_LENGTH :: 0x82E8; 1130 | DEBUG_OUTPUT :: 0x92E0; 1131 | CONTEXT_FLAG_DEBUG_BIT :: 0x00000002; 1132 | MAX_UNIFORM_LOCATIONS :: 0x826E; 1133 | FRAMEBUFFER_DEFAULT_WIDTH :: 0x9310; 1134 | FRAMEBUFFER_DEFAULT_HEIGHT :: 0x9311; 1135 | FRAMEBUFFER_DEFAULT_LAYERS :: 0x9312; 1136 | FRAMEBUFFER_DEFAULT_SAMPLES :: 0x9313; 1137 | FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS :: 0x9314; 1138 | MAX_FRAMEBUFFER_WIDTH :: 0x9315; 1139 | MAX_FRAMEBUFFER_HEIGHT :: 0x9316; 1140 | MAX_FRAMEBUFFER_LAYERS :: 0x9317; 1141 | MAX_FRAMEBUFFER_SAMPLES :: 0x9318; 1142 | INTERNALFORMAT_SUPPORTED :: 0x826F; 1143 | INTERNALFORMAT_PREFERRED :: 0x8270; 1144 | INTERNALFORMAT_RED_SIZE :: 0x8271; 1145 | INTERNALFORMAT_GREEN_SIZE :: 0x8272; 1146 | INTERNALFORMAT_BLUE_SIZE :: 0x8273; 1147 | INTERNALFORMAT_ALPHA_SIZE :: 0x8274; 1148 | INTERNALFORMAT_DEPTH_SIZE :: 0x8275; 1149 | INTERNALFORMAT_STENCIL_SIZE :: 0x8276; 1150 | INTERNALFORMAT_SHARED_SIZE :: 0x8277; 1151 | INTERNALFORMAT_RED_TYPE :: 0x8278; 1152 | INTERNALFORMAT_GREEN_TYPE :: 0x8279; 1153 | INTERNALFORMAT_BLUE_TYPE :: 0x827A; 1154 | INTERNALFORMAT_ALPHA_TYPE :: 0x827B; 1155 | INTERNALFORMAT_DEPTH_TYPE :: 0x827C; 1156 | INTERNALFORMAT_STENCIL_TYPE :: 0x827D; 1157 | MAX_WIDTH :: 0x827E; 1158 | MAX_HEIGHT :: 0x827F; 1159 | MAX_DEPTH :: 0x8280; 1160 | MAX_LAYERS :: 0x8281; 1161 | MAX_COMBINED_DIMENSIONS :: 0x8282; 1162 | COLOR_COMPONENTS :: 0x8283; 1163 | DEPTH_COMPONENTS :: 0x8284; 1164 | STENCIL_COMPONENTS :: 0x8285; 1165 | COLOR_RENDERABLE :: 0x8286; 1166 | DEPTH_RENDERABLE :: 0x8287; 1167 | STENCIL_RENDERABLE :: 0x8288; 1168 | FRAMEBUFFER_RENDERABLE :: 0x8289; 1169 | FRAMEBUFFER_RENDERABLE_LAYERED :: 0x828A; 1170 | FRAMEBUFFER_BLEND :: 0x828B; 1171 | READ_PIXELS :: 0x828C; 1172 | READ_PIXELS_FORMAT :: 0x828D; 1173 | READ_PIXELS_TYPE :: 0x828E; 1174 | TEXTURE_IMAGE_FORMAT :: 0x828F; 1175 | TEXTURE_IMAGE_TYPE :: 0x8290; 1176 | GET_TEXTURE_IMAGE_FORMAT :: 0x8291; 1177 | GET_TEXTURE_IMAGE_TYPE :: 0x8292; 1178 | MIPMAP :: 0x8293; 1179 | MANUAL_GENERATE_MIPMAP :: 0x8294; 1180 | AUTO_GENERATE_MIPMAP :: 0x8295; 1181 | COLOR_ENCODING :: 0x8296; 1182 | SRGB_READ :: 0x8297; 1183 | SRGB_WRITE :: 0x8298; 1184 | FILTER :: 0x829A; 1185 | VERTEX_TEXTURE :: 0x829B; 1186 | TESS_CONTROL_TEXTURE :: 0x829C; 1187 | TESS_EVALUATION_TEXTURE :: 0x829D; 1188 | GEOMETRY_TEXTURE :: 0x829E; 1189 | FRAGMENT_TEXTURE :: 0x829F; 1190 | COMPUTE_TEXTURE :: 0x82A0; 1191 | TEXTURE_SHADOW :: 0x82A1; 1192 | TEXTURE_GATHER :: 0x82A2; 1193 | TEXTURE_GATHER_SHADOW :: 0x82A3; 1194 | SHADER_IMAGE_LOAD :: 0x82A4; 1195 | SHADER_IMAGE_STORE :: 0x82A5; 1196 | SHADER_IMAGE_ATOMIC :: 0x82A6; 1197 | IMAGE_TEXEL_SIZE :: 0x82A7; 1198 | IMAGE_COMPATIBILITY_CLASS :: 0x82A8; 1199 | IMAGE_PIXEL_FORMAT :: 0x82A9; 1200 | IMAGE_PIXEL_TYPE :: 0x82AA; 1201 | SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST :: 0x82AC; 1202 | SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST :: 0x82AD; 1203 | SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE :: 0x82AE; 1204 | SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE :: 0x82AF; 1205 | TEXTURE_COMPRESSED_BLOCK_WIDTH :: 0x82B1; 1206 | TEXTURE_COMPRESSED_BLOCK_HEIGHT :: 0x82B2; 1207 | TEXTURE_COMPRESSED_BLOCK_SIZE :: 0x82B3; 1208 | CLEAR_BUFFER :: 0x82B4; 1209 | TEXTURE_VIEW :: 0x82B5; 1210 | VIEW_COMPATIBILITY_CLASS :: 0x82B6; 1211 | FULL_SUPPORT :: 0x82B7; 1212 | CAVEAT_SUPPORT :: 0x82B8; 1213 | IMAGE_CLASS_4_X_32 :: 0x82B9; 1214 | IMAGE_CLASS_2_X_32 :: 0x82BA; 1215 | IMAGE_CLASS_1_X_32 :: 0x82BB; 1216 | IMAGE_CLASS_4_X_16 :: 0x82BC; 1217 | IMAGE_CLASS_2_X_16 :: 0x82BD; 1218 | IMAGE_CLASS_1_X_16 :: 0x82BE; 1219 | IMAGE_CLASS_4_X_8 :: 0x82BF; 1220 | IMAGE_CLASS_2_X_8 :: 0x82C0; 1221 | IMAGE_CLASS_1_X_8 :: 0x82C1; 1222 | IMAGE_CLASS_11_11_10 :: 0x82C2; 1223 | IMAGE_CLASS_10_10_10_2 :: 0x82C3; 1224 | VIEW_CLASS_128_BITS :: 0x82C4; 1225 | VIEW_CLASS_96_BITS :: 0x82C5; 1226 | VIEW_CLASS_64_BITS :: 0x82C6; 1227 | VIEW_CLASS_48_BITS :: 0x82C7; 1228 | VIEW_CLASS_32_BITS :: 0x82C8; 1229 | VIEW_CLASS_24_BITS :: 0x82C9; 1230 | VIEW_CLASS_16_BITS :: 0x82CA; 1231 | VIEW_CLASS_8_BITS :: 0x82CB; 1232 | VIEW_CLASS_S3TC_DXT1_RGB :: 0x82CC; 1233 | VIEW_CLASS_S3TC_DXT1_RGBA :: 0x82CD; 1234 | VIEW_CLASS_S3TC_DXT3_RGBA :: 0x82CE; 1235 | VIEW_CLASS_S3TC_DXT5_RGBA :: 0x82CF; 1236 | VIEW_CLASS_RGTC1_RED :: 0x82D0; 1237 | VIEW_CLASS_RGTC2_RG :: 0x82D1; 1238 | VIEW_CLASS_BPTC_UNORM :: 0x82D2; 1239 | VIEW_CLASS_BPTC_FLOAT :: 0x82D3; 1240 | UNIFORM :: 0x92E1; 1241 | UNIFORM_BLOCK :: 0x92E2; 1242 | PROGRAM_INPUT :: 0x92E3; 1243 | PROGRAM_OUTPUT :: 0x92E4; 1244 | BUFFER_VARIABLE :: 0x92E5; 1245 | SHADER_STORAGE_BLOCK :: 0x92E6; 1246 | VERTEX_SUBROUTINE :: 0x92E8; 1247 | TESS_CONTROL_SUBROUTINE :: 0x92E9; 1248 | TESS_EVALUATION_SUBROUTINE :: 0x92EA; 1249 | GEOMETRY_SUBROUTINE :: 0x92EB; 1250 | FRAGMENT_SUBROUTINE :: 0x92EC; 1251 | COMPUTE_SUBROUTINE :: 0x92ED; 1252 | VERTEX_SUBROUTINE_UNIFORM :: 0x92EE; 1253 | TESS_CONTROL_SUBROUTINE_UNIFORM :: 0x92EF; 1254 | TESS_EVALUATION_SUBROUTINE_UNIFORM :: 0x92F0; 1255 | GEOMETRY_SUBROUTINE_UNIFORM :: 0x92F1; 1256 | FRAGMENT_SUBROUTINE_UNIFORM :: 0x92F2; 1257 | COMPUTE_SUBROUTINE_UNIFORM :: 0x92F3; 1258 | TRANSFORM_FEEDBACK_VARYING :: 0x92F4; 1259 | ACTIVE_RESOURCES :: 0x92F5; 1260 | MAX_NAME_LENGTH :: 0x92F6; 1261 | MAX_NUM_ACTIVE_VARIABLES :: 0x92F7; 1262 | MAX_NUM_COMPATIBLE_SUBROUTINES :: 0x92F8; 1263 | NAME_LENGTH :: 0x92F9; 1264 | TYPE :: 0x92FA; 1265 | ARRAY_SIZE :: 0x92FB; 1266 | OFFSET :: 0x92FC; 1267 | BLOCK_INDEX :: 0x92FD; 1268 | ARRAY_STRIDE :: 0x92FE; 1269 | MATRIX_STRIDE :: 0x92FF; 1270 | IS_ROW_MAJOR :: 0x9300; 1271 | ATOMIC_COUNTER_BUFFER_INDEX :: 0x9301; 1272 | BUFFER_BINDING :: 0x9302; 1273 | BUFFER_DATA_SIZE :: 0x9303; 1274 | NUM_ACTIVE_VARIABLES :: 0x9304; 1275 | ACTIVE_VARIABLES :: 0x9305; 1276 | REFERENCED_BY_VERTEX_SHADER :: 0x9306; 1277 | REFERENCED_BY_TESS_CONTROL_SHADER :: 0x9307; 1278 | REFERENCED_BY_TESS_EVALUATION_SHADER :: 0x9308; 1279 | REFERENCED_BY_GEOMETRY_SHADER :: 0x9309; 1280 | REFERENCED_BY_FRAGMENT_SHADER :: 0x930A; 1281 | REFERENCED_BY_COMPUTE_SHADER :: 0x930B; 1282 | TOP_LEVEL_ARRAY_SIZE :: 0x930C; 1283 | TOP_LEVEL_ARRAY_STRIDE :: 0x930D; 1284 | LOCATION :: 0x930E; 1285 | LOCATION_INDEX :: 0x930F; 1286 | IS_PER_PATCH :: 0x92E7; 1287 | SHADER_STORAGE_BUFFER :: 0x90D2; 1288 | SHADER_STORAGE_BUFFER_BINDING :: 0x90D3; 1289 | SHADER_STORAGE_BUFFER_START :: 0x90D4; 1290 | SHADER_STORAGE_BUFFER_SIZE :: 0x90D5; 1291 | MAX_VERTEX_SHADER_STORAGE_BLOCKS :: 0x90D6; 1292 | MAX_GEOMETRY_SHADER_STORAGE_BLOCKS :: 0x90D7; 1293 | MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS :: 0x90D8; 1294 | MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS :: 0x90D9; 1295 | MAX_FRAGMENT_SHADER_STORAGE_BLOCKS :: 0x90DA; 1296 | MAX_COMPUTE_SHADER_STORAGE_BLOCKS :: 0x90DB; 1297 | MAX_COMBINED_SHADER_STORAGE_BLOCKS :: 0x90DC; 1298 | MAX_SHADER_STORAGE_BUFFER_BINDINGS :: 0x90DD; 1299 | MAX_SHADER_STORAGE_BLOCK_SIZE :: 0x90DE; 1300 | SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT :: 0x90DF; 1301 | SHADER_STORAGE_BARRIER_BIT :: 0x00002000; 1302 | MAX_COMBINED_SHADER_OUTPUT_RESOURCES :: 0x8F39; 1303 | DEPTH_STENCIL_TEXTURE_MODE :: 0x90EA; 1304 | TEXTURE_BUFFER_OFFSET :: 0x919D; 1305 | TEXTURE_BUFFER_SIZE :: 0x919E; 1306 | TEXTURE_BUFFER_OFFSET_ALIGNMENT :: 0x919F; 1307 | TEXTURE_VIEW_MIN_LEVEL :: 0x82DB; 1308 | TEXTURE_VIEW_NUM_LEVELS :: 0x82DC; 1309 | TEXTURE_VIEW_MIN_LAYER :: 0x82DD; 1310 | TEXTURE_VIEW_NUM_LAYERS :: 0x82DE; 1311 | TEXTURE_IMMUTABLE_LEVELS :: 0x82DF; 1312 | VERTEX_ATTRIB_BINDING :: 0x82D4; 1313 | VERTEX_ATTRIB_RELATIVE_OFFSET :: 0x82D5; 1314 | VERTEX_BINDING_DIVISOR :: 0x82D6; 1315 | VERTEX_BINDING_OFFSET :: 0x82D7; 1316 | VERTEX_BINDING_STRIDE :: 0x82D8; 1317 | MAX_VERTEX_ATTRIB_RELATIVE_OFFSET :: 0x82D9; 1318 | MAX_VERTEX_ATTRIB_BINDINGS :: 0x82DA; 1319 | VERTEX_BINDING_BUFFER :: 0x8F4F; 1320 | 1321 | MAX_VERTEX_ATTRIB_STRIDE :: 0x82E5; 1322 | PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED :: 0x8221; 1323 | TEXTURE_BUFFER_BINDING :: 0x8C2A; 1324 | MAP_PERSISTENT_BIT :: 0x0040; 1325 | MAP_COHERENT_BIT :: 0x0080; 1326 | DYNAMIC_STORAGE_BIT :: 0x0100; 1327 | CLIENT_STORAGE_BIT :: 0x0200; 1328 | CLIENT_MAPPED_BUFFER_BARRIER_BIT :: 0x00004000; 1329 | BUFFER_IMMUTABLE_STORAGE :: 0x821F; 1330 | BUFFER_STORAGE_FLAGS :: 0x8220; 1331 | CLEAR_TEXTURE :: 0x9365; 1332 | LOCATION_COMPONENT :: 0x934A; 1333 | TRANSFORM_FEEDBACK_BUFFER_INDEX :: 0x934B; 1334 | TRANSFORM_FEEDBACK_BUFFER_STRIDE :: 0x934C; 1335 | QUERY_BUFFER :: 0x9192; 1336 | QUERY_BUFFER_BARRIER_BIT :: 0x00008000; 1337 | QUERY_BUFFER_BINDING :: 0x9193; 1338 | QUERY_RESULT_NO_WAIT :: 0x9194; 1339 | MIRROR_CLAMP_TO_EDGE :: 0x8743; 1340 | 1341 | CONTEXT_LOST :: 0x0507; 1342 | NEGATIVE_ONE_TO_ONE :: 0x935E; 1343 | ZERO_TO_ONE :: 0x935F; 1344 | CLIP_ORIGIN :: 0x935C; 1345 | CLIP_DEPTH_MODE :: 0x935D; 1346 | QUERY_WAIT_INVERTED :: 0x8E17; 1347 | QUERY_NO_WAIT_INVERTED :: 0x8E18; 1348 | QUERY_BY_REGION_WAIT_INVERTED :: 0x8E19; 1349 | QUERY_BY_REGION_NO_WAIT_INVERTED :: 0x8E1A; 1350 | MAX_CULL_DISTANCES :: 0x82F9; 1351 | MAX_COMBINED_CLIP_AND_CULL_DISTANCES :: 0x82FA; 1352 | TEXTURE_TARGET :: 0x1006; 1353 | QUERY_TARGET :: 0x82EA; 1354 | GUILTY_CONTEXT_RESET :: 0x8253; 1355 | INNOCENT_CONTEXT_RESET :: 0x8254; 1356 | UNKNOWN_CONTEXT_RESET :: 0x8255; 1357 | RESET_NOTIFICATION_STRATEGY :: 0x8256; 1358 | LOSE_CONTEXT_ON_RESET :: 0x8252; 1359 | NO_RESET_NOTIFICATION :: 0x8261; 1360 | CONTEXT_FLAG_ROBUST_ACCESS_BIT :: 0x00000004; 1361 | CONTEXT_RELEASE_BEHAVIOR :: 0x82FB; 1362 | CONTEXT_RELEASE_BEHAVIOR_FLUSH :: 0x82FC; 1363 | 1364 | DEBUG_OUTPUT_SYNCHRONOUS_ARB :: 0x8242; 1365 | DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB :: 0x8243; 1366 | DEBUG_CALLBACK_FUNCTION_ARB :: 0x8244; 1367 | DEBUG_CALLBACK_USER_PARAM_ARB :: 0x8245; 1368 | DEBUG_SOURCE_API_ARB :: 0x8246; 1369 | DEBUG_SOURCE_WINDOW_SYSTEM_ARB :: 0x8247; 1370 | DEBUG_SOURCE_SHADER_COMPILER_ARB :: 0x8248; 1371 | DEBUG_SOURCE_THIRD_PARTY_ARB :: 0x8249; 1372 | DEBUG_SOURCE_APPLICATION_ARB :: 0x824A; 1373 | DEBUG_SOURCE_OTHER_ARB :: 0x824B; 1374 | DEBUG_TYPE_ERROR_ARB :: 0x824C; 1375 | DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB :: 0x824D; 1376 | DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB :: 0x824E; 1377 | DEBUG_TYPE_PORTABILITY_ARB :: 0x824F; 1378 | DEBUG_TYPE_PERFORMANCE_ARB :: 0x8250; 1379 | DEBUG_TYPE_OTHER_ARB :: 0x8251; 1380 | MAX_DEBUG_MESSAGE_LENGTH_ARB :: 0x9143; 1381 | MAX_DEBUG_LOGGED_MESSAGES_ARB :: 0x9144; 1382 | DEBUG_LOGGED_MESSAGES_ARB :: 0x9145; 1383 | DEBUG_SEVERITY_HIGH_ARB :: 0x9146; 1384 | DEBUG_SEVERITY_MEDIUM_ARB :: 0x9147; 1385 | DEBUG_SEVERITY_LOW_ARB :: 0x9148; 1386 | 1387 | 1388 | SHADER_BINARY_FORMAT_SPIR_V :: 0x9551; 1389 | SPIR_V_BINARY :: 0x9552; 1390 | PARAMETER_BUFFER :: 0x80EE; 1391 | PARAMETER_BUFFER_BINDING :: 0x80EF; 1392 | CONTEXT_FLAG_NO_ERROR_BIT :: 0x00000008; 1393 | VERTICES_SUBMITTED :: 0x82EE; 1394 | PRIMITIVES_SUBMITTED :: 0x82EF; 1395 | VERTEX_SHADER_INVOCATIONS :: 0x82F0; 1396 | TESS_CONTROL_SHADER_PATCHES :: 0x82F1; 1397 | TESS_EVALUATION_SHADER_INVOCATIONS :: 0x82F2; 1398 | GEOMETRY_SHADER_PRIMITIVES_EMITTED :: 0x82F3; 1399 | FRAGMENT_SHADER_INVOCATIONS :: 0x82F4; 1400 | COMPUTE_SHADER_INVOCATIONS :: 0x82F5; 1401 | CLIPPING_INPUT_PRIMITIVES :: 0x82F6; 1402 | CLIPPING_OUTPUT_PRIMITIVES :: 0x82F7; 1403 | POLYGON_OFFSET_CLAMP :: 0x8E1B; 1404 | SPIR_V_EXTENSIONS :: 0x9553; 1405 | NUM_SPIR_V_EXTENSIONS :: 0x9554; 1406 | TEXTURE_MAX_ANISOTROPY :: 0x84FE; 1407 | MAX_TEXTURE_MAX_ANISOTROPY :: 0x84FF; 1408 | TRANSFORM_FEEDBACK_OVERFLOW :: 0x82EC; 1409 | TRANSFORM_FEEDBACK_STREAM_OVERFLOW :: 0x82ED; 1410 | 1411 | // Extensions, extended as necessary 1412 | DEVICE_LUID_EXT :: 0x9599; 1413 | --------------------------------------------------------------------------------