From 8998bc3936f4dce4edba66d4b2c23faa5944e496 Mon Sep 17 00:00:00 2001 From: Tarion <> Date: Thu, 2 Jul 2026 04:02:29 +0200 Subject: [PATCH] everything --- .idea/codeStyles/codeStyleConfig.xml | 5 + CMakeLists.txt | 96 +- assets/shaders/basicFragment.frag | 218 +- assets/shaders/basicVertex.vert | 8 +- engine/blend_importer/export_embedded_fbx.py | 4 + engine/camera.h | 19 +- engine/mesh.h | 178 +- engine/model.h | 260 + engine/shader.h | 25 +- engine/texture.h | 53 - game/game.cpp | 3 + game/game.h | 9 + main.cpp | 268 +- vendor/glfw/glfw3.dll | Bin 305664 -> 0 bytes vendor/glfw/glfw3.h | 6547 ------------------ vendor/glfw/glfw3native.h | 663 -- vendor/glfw/libglfw3.a | Bin 334770 -> 0 bytes vendor/glfw/libglfw3dll.a | Bin 89452 -> 0 bytes vendor/stb/stb_image.cpp | 3 +- 19 files changed, 855 insertions(+), 7504 deletions(-) create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 engine/blend_importer/export_embedded_fbx.py create mode 100644 engine/model.h delete mode 100644 engine/texture.h create mode 100644 game/game.cpp create mode 100644 game/game.h delete mode 100644 vendor/glfw/glfw3.dll delete mode 100644 vendor/glfw/glfw3.h delete mode 100644 vendor/glfw/glfw3native.h delete mode 100644 vendor/glfw/libglfw3.a delete mode 100644 vendor/glfw/libglfw3dll.a diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c47b54b..d3af58d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,48 +5,80 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -find_package(OpenGL REQUIRED) -find_package(glfw3 3.3 QUIET) - -if(NOT glfw3_FOUND) - message(STATUS "glfw3 not found via find_package") - if(WIN32) - set(GLFW_LIB "${CMAKE_CURRENT_SOURCE_DIR}/vendor/glfw/libglfw3.a") - else() - message(FATAL_ERROR "GLFW not found") - endif() -endif() - -add_executable(Engine2026 +# ------------------------------------------------------------------------------ +# 1. Source and Header Files +# ------------------------------------------------------------------------------ +set(SOURCES main.cpp + vendor/glad/glad.c + vendor/stb/stb_image.cpp +) + +set(HEADERS engine/shader.h engine/texture.h engine/mesh.h - vendor/glad/glad.c engine/camera.h + game/game.cpp + game/game.h ) -target_include_directories(Engine2026 PRIVATE +# Create the executable +add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) + +# ------------------------------------------------------------------------------ +# 2. Include Directories +# ------------------------------------------------------------------------------ +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/vendor + ${CMAKE_CURRENT_SOURCE_DIR}/vendor/assimp/include ) -if(glfw3_FOUND) - target_link_libraries(Engine2026 PRIVATE glfw OpenGL::GL) -else() - target_link_libraries(Engine2026 PRIVATE - ${GLFW_LIB} - opengl32 - gdi32 - user32 - ) -endif() +# ------------------------------------------------------------------------------ +# 3. Dependencies & Linking +# ------------------------------------------------------------------------------ -# Copy assets to build dir -add_custom_command( - TARGET Engine2026 POST_BUILD +# -- OpenGL -- +find_package(OpenGL REQUIRED) +target_link_libraries(${PROJECT_NAME} PRIVATE OpenGL::GL) + +# -- GLFW (Built from source) -- +# Turn off extra GLFW targets to speed up your compile times +set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + +# Add the GLFW source directory. +# NOTE: This automatically handles all underlying OS dependencies (gdi32, X11, Cocoa, etc.) +add_subdirectory(vendor/glfw) + +# Link the GLFW target +target_link_libraries(${PROJECT_NAME} PRIVATE glfw) + +# -- Assimp (Built from source) -- +# Turn off extra Assimp targets to speed up compile times +set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE BOOL "" FORCE) + +# Add the Assimp source directory +add_subdirectory(vendor/assimp) +# Link the GLFW and Assimp targets +target_link_libraries(${PROJECT_NAME} PRIVATE glfw assimp) + +# ------------------------------------------------------------------------------ +# 4. Asset Synchronization (Runs Every Single Compile) +# ------------------------------------------------------------------------------ + +add_custom_target(refresh_assets + # Step 1: Wipe the assets folder using a static configuration path + COMMAND ${CMAKE_COMMAND} -E rm -rf "${CMAKE_CURRENT_BINARY_DIR}/assets" + # Step 2: Copy them fresh COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/assets - $/assets - COMMENT "Copying assets to output directory" -) \ No newline at end of file + "${CMAKE_CURRENT_SOURCE_DIR}/assets" + "${CMAKE_CURRENT_BINARY_DIR}/assets" + COMMENT "Force-syncing assets to build directory..." +) + +# This now safely runs BEFORE the executable compiles, without the dependency loop +add_dependencies(${PROJECT_NAME} refresh_assets) \ No newline at end of file diff --git a/assets/shaders/basicFragment.frag b/assets/shaders/basicFragment.frag index b64ba4e..f33c7ae 100644 --- a/assets/shaders/basicFragment.frag +++ b/assets/shaders/basicFragment.frag @@ -1,56 +1,204 @@ #version 330 core out vec4 FragColor; + +struct Material { + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +struct DirectionalLight { + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +struct PointLight { + bool disabled; + + vec3 position; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +struct SpotLight { + bool disabled; + + vec3 position; + vec3 direction; + float cutOff; + float outerCutOff; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +struct Decal { + sampler2D tex; + float opacity; + vec4 uvCoords; +}; + in vec3 FragPos; in vec3 Normal; -in vec2 TexCoord; +in vec2 TexCoords; -uniform sampler2D ourTexture; -uniform sampler2D decal; +#define MAX_POINT_LIGHTS 4 +#define MAX_SPOT_LIGHTS 4 +#define MAX_DECALS 4 + +// Texture & Decals +uniform Material material; +uniform sampler2D mainTexture; +uniform Decal decals[MAX_DECALS]; +uniform int numberOfDecals; -uniform vec3 lightPos; -uniform vec3 lightColor; uniform vec3 viewPos; -vec4 calcTextures(){ - vec4 tex1 = texture(ourTexture, TexCoord); - vec4 tex2 = texture(decal, TexCoord); - vec4 textures = mix(tex1, tex2, 0.2f); +// Lights +uniform DirectionalLight dirLight; - return textures; -} +uniform PointLight pointLights[MAX_POINT_LIGHTS]; +uniform int numberOfPointLights; -vec4 calcDirectLight(norm, viewDir){ - // Ambient Lighting - float ambientStrength = 0.1; - vec3 ambient = ambientStrength * lightColor; +uniform SpotLight spotLights[MAX_SPOT_LIGHTS]; +uniform int numberOfSpotLights; - // Diffuse Lighting - vec3 lightDir = normalize(lightPos - FragPos); - - float diff = max(dot(norm, lightDir), 0.0); - vec3 diffuse = diff * lightColor; - - // Specular Lighting - float specularStrength = 0.5; - - vec3 reflectDir = reflect(-lightDir, norm); - - float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); - vec3 specular = specularStrength * spec * lightColor; - - vec4 result = vec4(ambient.rgb + diffuse.rgb + specular.rgb, 1.0f); - - return result; -} +// func declarations +vec3 calcTextures(); +vec4 calcDirectLight(DirectionalLight light, vec3 normal, vec3 viewDir, vec3 albedo); +vec4 calcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo); +vec4 calcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo); void main() { + vec4 result = vec4(0.0f); + vec3 norm = normalize(Normal); vec3 viewDir = normalize(viewPos - FragPos); - vec4 result = calcTextures(); - result += calcDirectLight(norm, viewDir); + vec3 albedo = calcTextures(); + albedo = vec3(1,1,1); + + //result += calcDirectLight(dirLight, norm, viewDir, albedo); + + for(int i = 0; i < numberOfPointLights; i++){ + if (pointLights[i].disabled) continue; + result += calcPointLight(pointLights[i], norm, FragPos, viewDir, albedo); + } + + for(int i = 0; i < numberOfSpotLights; i++){ + if (spotLights[i].disabled) continue; + result += calcSpotLight(spotLights[i], norm, FragPos, viewDir, albedo); + } FragColor = result; } + + +vec3 calcTextures(){ + vec4 textureAsVec = texture(mainTexture, TexCoords); + + vec4 decalMix; + for(int i = 0; i < numberOfDecals; i++){ + // We invert the 2nd one to make uv scaling easier + vec2 decalCoords = TexCoords * (1.0 / decals[i].uvCoords.xy) + decals[i].uvCoords.zw;; + + vec4 decal = texture(decals[i].tex, decalCoords); + + decalMix += mix(decalMix, decal, 0.2f); + } + + vec4 finalMix = mix(textureAsVec, decalMix, 0.2f); + + return vec3(finalMix); +} + +// calculates the color when using a directional light. +vec4 calcDirectLight(DirectionalLight light, vec3 norm, vec3 viewDir, vec3 albedo) +{ + vec3 lightDir = normalize(-light.direction); + + // diffuse shading + float diff = max(dot(norm, lightDir), 0.0); + + // specular shading + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + + // combine results + vec3 ambient = light.ambient * albedo; + vec3 diffuse = light.diffuse * diff * albedo; + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + + return vec4(ambient + diffuse + specular, 1.0f); +} + +vec4 calcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo) +{ + vec3 lightDir = normalize(light.position - fragPos); + + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + + // combine results + vec3 ambient = light.ambient * albedo; + vec3 diffuse = light.diffuse * diff * albedo; + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + ambient *= attenuation; + diffuse *= attenuation; + specular *= attenuation; + + return vec4(ambient + diffuse + specular, 1.0f); +} + +vec4 calcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec3 albedo) +{ + vec3 lightDir = normalize(light.position - fragPos); + + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + + // spotlight intensity + float theta = dot(lightDir, normalize(-light.direction)); + float epsilon = light.cutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); + + // combine results + vec3 ambient = light.ambient * albedo; + vec3 diffuse = light.diffuse * diff * albedo; + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); + ambient *= attenuation * intensity; + diffuse *= attenuation * intensity; + specular *= attenuation * intensity; + + return vec4(ambient + diffuse + specular, 1.0f); +} \ No newline at end of file diff --git a/assets/shaders/basicVertex.vert b/assets/shaders/basicVertex.vert index 887b27f..1c82e0e 100644 --- a/assets/shaders/basicVertex.vert +++ b/assets/shaders/basicVertex.vert @@ -5,7 +5,7 @@ layout (location = 2) in vec2 aTexCoord; out vec3 FragPos; out vec3 Normal; -out vec2 TexCoord; +out vec2 TexCoords; uniform mat4 model; uniform mat4 view; @@ -13,9 +13,9 @@ uniform mat4 projection; void main() { - FragPos = vec3(model * vec4(aPos, 1.0)); + FragPos = vec3(model * vec4(aPos, 1.0f)); Normal = mat3(transpose(inverse(model))) * aNormal; - TexCoord = aTexCoord; + TexCoords = aTexCoord; gl_Position = projection * view * model * vec4(aPos, 1.0f); -} +} \ No newline at end of file diff --git a/engine/blend_importer/export_embedded_fbx.py b/engine/blend_importer/export_embedded_fbx.py new file mode 100644 index 0000000..82a0769 --- /dev/null +++ b/engine/blend_importer/export_embedded_fbx.py @@ -0,0 +1,4 @@ +import bpy +import sys + +bpy.ops.export_scene.fbx(filepath=sys.argv[-1], path_mode='COPY', embed_textures=True) \ No newline at end of file diff --git a/engine/camera.h b/engine/camera.h index ce01cd1..c9586f1 100644 --- a/engine/camera.h +++ b/engine/camera.h @@ -11,13 +11,14 @@ enum Camera_Movement { FORWARD, BACKWARD, LEFT, - RIGHT + RIGHT, + SPRINT }; // Default camera values const float YAW = -90.0f; const float PITCH = 0.0f; -const float SPEED = 2.5f; +const float SPEED = 5.5f; const float SENSITIVITY = 0.1f; const float ZOOM = 45.0f; @@ -27,6 +28,7 @@ public: glm::vec3 position, front, up, right, worldUp; float yaw, pitch; float movementSpeed, mouseSensitivity, zoom; + bool sprinting = false; // constructor with vectors Camera(glm::vec3 newPosition = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float newYaw = YAW, float newPitch = PITCH) : front(glm::vec3(0.0f, 0.0f, -1.0f)), movementSpeed(SPEED), mouseSensitivity(SENSITIVITY), zoom(ZOOM) @@ -57,6 +59,9 @@ public: void processKeyboard(Camera_Movement direction, float deltaTime) { float velocity = movementSpeed * deltaTime; + if (sprinting) + velocity *= 8; + if (direction == FORWARD) position += front * velocity; if (direction == BACKWARD) @@ -65,6 +70,8 @@ public: position -= right * velocity; if (direction == RIGHT) position += right * velocity; + if (direction == SPRINT) + sprinting = !sprinting; } // processes input received from a mouse input system. Expects the offset value in both the x and y direction. @@ -100,6 +107,14 @@ public: zoom = 45.0f; } + void Update(Shader shader, int screenWidth, int screenHeight) + { + glm::mat4 projection = glm::perspective(glm::radians(zoom), (float)screenWidth / (float)screenHeight, 0.1f, 100.0f); + + shader.setMat4("projection", projection); + shader.setMat4("view", GetViewMatrix()); + shader.setVec3("viewPos", position); + } private: // calculates the front vector from the Camera's (updated) Euler Angles diff --git a/engine/mesh.h b/engine/mesh.h index acf1a11..e121767 100644 --- a/engine/mesh.h +++ b/engine/mesh.h @@ -1,63 +1,147 @@  -#include +#ifndef ENGINE2026_MESH_H +#define ENGINE2026_MESH_H + +#include // holds all OpenGL type declarations + +#include +#include + +#include + +#include #include -#include +using namespace std; + +#define MAX_BONE_INFLUENCE 4 struct Vertex { - float x, y, z; // position - float nX, nY, zY; // normal - float u, v; // texcoord + // position + glm::vec3 Position; + // normal + glm::vec3 Normal; + // texCoords + glm::vec2 TexCoords; + // tangent + glm::vec3 Tangent; + // bitangent + glm::vec3 Bitangent; + //bone indexes which will influence this vertex + int m_BoneIDs[MAX_BONE_INFLUENCE]; + //weights from each bone + float m_Weights[MAX_BONE_INFLUENCE]; }; -class Mesh -{ +struct Texture { + unsigned int id; + string type; + string path; +}; + +class Mesh { public: - unsigned int VBO, VAO, EBO; - std::size_t indexCount = 0; + // mesh Data + vector vertices; + vector indices; + vector textures; + unsigned int VAO; - Mesh(const std::vector& vertices, const std::vector& indices) : indexCount(indices.size()) - { - if (vertices.empty() || indices.empty()) { - throw std::runtime_error("Mesh created with empty vertices or indices"); - } - - try - { - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - glGenBuffers(1, &EBO); + // constructor + Mesh(vector vertices, vector indices, vector textures) + { + this->vertices = vertices; + this->indices = indices; + this->textures = textures; - glBindVertexArray(VAO); + // now that we have all the required data, set the vertex buffers and its attribute pointers. + setupMesh(); + } - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); + // render the mesh + void Draw(Shader &shader) + { + // bind appropriate textures + unsigned int diffuseNr = 1; + unsigned int specularNr = 1; + unsigned int normalNr = 1; + unsigned int heightNr = 1; + for(unsigned int i = 0; i < textures.size(); i++) + { + glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding + // retrieve texture number (the N in diffuse_textureN) + string number; + string name = textures[i].type; + if(name == "texture_diffuse") + number = std::to_string(diffuseNr++); + else if(name == "texture_specular") + number = std::to_string(specularNr++); // transfer unsigned int to string + else if(name == "texture_normal") + number = std::to_string(normalNr++); // transfer unsigned int to string + else if(name == "texture_height") + number = std::to_string(heightNr++); // transfer unsigned int to string - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW); + // now set the sampler to the correct texture unit + glUniform1i(glGetUniformLocation(shader.ID, (name + number).c_str()), i); + // and finally bind the texture + glBindTexture(GL_TEXTURE_2D, textures[i].id); + } - // Position - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x)); - glEnableVertexAttribArray(0); + // draw mesh + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, static_cast(indices.size()), GL_UNSIGNED_INT, 0); + glBindVertexArray(0); - // Normals - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, nX)); - glEnableVertexAttribArray(1); + // always good practice to set everything back to defaults once configured. + glActiveTexture(GL_TEXTURE0); + } - // Texcoords - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, u)); - glEnableVertexAttribArray(2); - } - catch (...) - { - std::cout << "Failed to load mesh" << std::endl; - } - } +private: + // render data + unsigned int VBO, EBO; - void Draw() const - { - //glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(VAO); - glDrawElements(GL_TRIANGLES, static_cast(indexCount), - GL_UNSIGNED_INT, 0); - } + // initializes all the buffer objects/arrays + void setupMesh() + { + // create buffers/arrays + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); + + glBindVertexArray(VAO); + // load data into vertex buffers + glBindBuffer(GL_ARRAY_BUFFER, VBO); + // A great thing about structs is that their memory layout is sequential for all its items. + // The effect is that we can simply pass a pointer to the struct and it translates perfectly to a glm::vec3/2 array which + // again translates to 3/2 floats which translates to a byte array. + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); + + // set the vertex attribute pointers + // vertex Positions + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); + // vertex normals + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal)); + // vertex texture coords + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords)); + // vertex tangent + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent)); + // vertex bitangent + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Bitangent)); + // ids + glEnableVertexAttribArray(5); + glVertexAttribIPointer(5, 4, GL_INT, sizeof(Vertex), (void*)offsetof(Vertex, m_BoneIDs)); + + // weights + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, m_Weights)); + glBindVertexArray(0); + } }; +#endif //ENGINE2026_MESH_H diff --git a/engine/model.h b/engine/model.h new file mode 100644 index 0000000..aaeb8e8 --- /dev/null +++ b/engine/model.h @@ -0,0 +1,260 @@ + +#ifndef ENGINE2026_MODEL_H +#define ENGINE2026_MODEL_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +unsigned int TextureFromFile(const char *path, const string &directory, bool gamma = false); + +class Model +{ +public: + // model data + vector textures_loaded; // stores all the textures loaded so far, optimization to make sure textures aren't loaded more than once. + vector meshes; + string directory; + bool gammaCorrection; + + // constructor, expects a filepath to a 3D model. + Model(string const &path, bool gamma = false) : gammaCorrection(gamma) + { + loadModel(path); + } + + // draws the model, and thus all its meshes + void Draw(Shader &shader) + { + for(unsigned int i = 0; i < meshes.size(); i++) + meshes[i].Draw(shader); + } + +private: + // loads a model with supported ASSIMP extensions from file and stores the resulting meshes in the meshes vector. + void loadModel(string const &path) + { + // read file via ASSIMP + Assimp::Importer importer; + const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_CalcTangentSpace); + // check for errors + if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero + { + cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << endl; + return; + } + // retrieve the directory path of the filepath + directory = path.substr(0, path.find_last_of('/')); + + // process ASSIMP's root node recursively + processNode(scene->mRootNode, scene); + } + + // processes a node in a recursive fashion. Processes each individual mesh located at the node and repeats this process on its children nodes (if any). + void processNode(aiNode *node, const aiScene *scene) + { + // process each mesh located at the current node + for(unsigned int i = 0; i < node->mNumMeshes; i++) + { + // the node object only contains indices to index the actual objects in the scene. + // the scene contains all the data, node is just to keep stuff organized (like relations between nodes). + aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; + meshes.push_back(processMesh(mesh, scene)); + } + // after we've processed all of the meshes (if any) we then recursively process each of the children nodes + for(unsigned int i = 0; i < node->mNumChildren; i++) + { + processNode(node->mChildren[i], scene); + } + + } + + Mesh processMesh(aiMesh *mesh, const aiScene *scene) + { + // data to fill + vector vertices; + vector indices; + vector textures; + + // walk through each of the mesh's vertices + for(unsigned int i = 0; i < mesh->mNumVertices; i++) + { + Vertex vertex; + glm::vec3 vector; // we declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to glm's vec3 class so we transfer the data to this placeholder glm::vec3 first. + // positions + vector.x = mesh->mVertices[i].x; + vector.y = mesh->mVertices[i].y; + vector.z = mesh->mVertices[i].z; + vertex.Position = vector; + // normals + if (mesh->HasNormals()) + { + vector.x = mesh->mNormals[i].x; + vector.y = mesh->mNormals[i].y; + vector.z = mesh->mNormals[i].z; + vertex.Normal = vector; + } + // texture coordinates + if(mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? + { + glm::vec2 vec; + // a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't + // use models where a vertex can have multiple texture coordinates so we always take the first set (0). + vec.x = mesh->mTextureCoords[0][i].x; + vec.y = mesh->mTextureCoords[0][i].y; + vertex.TexCoords = vec; + // tangent + vector.x = mesh->mTangents[i].x; + vector.y = mesh->mTangents[i].y; + vector.z = mesh->mTangents[i].z; + vertex.Tangent = vector; + // bitangent + vector.x = mesh->mBitangents[i].x; + vector.y = mesh->mBitangents[i].y; + vector.z = mesh->mBitangents[i].z; + vertex.Bitangent = vector; + } + else + vertex.TexCoords = glm::vec2(0.0f, 0.0f); + + vertices.push_back(vertex); + } + // now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices. + for(unsigned int i = 0; i < mesh->mNumFaces; i++) + { + aiFace face = mesh->mFaces[i]; + // retrieve all indices of the face and store them in the indices vector + for(unsigned int j = 0; j < face.mNumIndices; j++) + indices.push_back(face.mIndices[j]); + } + // process materials + aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; + // we assume a convention for sampler names in the shaders. Each diffuse texture should be named + // as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER. + // Same applies to other texture as the following list summarizes: + // diffuse: texture_diffuseN + // specular: texture_specularN + // normal: texture_normalN + + // 1. diffuse maps + vector diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", true); + textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end()); + // 2. specular maps + vector specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular"); + textures.insert(textures.end(), specularMaps.begin(), specularMaps.end()); + // 3. normal maps + std::vector normalMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, "texture_normal"); + textures.insert(textures.end(), normalMaps.begin(), normalMaps.end()); + // 4. height maps + std::vector heightMaps = loadMaterialTextures(material, aiTextureType_AMBIENT, "texture_height"); + textures.insert(textures.end(), heightMaps.begin(), heightMaps.end()); + + // return a mesh object created from the extracted mesh data + return Mesh(vertices, indices, textures); + } + + // checks all material textures of a given type and loads the textures if they're not loaded yet. + // the required info is returned as a Texture struct. + vector loadMaterialTextures(aiMaterial *mat, aiTextureType type, string typeName, bool fallback = false) + { + vector textures; + for(unsigned int i = 0; i < mat->GetTextureCount(type); i++) + { + aiString str; + mat->GetTexture(type, i, &str); + // check if texture was loaded before and if so, continue to next iteration: skip loading a new texture + bool skip = false; + for(unsigned int j = 0; j < textures_loaded.size(); j++) + { + if(std::strcmp(textures_loaded[j].path.data(), str.C_Str()) == 0) + { + textures.push_back(textures_loaded[j]); + skip = true; // a texture with the same filepath has already been loaded, continue to next one. (optimization) + break; + } + } + if(!skip) + { // if texture hasn't been loaded already, load it + Texture texture; + texture.id = TextureFromFile(str.C_Str(), this->directory); + texture.type = typeName; + texture.path = str.C_Str(); + textures.push_back(texture); + textures_loaded.push_back(texture); // store it as texture loaded for entire model, to ensure we won't unnecessary load duplicate textures. + } + } + + // Load DefaultTexture if there isn't one already + if (mat->GetTextureCount(type) == 0) { + string defaultPath = "DefaultTexture.jpg"; + + Texture texture; + texture.id = TextureFromFile(defaultPath.c_str(), "assets/"); + texture.type = typeName; + texture.path = defaultPath; + textures.push_back(texture); + textures_loaded.push_back(texture); + } + + return textures; + } +}; + + +unsigned int TextureFromFile(const char *path, const string &directory, bool gamma) +{ + string filename = string(path); + filename = directory + '/' + filename; + + unsigned int textureID; + glGenTextures(1, &textureID); + + int width, height, nrComponents; + unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0); + if (data) + { + GLenum format; + if (nrComponents == 1) + format = GL_RED; + else if (nrComponents == 3) + format = GL_RGB; + else if (nrComponents == 4) + format = GL_RGBA; + + glBindTexture(GL_TEXTURE_2D, textureID); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + } + else + { + std::cout << "Texture failed to load at path: " << path << std::endl; + stbi_image_free(data); + } + + return textureID; +} +#endif //ENGINE2026_MODEL_H \ No newline at end of file diff --git a/engine/shader.h b/engine/shader.h index 3ceeca8..c2ce31e 100644 --- a/engine/shader.h +++ b/engine/shader.h @@ -42,8 +42,8 @@ public: fragmentCode = fragmentStream.str(); // Fix encoding issues, specifically for Linux - vertexCode.erase(std::remove(vertexCode.begin(), vertexCode.end(), '\r'), vertexCode.end()); - fragmentCode.erase(std::remove(fragmentCode.begin(), fragmentCode.end(), '\r'), fragmentCode.end()); + //vertexCode.erase(std::remove(vertexCode.begin(), vertexCode.end(), '\r'), vertexCode.end()); + //fragmentCode.erase(std::remove(fragmentCode.begin(), fragmentCode.end(), '\r'), fragmentCode.end()); } catch (std::ifstream::failure& e) { @@ -112,6 +112,11 @@ public: void setVec3(const std::string &name, float x, float y, float z) const { glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); + } + // ------------------------------------------------------------------------ + void setArr(const std::string &name, const GLint value[], const int &count) const + { + glUniform1iv(glGetUniformLocation(ID, name.c_str()), count, value); } // ------------------------------------------------------------------------ void setVec4(const std::string &name, const glm::vec4 &value) const @@ -137,7 +142,21 @@ public: { glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } - + + void setDecal(int index, GLint tex, float opacity, const glm::vec4& uvCoords) const { + std::string indexStr = std::to_string(index); + + GLint texLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].tex").c_str()); + if (texLoc != -1) glUniform1i(texLoc, tex); + + GLint opLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].opacity").c_str()); + if (opLoc != -1) glUniform1f(opLoc, opacity); + + GLint uvLoc = glGetUniformLocation(ID, ("decals[" + indexStr + "].uvCoords").c_str()); + if (uvLoc != -1) { + glUniform4fv(uvLoc, 1, &uvCoords[0]); + } + } private: void checkCompileErrors(unsigned int shader, std::string type) { diff --git a/engine/texture.h b/engine/texture.h deleted file mode 100644 index 21b20fc..0000000 --- a/engine/texture.h +++ /dev/null @@ -1,53 +0,0 @@ - -#include - -#include -#define STB_IMAGE_IMPLEMENTATION -#include - -class Texture -{ -public: - unsigned int ID; - int width, height, nrChannels; - - Texture(const char* texturePath, bool flip = false) - { - // Create the Texture and set our ID - glGenTextures(1, &ID); - glBindTexture(GL_TEXTURE_2D, ID); - - // set the texture wrapping/filtering options (on the currently bound texture object) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - // Grab the texture from our path - if (flip) - stbi_set_flip_vertically_on_load(true); - - unsigned char *data = stbi_load(texturePath, &width, &height, &nrChannels, 0); - if (data) - { - GLenum format = (nrChannels == 4) ? GL_RGBA : GL_RGB; - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - } - else - { - std::cout << "Failed to load texture" << std::endl; - } - - if (flip) - stbi_set_flip_vertically_on_load(false); - - stbi_image_free(data); - } - - void Draw() const - { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, ID); - } -}; diff --git a/game/game.cpp b/game/game.cpp new file mode 100644 index 0000000..76c659a --- /dev/null +++ b/game/game.cpp @@ -0,0 +1,3 @@ +// +// Created by claire on 28/06/2026. +// \ No newline at end of file diff --git a/game/game.h b/game/game.h new file mode 100644 index 0000000..69beb0f --- /dev/null +++ b/game/game.h @@ -0,0 +1,9 @@ + +namespace Game { + void Init(); + + void Update(); + void Render(); + void PreRender(); + void PostRender(); +} diff --git a/main.cpp b/main.cpp index 48c4724..e090de4 100644 --- a/main.cpp +++ b/main.cpp @@ -3,15 +3,13 @@ #include #include -#include +#include #include #include #include -#include "stb/stb_easy_font.h" -#include #include -#include +#include #include void window_resize_callback(GLFWwindow* window, int width, int height); @@ -19,11 +17,12 @@ void mouse_callback(GLFWwindow* window, double xpos, double ypos); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); void processInput(GLFWwindow *window); -const int SCREEN_WIDTH = 1920; -const int SCREEN_HEIGHT = 1080; +int SCREEN_WIDTH = 1920; +int SCREEN_HEIGHT = 1080; static bool drawWireframe = false; static bool wireframeHeld = false; +static bool flashlight = true; Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); float lastX = SCREEN_WIDTH / 2.0f; @@ -65,6 +64,8 @@ int main(int argc, char* argv[]) glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); + glEnable(GL_DEPTH_TEST); + // Hide & Lock Cursor glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); @@ -73,145 +74,167 @@ int main(int argc, char* argv[]) Testing */ - // Load Shader - std::vector vertices = { - // Front face (-z) – normal: (0, 0, -1) - { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, - { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f }, - { 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }, - { 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }, - { -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f }, - { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, - - // Back face (+z) – normal: (0, 0, +1) - { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f }, - { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }, - { 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }, - { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f }, - { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }, - - // Left face (-x) – normal: (-1, 0, 0) - { -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, - { -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f }, - { -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, - - // Right face (+x) – normal: (+1, 0, 0) - { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f }, - { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }, - { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }, - - // Bottom face (-y) – normal: (0, -1, 0) - { -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f }, - { 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f }, - { 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }, - { 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }, - { -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f }, - { -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f }, - - // Top face (+y) – normal: (0, +1, 0) - { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }, - { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }, - { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, - { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, - { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, - { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f } - }; - std::vector indices = { - 0, 1, 2, 2, 4, 0, - 6, 7, 8, 8, 10, 6, - 12, 13, 14, 14, 16, 12, - 18, 19, 20, 20, 22, 18, - 24, 25, 26, 26, 28, 24, - 30, 31, 32, 32, 34, 30 - }; - - Mesh testMesh(vertices, indices); - - Texture texture1("assets/wall.jpg"); - Texture texture2("assets/awesomeface.png", true); - Shader shaderTest("assets/shaders/basicVertex.vert", "assets/shaders/basicFragment.frag"); - shaderTest.Use(); // don't forget to activate/use the shader before setting uniforms! - shaderTest.setInt("ourTexture", 0); - shaderTest.setInt("decal", 1); - Shader lightingShader("assets/shaders/basicVertex.vert", "assets/shaders/lightFragment.frag"); - Mesh lightMesh(vertices, indices); + Model ourModel("assets/models/sponza/Sponza.gltf"); + + shaderTest.Use(); + shaderTest.setInt("ourTexture", 0); + shaderTest.setInt("material.diffuse", 0); + shaderTest.setInt("material.specular", 1); + + // Set decals - TODO: Shift this to mesh.h with helpers + shaderTest.setDecal(0, 2, 1, glm::vec4(0.5, 0.5, 0, 0)); + shaderTest.setDecal(1, 2, 1, glm::vec4(0.5, 0.5, -0.75, -0.75)); + shaderTest.setInt("numberOfDecals", 2); + + shaderTest.setInt("numberOfPointLights", 1); + shaderTest.setInt("numberOfSpotLights", 1); + + glm::vec3 pointLightPositions[] = { + glm::vec3( 0.7f, 0.2f, 2.0f), + glm::vec3( 2.3f, -3.3f, -4.0f), + glm::vec3(-4.0f, 2.0f, -12.0f), + glm::vec3( 0.0f, 0.0f, -3.0f) + }; // Render Loop float lastUpdate = 0; - glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.0f); - glm::vec3 orbitCenter = glm::vec3(0.0f, 0.0f, 0.0f); while (!glfwWindowShouldClose(window)) { // per-frame time logic - // -------------------- float currentFrame = static_cast(glfwGetTime()); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // crappy fps printout if (currentFrame - lastUpdate >= 1.0) { - std::cout << 1.0f / deltaTime << std::endl; + // std::cout << 1.0f / deltaTime << std::endl; lastUpdate += 1.0f; } // Input processing processInput(window); - // Rendering - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture1.ID); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, texture2.ID); shaderTest.Use(); - shaderTest.setVec3("lightColor", 1.0f, 1.0f, 1.0f); - shaderTest.setVec3("lightPos", orbitCenter); - shaderTest.setVec3("viewPos", camera.position); - // pass projection matrix to shader (note that in this case it could change every frame) - glm::mat4 projection = glm::perspective(glm::radians(camera.zoom), (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 100.0f); - shaderTest.setMat4("projection", projection); + camera.Update(shaderTest, SCREEN_WIDTH, SCREEN_HEIGHT); - // camera/view transformation - glm::mat4 view = camera.GetViewMatrix(); - shaderTest.setMat4("view", view); + shaderTest.setFloat("material.shininess", 32.0f); + shaderTest.setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f); + shaderTest.setVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f); + shaderTest.setVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f); + shaderTest.setVec3("dirLight.specular", 0.8f, 0.8f, 0.8f); + +// ----------------------------------------------------------------------------- +// Ground Floor - Right Corridor (Warm Light) +// Placed halfway down the right hallway behind the arches +// ----------------------------------------------------------------------------- +shaderTest.setVec3("pointLights[0].position", -1.88f, 8.45f, -0.98f); +shaderTest.setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f); +shaderTest.setVec3("pointLights[0].diffuse", 1.0f, 0.7f, 0.4f); +shaderTest.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f); +shaderTest.setFloat("pointLights[0].constant", 1.0f); +shaderTest.setFloat("pointLights[0].linear", 0.09f); +shaderTest.setFloat("pointLights[0].quadratic", 0.032f); + +// ----------------------------------------------------------------------------- +// Ground Floor - Right Corridor, opposite end (Warm Light) +// ----------------------------------------------------------------------------- +shaderTest.setVec3("pointLights[1].position", -15.0f, 2.5f, 7.5f); +shaderTest.setVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f); +shaderTest.setVec3("pointLights[1].diffuse", 1.0f, 0.7f, 0.4f); +shaderTest.setVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f); +shaderTest.setFloat("pointLights[1].constant", 1.0f); +shaderTest.setFloat("pointLights[1].linear", 0.09f); +shaderTest.setFloat("pointLights[1].quadratic", 0.032f); + +// ----------------------------------------------------------------------------- +// Ground Floor - Left Corridor (Warm Light) +// Placed halfway down the left hallway behind the arches +// ----------------------------------------------------------------------------- +shaderTest.setVec3("pointLights[2].position", 15.0f, 2.5f, -7.5f); +shaderTest.setVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f); +shaderTest.setVec3("pointLights[2].diffuse", 1.0f, 0.7f, 0.4f); +shaderTest.setVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f); +shaderTest.setFloat("pointLights[2].constant", 1.0f); +shaderTest.setFloat("pointLights[2].linear", 0.09f); +shaderTest.setFloat("pointLights[2].quadratic", 0.032f); + +// ----------------------------------------------------------------------------- +// Ground Floor - Left Corridor, opposite end (Warm Light) +// ----------------------------------------------------------------------------- +shaderTest.setVec3("pointLights[3].position", -15.0f, 2.5f, -7.5f); +shaderTest.setVec3("pointLights[3].ambient", 0.05f, 0.05f, 0.05f); +shaderTest.setVec3("pointLights[3].diffuse", 1.0f, 0.7f, 0.4f); +shaderTest.setVec3("pointLights[3].specular", 1.0f, 1.0f, 1.0f); +shaderTest.setFloat("pointLights[3].constant", 1.0f); +shaderTest.setFloat("pointLights[3].linear", 0.09f); +shaderTest.setFloat("pointLights[3].quadratic", 0.032f); + +// ----------------------------------------------------------------------------- +// Upper Balcony - East Atrium Edge (Cool Light) +// Hovering above the balcony floor, shining into the main atrium +// ----------------------------------------------------------------------------- +shaderTest.setVec3("pointLights[4].position", 22.0f, 9.0f, 0.0f); +shaderTest.setVec3("pointLights[4].ambient", 0.05f, 0.05f, 0.05f); +shaderTest.setVec3("pointLights[4].diffuse", 0.7f, 0.8f, 1.0f); +shaderTest.setVec3("pointLights[4].specular", 1.0f, 1.0f, 1.0f); +shaderTest.setFloat("pointLights[4].constant", 1.0f); +shaderTest.setFloat("pointLights[4].linear", 0.09f); +shaderTest.setFloat("pointLights[4].quadratic", 0.032f); + +// ----------------------------------------------------------------------------- +// Upper Balcony - West Atrium Edge (Cool Light) +// Hovering above the balcony floor, shining into the main atrium +// ----------------------------------------------------------------------------- +shaderTest.setVec3("pointLights[5].position", -22.0f, 9.0f, 0.0f); +shaderTest.setVec3("pointLights[5].ambient", 0.05f, 0.05f, 0.05f); +shaderTest.setVec3("pointLights[5].diffuse", 0.7f, 0.8f, 1.0f); +shaderTest.setVec3("pointLights[5].specular", 1.0f, 1.0f, 1.0f); +shaderTest.setFloat("pointLights[5].constant", 1.0f); +shaderTest.setFloat("pointLights[5].linear", 0.09f); +shaderTest.setFloat("pointLights[5].quadratic", 0.032f); + + // spotLight1 + shaderTest.setBool("spotLights[0].disabled", flashlight); + shaderTest.setVec3("spotLights[0].position", camera.position); + shaderTest.setVec3("spotLights[0].direction", camera.front); + shaderTest.setVec3("spotLights[0].ambient", 0.0f, 0.0f, 0.0f); + shaderTest.setVec3("spotLights[0].diffuse", 1.0f, 1.0f, 1.0f); + shaderTest.setVec3("spotLights[0].specular", 1.0f, 1.0f, 1.0f); + shaderTest.setFloat("spotLights[0].constant", 1.0f); + shaderTest.setFloat("spotLights[0].linear", 0.09f); + shaderTest.setFloat("spotLights[0].quadratic", 0.032f); + shaderTest.setFloat("spotLights[0].cutOff", glm::cos(glm::radians(12.5f))); + shaderTest.setFloat("spotLights[0].outerCutOff", glm::cos(glm::radians(15.0f))); + // spotLight2 + shaderTest.setVec3("spotLights[1].position", -1.5441f, -0.294683f, 0.211498f); + shaderTest.setVec3("spotLights[1].direction", 1, 0, 0); + shaderTest.setVec3("spotLights[1].ambient", 0.0f, 0.0f, 0.0f); + shaderTest.setVec3("spotLights[1].diffuse", 1.0f, 1.0f, 1.0f); + shaderTest.setVec3("spotLights[1].specular", 1.0f, 1.0f, 1.0f); + shaderTest.setFloat("spotLights[1].constant", 1.0f); + shaderTest.setFloat("spotLights[1].linear", 0.09f); + shaderTest.setFloat("spotLights[1].quadratic", 0.032f); + shaderTest.setFloat("spotLights[1].cutOff", glm::cos(glm::radians(12.5f))); + shaderTest.setFloat("spotLights[1].outerCutOff", glm::cos(glm::radians(15.0f))); + + // render the loaded model glm::mat4 model = glm::mat4(1.0f); + model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); + model = glm::scale(model, glm::vec3(0.02f, 0.02f, 0.02f)); shaderTest.setMat4("model", model); + ourModel.Draw(shaderTest); - testMesh.Draw(); - - - lightingShader.Use(); - lightingShader.setMat4("projection", projection); - lightingShader.setMat4("view", view); - model = glm::mat4(1.0f); - - glm::vec3 offset = glm::vec3( - 2.0f * cos(glfwGetTime() * 1.0f), - 0.0f, - sin(glfwGetTime() * 1.0f) * 2.0f - ); - orbitCenter = lightPos + offset; - model = glm::translate(model, orbitCenter); - - model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube - lightingShader.setMat4("model", model); - - lightMesh.Draw(); + std::cout << "start" << std::endl; + std::cout << camera.position.x << std::endl; + std::cout << camera.position.y << std::endl; + std::cout << camera.position.z << std::endl; // Call events & swap buffers glfwSwapBuffers(window); @@ -227,6 +250,8 @@ int main(int argc, char* argv[]) void window_resize_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); + SCREEN_WIDTH = width; + SCREEN_HEIGHT = height; } void processInput(GLFWwindow* window) @@ -252,6 +277,15 @@ void processInput(GLFWwindow* window) if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_RELEASE) wireframeHeld = false; + // Flashlight toggle + if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS && !wireframeHeld) + { + wireframeHeld = true; + flashlight = !flashlight; + } + if (glfwGetKey(window, GLFW_KEY_F) == GLFW_RELEASE) + wireframeHeld = false; + // Camera if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera.processKeyboard(FORWARD, deltaTime); @@ -261,6 +295,8 @@ void processInput(GLFWwindow* window) camera.processKeyboard(LEFT, deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera.processKeyboard(RIGHT, deltaTime); + if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) + camera.processKeyboard(SPRINT, deltaTime); } diff --git a/vendor/glfw/glfw3.dll b/vendor/glfw/glfw3.dll deleted file mode 100644 index 86ab39a84bfb72be9c76c0962f107916f50bab59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 305664 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%0A}|42ij86TRC@@;p_oYzWPt> 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 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would - * be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - * - *************************************************************************/ - -#ifndef _glfw3_h_ -#define _glfw3_h_ - -#ifdef __cplusplus -extern "C" { -#endif - - -/************************************************************************* - * Doxygen documentation - *************************************************************************/ - -/*! @file glfw3.h - * @brief The header of the GLFW 3 API. - * - * This is the header file of the GLFW 3 API. It defines all its types and - * declares all its functions. - * - * For more information about how to use this file, see @ref build_include. - */ -/*! @defgroup context Context reference - * @brief Functions and types related to OpenGL and OpenGL ES contexts. - * - * This is the reference documentation for OpenGL and OpenGL ES context related - * functions. For more task-oriented information, see the @ref context_guide. - */ -/*! @defgroup vulkan Vulkan support reference - * @brief Functions and types related to Vulkan. - * - * This is the reference documentation for Vulkan related functions and types. - * For more task-oriented information, see the @ref vulkan_guide. - */ -/*! @defgroup init Initialization, version and error reference - * @brief Functions and types related to initialization and error handling. - * - * This is the reference documentation for initialization and termination of - * the library, version management and error handling. For more task-oriented - * information, see the @ref intro_guide. - */ -/*! @defgroup input Input reference - * @brief Functions and types related to input handling. - * - * This is the reference documentation for input related functions and types. - * For more task-oriented information, see the @ref input_guide. - */ -/*! @defgroup monitor Monitor reference - * @brief Functions and types related to monitors. - * - * This is the reference documentation for monitor related functions and types. - * For more task-oriented information, see the @ref monitor_guide. - */ -/*! @defgroup window Window reference - * @brief Functions and types related to windows. - * - * This is the reference documentation for window related functions and types, - * including creation, deletion and event polling. For more task-oriented - * information, see the @ref window_guide. - */ - - -/************************************************************************* - * Compiler- and platform-specific preprocessor work - *************************************************************************/ - -/* If we are we on Windows, we want a single define for it. - */ -#if !defined(_WIN32) && (defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__)) - #define _WIN32 -#endif /* _WIN32 */ - -/* Include because most Windows GLU headers need wchar_t and - * the macOS OpenGL header blocks the definition of ptrdiff_t by glext.h. - * Include it unconditionally to avoid surprising side-effects. - */ -#include - -/* Include because it is needed by Vulkan and related functions. - * Include it unconditionally to avoid surprising side-effects. - */ -#include - -#if defined(GLFW_INCLUDE_VULKAN) - #include -#endif /* Vulkan header */ - -/* The Vulkan header may have indirectly included windows.h (because of - * VK_USE_PLATFORM_WIN32_KHR) so we offer our replacement symbols after it. - */ - -/* It is customary to use APIENTRY for OpenGL function pointer declarations on - * all platforms. Additionally, the Windows OpenGL header needs APIENTRY. - */ -#if !defined(APIENTRY) - #if defined(_WIN32) - #define APIENTRY __stdcall - #else - #define APIENTRY - #endif - #define GLFW_APIENTRY_DEFINED -#endif /* APIENTRY */ - -/* Some Windows OpenGL headers need this. - */ -#if !defined(WINGDIAPI) && defined(_WIN32) - #define WINGDIAPI __declspec(dllimport) - #define GLFW_WINGDIAPI_DEFINED -#endif /* WINGDIAPI */ - -/* Some Windows GLU headers need this. - */ -#if !defined(CALLBACK) && defined(_WIN32) - #define CALLBACK __stdcall - #define GLFW_CALLBACK_DEFINED -#endif /* CALLBACK */ - -/* Include the chosen OpenGL or OpenGL ES headers. - */ -#if defined(GLFW_INCLUDE_ES1) - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - -#elif defined(GLFW_INCLUDE_ES2) - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - -#elif defined(GLFW_INCLUDE_ES3) - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - -#elif defined(GLFW_INCLUDE_ES31) - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - -#elif defined(GLFW_INCLUDE_ES32) - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - -#elif defined(GLFW_INCLUDE_GLCOREARB) - - #if defined(__APPLE__) - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif /*GLFW_INCLUDE_GLEXT*/ - - #else /*__APPLE__*/ - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - - #endif /*__APPLE__*/ - -#elif defined(GLFW_INCLUDE_GLU) - - #if defined(__APPLE__) - - #if defined(GLFW_INCLUDE_GLU) - #include - #endif - - #else /*__APPLE__*/ - - #if defined(GLFW_INCLUDE_GLU) - #include - #endif - - #endif /*__APPLE__*/ - -#elif !defined(GLFW_INCLUDE_NONE) && \ - !defined(__gl_h_) && \ - !defined(__gles1_gl_h_) && \ - !defined(__gles2_gl2_h_) && \ - !defined(__gles2_gl3_h_) && \ - !defined(__gles2_gl31_h_) && \ - !defined(__gles2_gl32_h_) && \ - !defined(__gl_glcorearb_h_) && \ - !defined(__gl2_h_) /*legacy*/ && \ - !defined(__gl3_h_) /*legacy*/ && \ - !defined(__gl31_h_) /*legacy*/ && \ - !defined(__gl32_h_) /*legacy*/ && \ - !defined(__glcorearb_h_) /*legacy*/ && \ - !defined(__GL_H__) /*non-standard*/ && \ - !defined(__gltypes_h_) /*non-standard*/ && \ - !defined(__glee_h_) /*non-standard*/ - - #if defined(__APPLE__) - - #if !defined(GLFW_INCLUDE_GLEXT) - #define GL_GLEXT_LEGACY - #endif - #include - - #else /*__APPLE__*/ - - #include - #if defined(GLFW_INCLUDE_GLEXT) - #include - #endif - - #endif /*__APPLE__*/ - -#endif /* OpenGL and OpenGL ES headers */ - -#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) - /* GLFW_DLL must be defined by applications that are linking against the DLL - * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW - * configuration header when compiling the DLL version of the library. - */ - #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" -#endif - -/* GLFWAPI is used to declare public API functions for export - * from the DLL / shared library / dynamic library. - */ -#if defined(_WIN32) && defined(_GLFW_BUILD_DLL) - /* We are building GLFW as a Win32 DLL */ - #define GLFWAPI __declspec(dllexport) -#elif defined(_WIN32) && defined(GLFW_DLL) - /* We are calling a GLFW Win32 DLL */ - #define GLFWAPI __declspec(dllimport) -#elif defined(__GNUC__) && defined(_GLFW_BUILD_DLL) - /* We are building GLFW as a Unix shared library */ - #define GLFWAPI __attribute__((visibility("default"))) -#else - #define GLFWAPI -#endif - - -/************************************************************************* - * GLFW API tokens - *************************************************************************/ - -/*! @name GLFW version macros - * @{ */ -/*! @brief The major version number of the GLFW header. - * - * The major version number of the GLFW header. This is incremented when the - * API is changed in non-compatible ways. - * @ingroup init - */ -#define GLFW_VERSION_MAJOR 3 -/*! @brief The minor version number of the GLFW header. - * - * The minor version number of the GLFW header. This is incremented when - * features are added to the API but it remains backward-compatible. - * @ingroup init - */ -#define GLFW_VERSION_MINOR 4 -/*! @brief The revision number of the GLFW header. - * - * The revision number of the GLFW header. This is incremented when a bug fix - * release is made that does not contain any API changes. - * @ingroup init - */ -#define GLFW_VERSION_REVISION 0 -/*! @} */ - -/*! @brief One. - * - * This is only semantic sugar for the number 1. You can instead use `1` or - * `true` or `_True` or `GL_TRUE` or `VK_TRUE` or anything else that is equal - * to one. - * - * @ingroup init - */ -#define GLFW_TRUE 1 -/*! @brief Zero. - * - * This is only semantic sugar for the number 0. You can instead use `0` or - * `false` or `_False` or `GL_FALSE` or `VK_FALSE` or anything else that is - * equal to zero. - * - * @ingroup init - */ -#define GLFW_FALSE 0 - -/*! @name Key and button actions - * @{ */ -/*! @brief The key or mouse button was released. - * - * The key or mouse button was released. - * - * @ingroup input - */ -#define GLFW_RELEASE 0 -/*! @brief The key or mouse button was pressed. - * - * The key or mouse button was pressed. - * - * @ingroup input - */ -#define GLFW_PRESS 1 -/*! @brief The key was held down until it repeated. - * - * The key was held down until it repeated. - * - * @ingroup input - */ -#define GLFW_REPEAT 2 -/*! @} */ - -/*! @defgroup hat_state Joystick hat states - * @brief Joystick hat states. - * - * See [joystick hat input](@ref joystick_hat) for how these are used. - * - * @ingroup input - * @{ */ -#define GLFW_HAT_CENTERED 0 -#define GLFW_HAT_UP 1 -#define GLFW_HAT_RIGHT 2 -#define GLFW_HAT_DOWN 4 -#define GLFW_HAT_LEFT 8 -#define GLFW_HAT_RIGHT_UP (GLFW_HAT_RIGHT | GLFW_HAT_UP) -#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN) -#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP) -#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN) - -/*! @ingroup input - */ -#define GLFW_KEY_UNKNOWN -1 - -/*! @} */ - -/*! @defgroup keys Keyboard key tokens - * @brief Keyboard key tokens. - * - * See [key input](@ref input_key) for how these are used. - * - * These key codes are inspired by the _USB HID Usage Tables v1.12_ (p. 53-60), - * but re-arranged to map to 7-bit ASCII for printable keys (function keys are - * put in the 256+ range). - * - * The naming of the key codes follow these rules: - * - The US keyboard layout is used - * - Names of printable alphanumeric characters are used (e.g. "A", "R", - * "3", etc.) - * - For non-alphanumeric characters, Unicode:ish names are used (e.g. - * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not - * correspond to the Unicode standard (usually for brevity) - * - Keys that lack a clear US mapping are named "WORLD_x" - * - For non-printable keys, custom names are used (e.g. "F4", - * "BACKSPACE", etc.) - * - * @ingroup input - * @{ - */ - -/* Printable keys */ -#define GLFW_KEY_SPACE 32 -#define GLFW_KEY_APOSTROPHE 39 /* ' */ -#define GLFW_KEY_COMMA 44 /* , */ -#define GLFW_KEY_MINUS 45 /* - */ -#define GLFW_KEY_PERIOD 46 /* . */ -#define GLFW_KEY_SLASH 47 /* / */ -#define GLFW_KEY_0 48 -#define GLFW_KEY_1 49 -#define GLFW_KEY_2 50 -#define GLFW_KEY_3 51 -#define GLFW_KEY_4 52 -#define GLFW_KEY_5 53 -#define GLFW_KEY_6 54 -#define GLFW_KEY_7 55 -#define GLFW_KEY_8 56 -#define GLFW_KEY_9 57 -#define GLFW_KEY_SEMICOLON 59 /* ; */ -#define GLFW_KEY_EQUAL 61 /* = */ -#define GLFW_KEY_A 65 -#define GLFW_KEY_B 66 -#define GLFW_KEY_C 67 -#define GLFW_KEY_D 68 -#define GLFW_KEY_E 69 -#define GLFW_KEY_F 70 -#define GLFW_KEY_G 71 -#define GLFW_KEY_H 72 -#define GLFW_KEY_I 73 -#define GLFW_KEY_J 74 -#define GLFW_KEY_K 75 -#define GLFW_KEY_L 76 -#define GLFW_KEY_M 77 -#define GLFW_KEY_N 78 -#define GLFW_KEY_O 79 -#define GLFW_KEY_P 80 -#define GLFW_KEY_Q 81 -#define GLFW_KEY_R 82 -#define GLFW_KEY_S 83 -#define GLFW_KEY_T 84 -#define GLFW_KEY_U 85 -#define GLFW_KEY_V 86 -#define GLFW_KEY_W 87 -#define GLFW_KEY_X 88 -#define GLFW_KEY_Y 89 -#define GLFW_KEY_Z 90 -#define GLFW_KEY_LEFT_BRACKET 91 /* [ */ -#define GLFW_KEY_BACKSLASH 92 /* \ */ -#define GLFW_KEY_RIGHT_BRACKET 93 /* ] */ -#define GLFW_KEY_GRAVE_ACCENT 96 /* ` */ -#define GLFW_KEY_WORLD_1 161 /* non-US #1 */ -#define GLFW_KEY_WORLD_2 162 /* non-US #2 */ - -/* Function keys */ -#define GLFW_KEY_ESCAPE 256 -#define GLFW_KEY_ENTER 257 -#define GLFW_KEY_TAB 258 -#define GLFW_KEY_BACKSPACE 259 -#define GLFW_KEY_INSERT 260 -#define GLFW_KEY_DELETE 261 -#define GLFW_KEY_RIGHT 262 -#define GLFW_KEY_LEFT 263 -#define GLFW_KEY_DOWN 264 -#define GLFW_KEY_UP 265 -#define GLFW_KEY_PAGE_UP 266 -#define GLFW_KEY_PAGE_DOWN 267 -#define GLFW_KEY_HOME 268 -#define GLFW_KEY_END 269 -#define GLFW_KEY_CAPS_LOCK 280 -#define GLFW_KEY_SCROLL_LOCK 281 -#define GLFW_KEY_NUM_LOCK 282 -#define GLFW_KEY_PRINT_SCREEN 283 -#define GLFW_KEY_PAUSE 284 -#define GLFW_KEY_F1 290 -#define GLFW_KEY_F2 291 -#define GLFW_KEY_F3 292 -#define GLFW_KEY_F4 293 -#define GLFW_KEY_F5 294 -#define GLFW_KEY_F6 295 -#define GLFW_KEY_F7 296 -#define GLFW_KEY_F8 297 -#define GLFW_KEY_F9 298 -#define GLFW_KEY_F10 299 -#define GLFW_KEY_F11 300 -#define GLFW_KEY_F12 301 -#define GLFW_KEY_F13 302 -#define GLFW_KEY_F14 303 -#define GLFW_KEY_F15 304 -#define GLFW_KEY_F16 305 -#define GLFW_KEY_F17 306 -#define GLFW_KEY_F18 307 -#define GLFW_KEY_F19 308 -#define GLFW_KEY_F20 309 -#define GLFW_KEY_F21 310 -#define GLFW_KEY_F22 311 -#define GLFW_KEY_F23 312 -#define GLFW_KEY_F24 313 -#define GLFW_KEY_F25 314 -#define GLFW_KEY_KP_0 320 -#define GLFW_KEY_KP_1 321 -#define GLFW_KEY_KP_2 322 -#define GLFW_KEY_KP_3 323 -#define GLFW_KEY_KP_4 324 -#define GLFW_KEY_KP_5 325 -#define GLFW_KEY_KP_6 326 -#define GLFW_KEY_KP_7 327 -#define GLFW_KEY_KP_8 328 -#define GLFW_KEY_KP_9 329 -#define GLFW_KEY_KP_DECIMAL 330 -#define GLFW_KEY_KP_DIVIDE 331 -#define GLFW_KEY_KP_MULTIPLY 332 -#define GLFW_KEY_KP_SUBTRACT 333 -#define GLFW_KEY_KP_ADD 334 -#define GLFW_KEY_KP_ENTER 335 -#define GLFW_KEY_KP_EQUAL 336 -#define GLFW_KEY_LEFT_SHIFT 340 -#define GLFW_KEY_LEFT_CONTROL 341 -#define GLFW_KEY_LEFT_ALT 342 -#define GLFW_KEY_LEFT_SUPER 343 -#define GLFW_KEY_RIGHT_SHIFT 344 -#define GLFW_KEY_RIGHT_CONTROL 345 -#define GLFW_KEY_RIGHT_ALT 346 -#define GLFW_KEY_RIGHT_SUPER 347 -#define GLFW_KEY_MENU 348 - -#define GLFW_KEY_LAST GLFW_KEY_MENU - -/*! @} */ - -/*! @defgroup mods Modifier key flags - * @brief Modifier key flags. - * - * See [key input](@ref input_key) for how these are used. - * - * @ingroup input - * @{ */ - -/*! @brief If this bit is set one or more Shift keys were held down. - * - * If this bit is set one or more Shift keys were held down. - */ -#define GLFW_MOD_SHIFT 0x0001 -/*! @brief If this bit is set one or more Control keys were held down. - * - * If this bit is set one or more Control keys were held down. - */ -#define GLFW_MOD_CONTROL 0x0002 -/*! @brief If this bit is set one or more Alt keys were held down. - * - * If this bit is set one or more Alt keys were held down. - */ -#define GLFW_MOD_ALT 0x0004 -/*! @brief If this bit is set one or more Super keys were held down. - * - * If this bit is set one or more Super keys were held down. - */ -#define GLFW_MOD_SUPER 0x0008 -/*! @brief If this bit is set the Caps Lock key is enabled. - * - * If this bit is set the Caps Lock key is enabled and the @ref - * GLFW_LOCK_KEY_MODS input mode is set. - */ -#define GLFW_MOD_CAPS_LOCK 0x0010 -/*! @brief If this bit is set the Num Lock key is enabled. - * - * If this bit is set the Num Lock key is enabled and the @ref - * GLFW_LOCK_KEY_MODS input mode is set. - */ -#define GLFW_MOD_NUM_LOCK 0x0020 - -/*! @} */ - -/*! @defgroup buttons Mouse buttons - * @brief Mouse button IDs. - * - * See [mouse button input](@ref input_mouse_button) for how these are used. - * - * @ingroup input - * @{ */ -#define GLFW_MOUSE_BUTTON_1 0 -#define GLFW_MOUSE_BUTTON_2 1 -#define GLFW_MOUSE_BUTTON_3 2 -#define GLFW_MOUSE_BUTTON_4 3 -#define GLFW_MOUSE_BUTTON_5 4 -#define GLFW_MOUSE_BUTTON_6 5 -#define GLFW_MOUSE_BUTTON_7 6 -#define GLFW_MOUSE_BUTTON_8 7 -#define GLFW_MOUSE_BUTTON_LAST GLFW_MOUSE_BUTTON_8 -#define GLFW_MOUSE_BUTTON_LEFT GLFW_MOUSE_BUTTON_1 -#define GLFW_MOUSE_BUTTON_RIGHT GLFW_MOUSE_BUTTON_2 -#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3 -/*! @} */ - -/*! @defgroup joysticks Joysticks - * @brief Joystick IDs. - * - * See [joystick input](@ref joystick) for how these are used. - * - * @ingroup input - * @{ */ -#define GLFW_JOYSTICK_1 0 -#define GLFW_JOYSTICK_2 1 -#define GLFW_JOYSTICK_3 2 -#define GLFW_JOYSTICK_4 3 -#define GLFW_JOYSTICK_5 4 -#define GLFW_JOYSTICK_6 5 -#define GLFW_JOYSTICK_7 6 -#define GLFW_JOYSTICK_8 7 -#define GLFW_JOYSTICK_9 8 -#define GLFW_JOYSTICK_10 9 -#define GLFW_JOYSTICK_11 10 -#define GLFW_JOYSTICK_12 11 -#define GLFW_JOYSTICK_13 12 -#define GLFW_JOYSTICK_14 13 -#define GLFW_JOYSTICK_15 14 -#define GLFW_JOYSTICK_16 15 -#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16 -/*! @} */ - -/*! @defgroup gamepad_buttons Gamepad buttons - * @brief Gamepad buttons. - * - * See @ref gamepad for how these are used. - * - * @ingroup input - * @{ */ -#define GLFW_GAMEPAD_BUTTON_A 0 -#define GLFW_GAMEPAD_BUTTON_B 1 -#define GLFW_GAMEPAD_BUTTON_X 2 -#define GLFW_GAMEPAD_BUTTON_Y 3 -#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4 -#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5 -#define GLFW_GAMEPAD_BUTTON_BACK 6 -#define GLFW_GAMEPAD_BUTTON_START 7 -#define GLFW_GAMEPAD_BUTTON_GUIDE 8 -#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9 -#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10 -#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11 -#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12 -#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13 -#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14 -#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT - -#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A -#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B -#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X -#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y -/*! @} */ - -/*! @defgroup gamepad_axes Gamepad axes - * @brief Gamepad axes. - * - * See @ref gamepad for how these are used. - * - * @ingroup input - * @{ */ -#define GLFW_GAMEPAD_AXIS_LEFT_X 0 -#define GLFW_GAMEPAD_AXIS_LEFT_Y 1 -#define GLFW_GAMEPAD_AXIS_RIGHT_X 2 -#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3 -#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4 -#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5 -#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER -/*! @} */ - -/*! @defgroup errors Error codes - * @brief Error codes. - * - * See [error handling](@ref error_handling) for how these are used. - * - * @ingroup init - * @{ */ -/*! @brief No error has occurred. - * - * No error has occurred. - * - * @analysis Yay. - */ -#define GLFW_NO_ERROR 0 -/*! @brief GLFW has not been initialized. - * - * This occurs if a GLFW function was called that must not be called unless the - * library is [initialized](@ref intro_init). - * - * @analysis Application programmer error. Initialize GLFW before calling any - * function that requires initialization. - */ -#define GLFW_NOT_INITIALIZED 0x00010001 -/*! @brief No context is current for this thread. - * - * This occurs if a GLFW function was called that needs and operates on the - * current OpenGL or OpenGL ES context but no context is current on the calling - * thread. One such function is @ref glfwSwapInterval. - * - * @analysis Application programmer error. Ensure a context is current before - * calling functions that require a current context. - */ -#define GLFW_NO_CURRENT_CONTEXT 0x00010002 -/*! @brief One of the arguments to the function was an invalid enum value. - * - * One of the arguments to the function was an invalid enum value, for example - * requesting @ref GLFW_RED_BITS with @ref glfwGetWindowAttrib. - * - * @analysis Application programmer error. Fix the offending call. - */ -#define GLFW_INVALID_ENUM 0x00010003 -/*! @brief One of the arguments to the function was an invalid value. - * - * One of the arguments to the function was an invalid value, for example - * requesting a non-existent OpenGL or OpenGL ES version like 2.7. - * - * Requesting a valid but unavailable OpenGL or OpenGL ES version will instead - * result in a @ref GLFW_VERSION_UNAVAILABLE error. - * - * @analysis Application programmer error. Fix the offending call. - */ -#define GLFW_INVALID_VALUE 0x00010004 -/*! @brief A memory allocation failed. - * - * A memory allocation failed. - * - * @analysis A bug in GLFW or the underlying operating system. Report the bug - * to our [issue tracker](https://github.com/glfw/glfw/issues). - */ -#define GLFW_OUT_OF_MEMORY 0x00010005 -/*! @brief GLFW could not find support for the requested API on the system. - * - * GLFW could not find support for the requested API on the system. - * - * @analysis The installed graphics driver does not support the requested - * API, or does not support it via the chosen context creation API. - * Below are a few examples. - * - * @par - * Some pre-installed Windows graphics drivers do not support OpenGL. AMD only - * supports OpenGL ES via EGL, while Nvidia and Intel only support it via - * a WGL or GLX extension. macOS does not provide OpenGL ES at all. The Mesa - * EGL, OpenGL and OpenGL ES libraries do not interface with the Nvidia binary - * driver. Older graphics drivers do not support Vulkan. - */ -#define GLFW_API_UNAVAILABLE 0x00010006 -/*! @brief The requested OpenGL or OpenGL ES version is not available. - * - * The requested OpenGL or OpenGL ES version (including any requested context - * or framebuffer hints) is not available on this machine. - * - * @analysis The machine does not support your requirements. If your - * application is sufficiently flexible, downgrade your requirements and try - * again. Otherwise, inform the user that their machine does not match your - * requirements. - * - * @par - * Future invalid OpenGL and OpenGL ES versions, for example OpenGL 4.8 if 5.0 - * comes out before the 4.x series gets that far, also fail with this error and - * not @ref GLFW_INVALID_VALUE, because GLFW cannot know what future versions - * will exist. - */ -#define GLFW_VERSION_UNAVAILABLE 0x00010007 -/*! @brief A platform-specific error occurred that does not match any of the - * more specific categories. - * - * A platform-specific error occurred that does not match any of the more - * specific categories. - * - * @analysis A bug or configuration error in GLFW, the underlying operating - * system or its drivers, or a lack of required resources. Report the issue to - * our [issue tracker](https://github.com/glfw/glfw/issues). - */ -#define GLFW_PLATFORM_ERROR 0x00010008 -/*! @brief The requested format is not supported or available. - * - * If emitted during window creation, the requested pixel format is not - * supported. - * - * If emitted when querying the clipboard, the contents of the clipboard could - * not be converted to the requested format. - * - * @analysis If emitted during window creation, one or more - * [hard constraints](@ref window_hints_hard) did not match any of the - * available pixel formats. If your application is sufficiently flexible, - * downgrade your requirements and try again. Otherwise, inform the user that - * their machine does not match your requirements. - * - * @par - * If emitted when querying the clipboard, ignore the error or report it to - * the user, as appropriate. - */ -#define GLFW_FORMAT_UNAVAILABLE 0x00010009 -/*! @brief The specified window does not have an OpenGL or OpenGL ES context. - * - * A window that does not have an OpenGL or OpenGL ES context was passed to - * a function that requires it to have one. - * - * @analysis Application programmer error. Fix the offending call. - */ -#define GLFW_NO_WINDOW_CONTEXT 0x0001000A -/*! @brief The specified cursor shape is not available. - * - * The specified standard cursor shape is not available, either because the - * current platform cursor theme does not provide it or because it is not - * available on the platform. - * - * @analysis Platform or system settings limitation. Pick another - * [standard cursor shape](@ref shapes) or create a - * [custom cursor](@ref cursor_custom). - */ -#define GLFW_CURSOR_UNAVAILABLE 0x0001000B -/*! @brief The requested feature is not provided by the platform. - * - * The requested feature is not provided by the platform, so GLFW is unable to - * implement it. The documentation for each function notes if it could emit - * this error. - * - * @analysis Platform or platform version limitation. The error can be ignored - * unless the feature is critical to the application. - * - * @par - * A function call that emits this error has no effect other than the error and - * updating any existing out parameters. - */ -#define GLFW_FEATURE_UNAVAILABLE 0x0001000C -/*! @brief The requested feature is not implemented for the platform. - * - * The requested feature has not yet been implemented in GLFW for this platform. - * - * @analysis An incomplete implementation of GLFW for this platform, hopefully - * fixed in a future release. The error can be ignored unless the feature is - * critical to the application. - * - * @par - * A function call that emits this error has no effect other than the error and - * updating any existing out parameters. - */ -#define GLFW_FEATURE_UNIMPLEMENTED 0x0001000D -/*! @brief Platform unavailable or no matching platform was found. - * - * If emitted during initialization, no matching platform was found. If the @ref - * GLFW_PLATFORM init hint was set to `GLFW_ANY_PLATFORM`, GLFW could not detect any of - * the platforms supported by this library binary, except for the Null platform. If the - * init hint was set to a specific platform, it is either not supported by this library - * binary or GLFW was not able to detect it. - * - * If emitted by a native access function, GLFW was initialized for a different platform - * than the function is for. - * - * @analysis Failure to detect any platform usually only happens on non-macOS Unix - * systems, either when no window system is running or the program was run from - * a terminal that does not have the necessary environment variables. Fall back to - * a different platform if possible or notify the user that no usable platform was - * detected. - * - * Failure to detect a specific platform may have the same cause as above or be because - * support for that platform was not compiled in. Call @ref glfwPlatformSupported to - * check whether a specific platform is supported by a library binary. - */ -#define GLFW_PLATFORM_UNAVAILABLE 0x0001000E -/*! @} */ - -/*! @addtogroup window - * @{ */ -/*! @brief Input focus window hint and attribute - * - * Input focus [window hint](@ref GLFW_FOCUSED_hint) or - * [window attribute](@ref GLFW_FOCUSED_attrib). - */ -#define GLFW_FOCUSED 0x00020001 -/*! @brief Window iconification window attribute - * - * Window iconification [window attribute](@ref GLFW_ICONIFIED_attrib). - */ -#define GLFW_ICONIFIED 0x00020002 -/*! @brief Window resize-ability window hint and attribute - * - * Window resize-ability [window hint](@ref GLFW_RESIZABLE_hint) and - * [window attribute](@ref GLFW_RESIZABLE_attrib). - */ -#define GLFW_RESIZABLE 0x00020003 -/*! @brief Window visibility window hint and attribute - * - * Window visibility [window hint](@ref GLFW_VISIBLE_hint) and - * [window attribute](@ref GLFW_VISIBLE_attrib). - */ -#define GLFW_VISIBLE 0x00020004 -/*! @brief Window decoration window hint and attribute - * - * Window decoration [window hint](@ref GLFW_DECORATED_hint) and - * [window attribute](@ref GLFW_DECORATED_attrib). - */ -#define GLFW_DECORATED 0x00020005 -/*! @brief Window auto-iconification window hint and attribute - * - * Window auto-iconification [window hint](@ref GLFW_AUTO_ICONIFY_hint) and - * [window attribute](@ref GLFW_AUTO_ICONIFY_attrib). - */ -#define GLFW_AUTO_ICONIFY 0x00020006 -/*! @brief Window decoration window hint and attribute - * - * Window decoration [window hint](@ref GLFW_FLOATING_hint) and - * [window attribute](@ref GLFW_FLOATING_attrib). - */ -#define GLFW_FLOATING 0x00020007 -/*! @brief Window maximization window hint and attribute - * - * Window maximization [window hint](@ref GLFW_MAXIMIZED_hint) and - * [window attribute](@ref GLFW_MAXIMIZED_attrib). - */ -#define GLFW_MAXIMIZED 0x00020008 -/*! @brief Cursor centering window hint - * - * Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint). - */ -#define GLFW_CENTER_CURSOR 0x00020009 -/*! @brief Window framebuffer transparency hint and attribute - * - * Window framebuffer transparency - * [window hint](@ref GLFW_TRANSPARENT_FRAMEBUFFER_hint) and - * [window attribute](@ref GLFW_TRANSPARENT_FRAMEBUFFER_attrib). - */ -#define GLFW_TRANSPARENT_FRAMEBUFFER 0x0002000A -/*! @brief Mouse cursor hover window attribute. - * - * Mouse cursor hover [window attribute](@ref GLFW_HOVERED_attrib). - */ -#define GLFW_HOVERED 0x0002000B -/*! @brief Input focus on calling show window hint and attribute - * - * Input focus [window hint](@ref GLFW_FOCUS_ON_SHOW_hint) or - * [window attribute](@ref GLFW_FOCUS_ON_SHOW_attrib). - */ -#define GLFW_FOCUS_ON_SHOW 0x0002000C - -/*! @brief Mouse input transparency window hint and attribute - * - * Mouse input transparency [window hint](@ref GLFW_MOUSE_PASSTHROUGH_hint) or - * [window attribute](@ref GLFW_MOUSE_PASSTHROUGH_attrib). - */ -#define GLFW_MOUSE_PASSTHROUGH 0x0002000D - -/*! @brief Initial position x-coordinate window hint. - * - * Initial position x-coordinate [window hint](@ref GLFW_POSITION_X). - */ -#define GLFW_POSITION_X 0x0002000E - -/*! @brief Initial position y-coordinate window hint. - * - * Initial position y-coordinate [window hint](@ref GLFW_POSITION_Y). - */ -#define GLFW_POSITION_Y 0x0002000F - -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_RED_BITS). - */ -#define GLFW_RED_BITS 0x00021001 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_GREEN_BITS). - */ -#define GLFW_GREEN_BITS 0x00021002 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_BLUE_BITS). - */ -#define GLFW_BLUE_BITS 0x00021003 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_ALPHA_BITS). - */ -#define GLFW_ALPHA_BITS 0x00021004 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_DEPTH_BITS). - */ -#define GLFW_DEPTH_BITS 0x00021005 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_STENCIL_BITS). - */ -#define GLFW_STENCIL_BITS 0x00021006 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_ACCUM_RED_BITS). - */ -#define GLFW_ACCUM_RED_BITS 0x00021007 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_ACCUM_GREEN_BITS). - */ -#define GLFW_ACCUM_GREEN_BITS 0x00021008 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_ACCUM_BLUE_BITS). - */ -#define GLFW_ACCUM_BLUE_BITS 0x00021009 -/*! @brief Framebuffer bit depth hint. - * - * Framebuffer bit depth [hint](@ref GLFW_ACCUM_ALPHA_BITS). - */ -#define GLFW_ACCUM_ALPHA_BITS 0x0002100A -/*! @brief Framebuffer auxiliary buffer hint. - * - * Framebuffer auxiliary buffer [hint](@ref GLFW_AUX_BUFFERS). - */ -#define GLFW_AUX_BUFFERS 0x0002100B -/*! @brief OpenGL stereoscopic rendering hint. - * - * OpenGL stereoscopic rendering [hint](@ref GLFW_STEREO). - */ -#define GLFW_STEREO 0x0002100C -/*! @brief Framebuffer MSAA samples hint. - * - * Framebuffer MSAA samples [hint](@ref GLFW_SAMPLES). - */ -#define GLFW_SAMPLES 0x0002100D -/*! @brief Framebuffer sRGB hint. - * - * Framebuffer sRGB [hint](@ref GLFW_SRGB_CAPABLE). - */ -#define GLFW_SRGB_CAPABLE 0x0002100E -/*! @brief Monitor refresh rate hint. - * - * Monitor refresh rate [hint](@ref GLFW_REFRESH_RATE). - */ -#define GLFW_REFRESH_RATE 0x0002100F -/*! @brief Framebuffer double buffering hint and attribute. - * - * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER_hint) and - * [attribute](@ref GLFW_DOUBLEBUFFER_attrib). - */ -#define GLFW_DOUBLEBUFFER 0x00021010 - -/*! @brief Context client API hint and attribute. - * - * Context client API [hint](@ref GLFW_CLIENT_API_hint) and - * [attribute](@ref GLFW_CLIENT_API_attrib). - */ -#define GLFW_CLIENT_API 0x00022001 -/*! @brief Context client API major version hint and attribute. - * - * Context client API major version [hint](@ref GLFW_CONTEXT_VERSION_MAJOR_hint) - * and [attribute](@ref GLFW_CONTEXT_VERSION_MAJOR_attrib). - */ -#define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 -/*! @brief Context client API minor version hint and attribute. - * - * Context client API minor version [hint](@ref GLFW_CONTEXT_VERSION_MINOR_hint) - * and [attribute](@ref GLFW_CONTEXT_VERSION_MINOR_attrib). - */ -#define GLFW_CONTEXT_VERSION_MINOR 0x00022003 -/*! @brief Context client API revision number attribute. - * - * Context client API revision number - * [attribute](@ref GLFW_CONTEXT_REVISION_attrib). - */ -#define GLFW_CONTEXT_REVISION 0x00022004 -/*! @brief Context robustness hint and attribute. - * - * Context client API revision number [hint](@ref GLFW_CONTEXT_ROBUSTNESS_hint) - * and [attribute](@ref GLFW_CONTEXT_ROBUSTNESS_attrib). - */ -#define GLFW_CONTEXT_ROBUSTNESS 0x00022005 -/*! @brief OpenGL forward-compatibility hint and attribute. - * - * OpenGL forward-compatibility [hint](@ref GLFW_OPENGL_FORWARD_COMPAT_hint) - * and [attribute](@ref GLFW_OPENGL_FORWARD_COMPAT_attrib). - */ -#define GLFW_OPENGL_FORWARD_COMPAT 0x00022006 -/*! @brief Debug mode context hint and attribute. - * - * Debug mode context [hint](@ref GLFW_CONTEXT_DEBUG_hint) and - * [attribute](@ref GLFW_CONTEXT_DEBUG_attrib). - */ -#define GLFW_CONTEXT_DEBUG 0x00022007 -/*! @brief Legacy name for compatibility. - * - * This is an alias for compatibility with earlier versions. - */ -#define GLFW_OPENGL_DEBUG_CONTEXT GLFW_CONTEXT_DEBUG -/*! @brief OpenGL profile hint and attribute. - * - * OpenGL profile [hint](@ref GLFW_OPENGL_PROFILE_hint) and - * [attribute](@ref GLFW_OPENGL_PROFILE_attrib). - */ -#define GLFW_OPENGL_PROFILE 0x00022008 -/*! @brief Context flush-on-release hint and attribute. - * - * Context flush-on-release [hint](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) and - * [attribute](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_attrib). - */ -#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009 -/*! @brief Context error suppression hint and attribute. - * - * Context error suppression [hint](@ref GLFW_CONTEXT_NO_ERROR_hint) and - * [attribute](@ref GLFW_CONTEXT_NO_ERROR_attrib). - */ -#define GLFW_CONTEXT_NO_ERROR 0x0002200A -/*! @brief Context creation API hint and attribute. - * - * Context creation API [hint](@ref GLFW_CONTEXT_CREATION_API_hint) and - * [attribute](@ref GLFW_CONTEXT_CREATION_API_attrib). - */ -#define GLFW_CONTEXT_CREATION_API 0x0002200B -/*! @brief Window content area scaling window - * [window hint](@ref GLFW_SCALE_TO_MONITOR). - */ -#define GLFW_SCALE_TO_MONITOR 0x0002200C -/*! @brief Window framebuffer scaling - * [window hint](@ref GLFW_SCALE_FRAMEBUFFER_hint). - */ -#define GLFW_SCALE_FRAMEBUFFER 0x0002200D -/*! @brief Legacy name for compatibility. - * - * This is an alias for the - * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) window hint for - * compatibility with earlier versions. - */ -#define GLFW_COCOA_RETINA_FRAMEBUFFER 0x00023001 -/*! @brief macOS specific - * [window hint](@ref GLFW_COCOA_FRAME_NAME_hint). - */ -#define GLFW_COCOA_FRAME_NAME 0x00023002 -/*! @brief macOS specific - * [window hint](@ref GLFW_COCOA_GRAPHICS_SWITCHING_hint). - */ -#define GLFW_COCOA_GRAPHICS_SWITCHING 0x00023003 -/*! @brief X11 specific - * [window hint](@ref GLFW_X11_CLASS_NAME_hint). - */ -#define GLFW_X11_CLASS_NAME 0x00024001 -/*! @brief X11 specific - * [window hint](@ref GLFW_X11_CLASS_NAME_hint). - */ -#define GLFW_X11_INSTANCE_NAME 0x00024002 -#define GLFW_WIN32_KEYBOARD_MENU 0x00025001 -/*! @brief Win32 specific [window hint](@ref GLFW_WIN32_SHOWDEFAULT_hint). - */ -#define GLFW_WIN32_SHOWDEFAULT 0x00025002 -/*! @brief Wayland specific - * [window hint](@ref GLFW_WAYLAND_APP_ID_hint). - * - * Allows specification of the Wayland app_id. - */ -#define GLFW_WAYLAND_APP_ID 0x00026001 -/*! @} */ - -#define GLFW_NO_API 0 -#define GLFW_OPENGL_API 0x00030001 -#define GLFW_OPENGL_ES_API 0x00030002 - -#define GLFW_NO_ROBUSTNESS 0 -#define GLFW_NO_RESET_NOTIFICATION 0x00031001 -#define GLFW_LOSE_CONTEXT_ON_RESET 0x00031002 - -#define GLFW_OPENGL_ANY_PROFILE 0 -#define GLFW_OPENGL_CORE_PROFILE 0x00032001 -#define GLFW_OPENGL_COMPAT_PROFILE 0x00032002 - -#define GLFW_CURSOR 0x00033001 -#define GLFW_STICKY_KEYS 0x00033002 -#define GLFW_STICKY_MOUSE_BUTTONS 0x00033003 -#define GLFW_LOCK_KEY_MODS 0x00033004 -#define GLFW_RAW_MOUSE_MOTION 0x00033005 - -#define GLFW_CURSOR_NORMAL 0x00034001 -#define GLFW_CURSOR_HIDDEN 0x00034002 -#define GLFW_CURSOR_DISABLED 0x00034003 -#define GLFW_CURSOR_CAPTURED 0x00034004 - -#define GLFW_ANY_RELEASE_BEHAVIOR 0 -#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001 -#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002 - -#define GLFW_NATIVE_CONTEXT_API 0x00036001 -#define GLFW_EGL_CONTEXT_API 0x00036002 -#define GLFW_OSMESA_CONTEXT_API 0x00036003 - -#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001 -#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002 -#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003 -#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004 -#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005 -#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 -#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 - -#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001 -#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002 - -#define GLFW_ANY_POSITION 0x80000000 - -/*! @defgroup shapes Standard cursor shapes - * @brief Standard system cursor shapes. - * - * These are the [standard cursor shapes](@ref cursor_standard) that can be - * requested from the platform (window system). - * - * @ingroup input - * @{ */ - -/*! @brief The regular arrow cursor shape. - * - * The regular arrow cursor shape. - */ -#define GLFW_ARROW_CURSOR 0x00036001 -/*! @brief The text input I-beam cursor shape. - * - * The text input I-beam cursor shape. - */ -#define GLFW_IBEAM_CURSOR 0x00036002 -/*! @brief The crosshair cursor shape. - * - * The crosshair cursor shape. - */ -#define GLFW_CROSSHAIR_CURSOR 0x00036003 -/*! @brief The pointing hand cursor shape. - * - * The pointing hand cursor shape. - */ -#define GLFW_POINTING_HAND_CURSOR 0x00036004 -/*! @brief The horizontal resize/move arrow shape. - * - * The horizontal resize/move arrow shape. This is usually a horizontal - * double-headed arrow. - */ -#define GLFW_RESIZE_EW_CURSOR 0x00036005 -/*! @brief The vertical resize/move arrow shape. - * - * The vertical resize/move shape. This is usually a vertical double-headed - * arrow. - */ -#define GLFW_RESIZE_NS_CURSOR 0x00036006 -/*! @brief The top-left to bottom-right diagonal resize/move arrow shape. - * - * The top-left to bottom-right diagonal resize/move shape. This is usually - * a diagonal double-headed arrow. - * - * @note @macos This shape is provided by a private system API and may fail - * with @ref GLFW_CURSOR_UNAVAILABLE in the future. - * - * @note @wayland This shape is provided by a newer standard not supported by - * all cursor themes. - * - * @note @x11 This shape is provided by a newer standard not supported by all - * cursor themes. - */ -#define GLFW_RESIZE_NWSE_CURSOR 0x00036007 -/*! @brief The top-right to bottom-left diagonal resize/move arrow shape. - * - * The top-right to bottom-left diagonal resize/move shape. This is usually - * a diagonal double-headed arrow. - * - * @note @macos This shape is provided by a private system API and may fail - * with @ref GLFW_CURSOR_UNAVAILABLE in the future. - * - * @note @wayland This shape is provided by a newer standard not supported by - * all cursor themes. - * - * @note @x11 This shape is provided by a newer standard not supported by all - * cursor themes. - */ -#define GLFW_RESIZE_NESW_CURSOR 0x00036008 -/*! @brief The omni-directional resize/move cursor shape. - * - * The omni-directional resize cursor/move shape. This is usually either - * a combined horizontal and vertical double-headed arrow or a grabbing hand. - */ -#define GLFW_RESIZE_ALL_CURSOR 0x00036009 -/*! @brief The operation-not-allowed shape. - * - * The operation-not-allowed shape. This is usually a circle with a diagonal - * line through it. - * - * @note @wayland This shape is provided by a newer standard not supported by - * all cursor themes. - * - * @note @x11 This shape is provided by a newer standard not supported by all - * cursor themes. - */ -#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A -/*! @brief Legacy name for compatibility. - * - * This is an alias for compatibility with earlier versions. - */ -#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR -/*! @brief Legacy name for compatibility. - * - * This is an alias for compatibility with earlier versions. - */ -#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR -/*! @brief Legacy name for compatibility. - * - * This is an alias for compatibility with earlier versions. - */ -#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR -/*! @} */ - -#define GLFW_CONNECTED 0x00040001 -#define GLFW_DISCONNECTED 0x00040002 - -/*! @addtogroup init - * @{ */ -/*! @brief Joystick hat buttons init hint. - * - * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS). - */ -#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 -/*! @brief ANGLE rendering backend init hint. - * - * ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint). - */ -#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002 -/*! @brief Platform selection init hint. - * - * Platform selection [init hint](@ref GLFW_PLATFORM). - */ -#define GLFW_PLATFORM 0x00050003 -/*! @brief macOS specific init hint. - * - * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint). - */ -#define GLFW_COCOA_CHDIR_RESOURCES 0x00051001 -/*! @brief macOS specific init hint. - * - * macOS specific [init hint](@ref GLFW_COCOA_MENUBAR_hint). - */ -#define GLFW_COCOA_MENUBAR 0x00051002 -/*! @brief X11 specific init hint. - * - * X11 specific [init hint](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint). - */ -#define GLFW_X11_XCB_VULKAN_SURFACE 0x00052001 -/*! @brief Wayland specific init hint. - * - * Wayland specific [init hint](@ref GLFW_WAYLAND_LIBDECOR_hint). - */ -#define GLFW_WAYLAND_LIBDECOR 0x00053001 -/*! @} */ - -/*! @addtogroup init - * @{ */ -/*! @brief Hint value that enables automatic platform selection. - * - * Hint value for @ref GLFW_PLATFORM that enables automatic platform selection. - */ -#define GLFW_ANY_PLATFORM 0x00060000 -#define GLFW_PLATFORM_WIN32 0x00060001 -#define GLFW_PLATFORM_COCOA 0x00060002 -#define GLFW_PLATFORM_WAYLAND 0x00060003 -#define GLFW_PLATFORM_X11 0x00060004 -#define GLFW_PLATFORM_NULL 0x00060005 -/*! @} */ - -#define GLFW_DONT_CARE -1 - - -/************************************************************************* - * GLFW API types - *************************************************************************/ - -/*! @brief Client API function pointer type. - * - * Generic function pointer used for returning client API function pointers - * without forcing a cast from a regular pointer. - * - * @sa @ref context_glext - * @sa @ref glfwGetProcAddress - * - * @since Added in version 3.0. - * - * @ingroup context - */ -typedef void (*GLFWglproc)(void); - -/*! @brief Vulkan API function pointer type. - * - * Generic function pointer used for returning Vulkan API function pointers - * without forcing a cast from a regular pointer. - * - * @sa @ref vulkan_proc - * @sa @ref glfwGetInstanceProcAddress - * - * @since Added in version 3.2. - * - * @ingroup vulkan - */ -typedef void (*GLFWvkproc)(void); - -/*! @brief Opaque monitor object. - * - * Opaque monitor object. - * - * @see @ref monitor_object - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -typedef struct GLFWmonitor GLFWmonitor; - -/*! @brief Opaque window object. - * - * Opaque window object. - * - * @see @ref window_object - * - * @since Added in version 3.0. - * - * @ingroup window - */ -typedef struct GLFWwindow GLFWwindow; - -/*! @brief Opaque cursor object. - * - * Opaque cursor object. - * - * @see @ref cursor_object - * - * @since Added in version 3.1. - * - * @ingroup input - */ -typedef struct GLFWcursor GLFWcursor; - -/*! @brief The function pointer type for memory allocation callbacks. - * - * This is the function pointer type for memory allocation callbacks. A memory - * allocation callback function has the following signature: - * @code - * void* function_name(size_t size, void* user) - * @endcode - * - * This function must return either a memory block at least `size` bytes long, - * or `NULL` if allocation failed. Note that not all parts of GLFW handle allocation - * failures gracefully yet. - * - * This function must support being called during @ref glfwInit but before the library is - * flagged as initialized, as well as during @ref glfwTerminate after the library is no - * longer flagged as initialized. - * - * Any memory allocated via this function will be deallocated via the same allocator - * during library termination or earlier. - * - * Any memory allocated via this function must be suitably aligned for any object type. - * If you are using C99 or earlier, this alignment is platform-dependent but will be the - * same as what `malloc` provides. If you are using C11 or later, this is the value of - * `alignof(max_align_t)`. - * - * The size will always be greater than zero. Allocations of size zero are filtered out - * before reaching the custom allocator. - * - * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. - * - * This function must not call any GLFW function. - * - * @param[in] size The minimum size, in bytes, of the memory block. - * @param[in] user The user-defined pointer from the allocator. - * @return The address of the newly allocated memory block, or `NULL` if an - * error occurred. - * - * @pointer_lifetime The returned memory block must be valid at least until it - * is deallocated. - * - * @reentrancy This function should not call any GLFW function. - * - * @thread_safety This function must support being called from any thread that calls GLFW - * functions. - * - * @sa @ref init_allocator - * @sa @ref GLFWallocator - * - * @since Added in version 3.4. - * - * @ingroup init - */ -typedef void* (* GLFWallocatefun)(size_t size, void* user); - -/*! @brief The function pointer type for memory reallocation callbacks. - * - * This is the function pointer type for memory reallocation callbacks. - * A memory reallocation callback function has the following signature: - * @code - * void* function_name(void* block, size_t size, void* user) - * @endcode - * - * This function must return a memory block at least `size` bytes long, or - * `NULL` if allocation failed. Note that not all parts of GLFW handle allocation - * failures gracefully yet. - * - * This function must support being called during @ref glfwInit but before the library is - * flagged as initialized, as well as during @ref glfwTerminate after the library is no - * longer flagged as initialized. - * - * Any memory allocated via this function will be deallocated via the same allocator - * during library termination or earlier. - * - * Any memory allocated via this function must be suitably aligned for any object type. - * If you are using C99 or earlier, this alignment is platform-dependent but will be the - * same as what `realloc` provides. If you are using C11 or later, this is the value of - * `alignof(max_align_t)`. - * - * The block address will never be `NULL` and the size will always be greater than zero. - * Reallocations of a block to size zero are converted into deallocations before reaching - * the custom allocator. Reallocations of `NULL` to a non-zero size are converted into - * regular allocations before reaching the custom allocator. - * - * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. - * - * This function must not call any GLFW function. - * - * @param[in] block The address of the memory block to reallocate. - * @param[in] size The new minimum size, in bytes, of the memory block. - * @param[in] user The user-defined pointer from the allocator. - * @return The address of the newly allocated or resized memory block, or - * `NULL` if an error occurred. - * - * @pointer_lifetime The returned memory block must be valid at least until it - * is deallocated. - * - * @reentrancy This function should not call any GLFW function. - * - * @thread_safety This function must support being called from any thread that calls GLFW - * functions. - * - * @sa @ref init_allocator - * @sa @ref GLFWallocator - * - * @since Added in version 3.4. - * - * @ingroup init - */ -typedef void* (* GLFWreallocatefun)(void* block, size_t size, void* user); - -/*! @brief The function pointer type for memory deallocation callbacks. - * - * This is the function pointer type for memory deallocation callbacks. - * A memory deallocation callback function has the following signature: - * @code - * void function_name(void* block, void* user) - * @endcode - * - * This function may deallocate the specified memory block. This memory block - * will have been allocated with the same allocator. - * - * This function must support being called during @ref glfwInit but before the library is - * flagged as initialized, as well as during @ref glfwTerminate after the library is no - * longer flagged as initialized. - * - * The block address will never be `NULL`. Deallocations of `NULL` are filtered out - * before reaching the custom allocator. - * - * If this function returns `NULL`, GLFW will emit @ref GLFW_OUT_OF_MEMORY. - * - * This function must not call any GLFW function. - * - * @param[in] block The address of the memory block to deallocate. - * @param[in] user The user-defined pointer from the allocator. - * - * @pointer_lifetime The specified memory block will not be accessed by GLFW - * after this function is called. - * - * @reentrancy This function should not call any GLFW function. - * - * @thread_safety This function must support being called from any thread that calls GLFW - * functions. - * - * @sa @ref init_allocator - * @sa @ref GLFWallocator - * - * @since Added in version 3.4. - * - * @ingroup init - */ -typedef void (* GLFWdeallocatefun)(void* block, void* user); - -/*! @brief The function pointer type for error callbacks. - * - * This is the function pointer type for error callbacks. An error callback - * function has the following signature: - * @code - * void callback_name(int error_code, const char* description) - * @endcode - * - * @param[in] error_code An [error code](@ref errors). Future releases may add - * more error codes. - * @param[in] description A UTF-8 encoded string describing the error. - * - * @pointer_lifetime The error description string is valid until the callback - * function returns. - * - * @sa @ref error_handling - * @sa @ref glfwSetErrorCallback - * - * @since Added in version 3.0. - * - * @ingroup init - */ -typedef void (* GLFWerrorfun)(int error_code, const char* description); - -/*! @brief The function pointer type for window position callbacks. - * - * This is the function pointer type for window position callbacks. A window - * position callback function has the following signature: - * @code - * void callback_name(GLFWwindow* window, int xpos, int ypos) - * @endcode - * - * @param[in] window The window that was moved. - * @param[in] xpos The new x-coordinate, in screen coordinates, of the - * upper-left corner of the content area of the window. - * @param[in] ypos The new y-coordinate, in screen coordinates, of the - * upper-left corner of the content area of the window. - * - * @sa @ref window_pos - * @sa @ref glfwSetWindowPosCallback - * - * @since Added in version 3.0. - * - * @ingroup window - */ -typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos); - -/*! @brief The function pointer type for window size callbacks. - * - * This is the function pointer type for window size callbacks. A window size - * callback function has the following signature: - * @code - * void callback_name(GLFWwindow* window, int width, int height) - * @endcode - * - * @param[in] window The window that was resized. - * @param[in] width The new width, in screen coordinates, of the window. - * @param[in] height The new height, in screen coordinates, of the window. - * - * @sa @ref window_size - * @sa @ref glfwSetWindowSizeCallback - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height); - -/*! @brief The function pointer type for window close callbacks. - * - * This is the function pointer type for window close callbacks. A window - * close callback function has the following signature: - * @code - * void function_name(GLFWwindow* window) - * @endcode - * - * @param[in] window The window that the user attempted to close. - * - * @sa @ref window_close - * @sa @ref glfwSetWindowCloseCallback - * - * @since Added in version 2.5. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -typedef void (* GLFWwindowclosefun)(GLFWwindow* window); - -/*! @brief The function pointer type for window content refresh callbacks. - * - * This is the function pointer type for window content refresh callbacks. - * A window content refresh callback function has the following signature: - * @code - * void function_name(GLFWwindow* window); - * @endcode - * - * @param[in] window The window whose content needs to be refreshed. - * - * @sa @ref window_refresh - * @sa @ref glfwSetWindowRefreshCallback - * - * @since Added in version 2.5. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -typedef void (* GLFWwindowrefreshfun)(GLFWwindow* window); - -/*! @brief The function pointer type for window focus callbacks. - * - * This is the function pointer type for window focus callbacks. A window - * focus callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int focused) - * @endcode - * - * @param[in] window The window that gained or lost input focus. - * @param[in] focused `GLFW_TRUE` if the window was given input focus, or - * `GLFW_FALSE` if it lost it. - * - * @sa @ref window_focus - * @sa @ref glfwSetWindowFocusCallback - * - * @since Added in version 3.0. - * - * @ingroup window - */ -typedef void (* GLFWwindowfocusfun)(GLFWwindow* window, int focused); - -/*! @brief The function pointer type for window iconify callbacks. - * - * This is the function pointer type for window iconify callbacks. A window - * iconify callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int iconified) - * @endcode - * - * @param[in] window The window that was iconified or restored. - * @param[in] iconified `GLFW_TRUE` if the window was iconified, or - * `GLFW_FALSE` if it was restored. - * - * @sa @ref window_iconify - * @sa @ref glfwSetWindowIconifyCallback - * - * @since Added in version 3.0. - * - * @ingroup window - */ -typedef void (* GLFWwindowiconifyfun)(GLFWwindow* window, int iconified); - -/*! @brief The function pointer type for window maximize callbacks. - * - * This is the function pointer type for window maximize callbacks. A window - * maximize callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int maximized) - * @endcode - * - * @param[in] window The window that was maximized or restored. - * @param[in] maximized `GLFW_TRUE` if the window was maximized, or - * `GLFW_FALSE` if it was restored. - * - * @sa @ref window_maximize - * @sa glfwSetWindowMaximizeCallback - * - * @since Added in version 3.3. - * - * @ingroup window - */ -typedef void (* GLFWwindowmaximizefun)(GLFWwindow* window, int maximized); - -/*! @brief The function pointer type for framebuffer size callbacks. - * - * This is the function pointer type for framebuffer size callbacks. - * A framebuffer size callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int width, int height) - * @endcode - * - * @param[in] window The window whose framebuffer was resized. - * @param[in] width The new width, in pixels, of the framebuffer. - * @param[in] height The new height, in pixels, of the framebuffer. - * - * @sa @ref window_fbsize - * @sa @ref glfwSetFramebufferSizeCallback - * - * @since Added in version 3.0. - * - * @ingroup window - */ -typedef void (* GLFWframebuffersizefun)(GLFWwindow* window, int width, int height); - -/*! @brief The function pointer type for window content scale callbacks. - * - * This is the function pointer type for window content scale callbacks. - * A window content scale callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, float xscale, float yscale) - * @endcode - * - * @param[in] window The window whose content scale changed. - * @param[in] xscale The new x-axis content scale of the window. - * @param[in] yscale The new y-axis content scale of the window. - * - * @sa @ref window_scale - * @sa @ref glfwSetWindowContentScaleCallback - * - * @since Added in version 3.3. - * - * @ingroup window - */ -typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, float yscale); - -/*! @brief The function pointer type for mouse button callbacks. - * - * This is the function pointer type for mouse button callback functions. - * A mouse button callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int button, int action, int mods) - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] button The [mouse button](@ref buttons) that was pressed or - * released. - * @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`. Future releases - * may add more actions. - * @param[in] mods Bit field describing which [modifier keys](@ref mods) were - * held down. - * - * @sa @ref input_mouse_button - * @sa @ref glfwSetMouseButtonCallback - * - * @since Added in version 1.0. - * @glfw3 Added window handle and modifier mask parameters. - * - * @ingroup input - */ -typedef void (* GLFWmousebuttonfun)(GLFWwindow* window, int button, int action, int mods); - -/*! @brief The function pointer type for cursor position callbacks. - * - * This is the function pointer type for cursor position callbacks. A cursor - * position callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, double xpos, double ypos); - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] xpos The new cursor x-coordinate, relative to the left edge of - * the content area. - * @param[in] ypos The new cursor y-coordinate, relative to the top edge of the - * content area. - * - * @sa @ref cursor_pos - * @sa @ref glfwSetCursorPosCallback - * - * @since Added in version 3.0. Replaces `GLFWmouseposfun`. - * - * @ingroup input - */ -typedef void (* GLFWcursorposfun)(GLFWwindow* window, double xpos, double ypos); - -/*! @brief The function pointer type for cursor enter/leave callbacks. - * - * This is the function pointer type for cursor enter/leave callbacks. - * A cursor enter/leave callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int entered) - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] entered `GLFW_TRUE` if the cursor entered the window's content - * area, or `GLFW_FALSE` if it left it. - * - * @sa @ref cursor_enter - * @sa @ref glfwSetCursorEnterCallback - * - * @since Added in version 3.0. - * - * @ingroup input - */ -typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered); - -/*! @brief The function pointer type for scroll callbacks. - * - * This is the function pointer type for scroll callbacks. A scroll callback - * function has the following signature: - * @code - * void function_name(GLFWwindow* window, double xoffset, double yoffset) - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] xoffset The scroll offset along the x-axis. - * @param[in] yoffset The scroll offset along the y-axis. - * - * @sa @ref scrolling - * @sa @ref glfwSetScrollCallback - * - * @since Added in version 3.0. Replaces `GLFWmousewheelfun`. - * - * @ingroup input - */ -typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset); - -/*! @brief The function pointer type for keyboard key callbacks. - * - * This is the function pointer type for keyboard key callbacks. A keyboard - * key callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] key The [keyboard key](@ref keys) that was pressed or released. - * @param[in] scancode The platform-specific scancode of the key. - * @param[in] action `GLFW_PRESS`, `GLFW_RELEASE` or `GLFW_REPEAT`. Future - * releases may add more actions. - * @param[in] mods Bit field describing which [modifier keys](@ref mods) were - * held down. - * - * @sa @ref input_key - * @sa @ref glfwSetKeyCallback - * - * @since Added in version 1.0. - * @glfw3 Added window handle, scancode and modifier mask parameters. - * - * @ingroup input - */ -typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int action, int mods); - -/*! @brief The function pointer type for Unicode character callbacks. - * - * This is the function pointer type for Unicode character callbacks. - * A Unicode character callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, unsigned int codepoint) - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] codepoint The Unicode code point of the character. - * - * @sa @ref input_char - * @sa @ref glfwSetCharCallback - * - * @since Added in version 2.4. - * @glfw3 Added window handle parameter. - * - * @ingroup input - */ -typedef void (* GLFWcharfun)(GLFWwindow* window, unsigned int codepoint); - -/*! @brief The function pointer type for Unicode character with modifiers - * callbacks. - * - * This is the function pointer type for Unicode character with modifiers - * callbacks. It is called for each input character, regardless of what - * modifier keys are held down. A Unicode character with modifiers callback - * function has the following signature: - * @code - * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] codepoint The Unicode code point of the character. - * @param[in] mods Bit field describing which [modifier keys](@ref mods) were - * held down. - * - * @sa @ref input_char - * @sa @ref glfwSetCharModsCallback - * - * @deprecated Scheduled for removal in version 4.0. - * - * @since Added in version 3.1. - * - * @ingroup input - */ -typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int mods); - -/*! @brief The function pointer type for path drop callbacks. - * - * This is the function pointer type for path drop callbacks. A path drop - * callback function has the following signature: - * @code - * void function_name(GLFWwindow* window, int path_count, const char* paths[]) - * @endcode - * - * @param[in] window The window that received the event. - * @param[in] path_count The number of dropped paths. - * @param[in] paths The UTF-8 encoded file and/or directory path names. - * - * @pointer_lifetime The path array and its strings are valid until the - * callback function returns. - * - * @sa @ref path_drop - * @sa @ref glfwSetDropCallback - * - * @since Added in version 3.1. - * - * @ingroup input - */ -typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* paths[]); - -/*! @brief The function pointer type for monitor configuration callbacks. - * - * This is the function pointer type for monitor configuration callbacks. - * A monitor callback function has the following signature: - * @code - * void function_name(GLFWmonitor* monitor, int event) - * @endcode - * - * @param[in] monitor The monitor that was connected or disconnected. - * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future - * releases may add more events. - * - * @sa @ref monitor_event - * @sa @ref glfwSetMonitorCallback - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event); - -/*! @brief The function pointer type for joystick configuration callbacks. - * - * This is the function pointer type for joystick configuration callbacks. - * A joystick configuration callback function has the following signature: - * @code - * void function_name(int jid, int event) - * @endcode - * - * @param[in] jid The joystick that was connected or disconnected. - * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future - * releases may add more events. - * - * @sa @ref joystick_event - * @sa @ref glfwSetJoystickCallback - * - * @since Added in version 3.2. - * - * @ingroup input - */ -typedef void (* GLFWjoystickfun)(int jid, int event); - -/*! @brief Video mode type. - * - * This describes a single video mode. - * - * @sa @ref monitor_modes - * @sa @ref glfwGetVideoMode - * @sa @ref glfwGetVideoModes - * - * @since Added in version 1.0. - * @glfw3 Added refresh rate member. - * - * @ingroup monitor - */ -typedef struct GLFWvidmode -{ - /*! The width, in screen coordinates, of the video mode. - */ - int width; - /*! The height, in screen coordinates, of the video mode. - */ - int height; - /*! The bit depth of the red channel of the video mode. - */ - int redBits; - /*! The bit depth of the green channel of the video mode. - */ - int greenBits; - /*! The bit depth of the blue channel of the video mode. - */ - int blueBits; - /*! The refresh rate, in Hz, of the video mode. - */ - int refreshRate; -} GLFWvidmode; - -/*! @brief Gamma ramp. - * - * This describes the gamma ramp for a monitor. - * - * @sa @ref monitor_gamma - * @sa @ref glfwGetGammaRamp - * @sa @ref glfwSetGammaRamp - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -typedef struct GLFWgammaramp -{ - /*! An array of value describing the response of the red channel. - */ - unsigned short* red; - /*! An array of value describing the response of the green channel. - */ - unsigned short* green; - /*! An array of value describing the response of the blue channel. - */ - unsigned short* blue; - /*! The number of elements in each array. - */ - unsigned int size; -} GLFWgammaramp; - -/*! @brief Image data. - * - * This describes a single 2D image. See the documentation for each related - * function what the expected pixel format is. - * - * @sa @ref cursor_custom - * @sa @ref window_icon - * - * @since Added in version 2.1. - * @glfw3 Removed format and bytes-per-pixel members. - * - * @ingroup window - */ -typedef struct GLFWimage -{ - /*! The width, in pixels, of this image. - */ - int width; - /*! The height, in pixels, of this image. - */ - int height; - /*! The pixel data of this image, arranged left-to-right, top-to-bottom. - */ - unsigned char* pixels; -} GLFWimage; - -/*! @brief Gamepad input state - * - * This describes the input state of a gamepad. - * - * @sa @ref gamepad - * @sa @ref glfwGetGamepadState - * - * @since Added in version 3.3. - * - * @ingroup input - */ -typedef struct GLFWgamepadstate -{ - /*! The states of each [gamepad button](@ref gamepad_buttons), `GLFW_PRESS` - * or `GLFW_RELEASE`. - */ - unsigned char buttons[15]; - /*! The states of each [gamepad axis](@ref gamepad_axes), in the range -1.0 - * to 1.0 inclusive. - */ - float axes[6]; -} GLFWgamepadstate; - -/*! @brief Custom heap memory allocator. - * - * This describes a custom heap memory allocator for GLFW. To set an allocator, pass it - * to @ref glfwInitAllocator before initializing the library. - * - * @sa @ref init_allocator - * @sa @ref glfwInitAllocator - * - * @since Added in version 3.4. - * - * @ingroup init - */ -typedef struct GLFWallocator -{ - /*! The memory allocation function. See @ref GLFWallocatefun for details about - * allocation function. - */ - GLFWallocatefun allocate; - /*! The memory reallocation function. See @ref GLFWreallocatefun for details about - * reallocation function. - */ - GLFWreallocatefun reallocate; - /*! The memory deallocation function. See @ref GLFWdeallocatefun for details about - * deallocation function. - */ - GLFWdeallocatefun deallocate; - /*! The user pointer for this custom allocator. This value will be passed to the - * allocator functions. - */ - void* user; -} GLFWallocator; - - -/************************************************************************* - * GLFW API functions - *************************************************************************/ - -/*! @brief Initializes the GLFW library. - * - * This function initializes the GLFW library. Before most GLFW functions can - * be used, GLFW must be initialized, and before an application terminates GLFW - * should be terminated in order to free any resources allocated during or - * after initialization. - * - * If this function fails, it calls @ref glfwTerminate before returning. If it - * succeeds, you should call @ref glfwTerminate before the application exits. - * - * Additional calls to this function after successful initialization but before - * termination will return `GLFW_TRUE` immediately. - * - * The @ref GLFW_PLATFORM init hint controls which platforms are considered during - * initialization. This also depends on which platforms the library was compiled to - * support. - * - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @macos This function will change the current directory of the - * application to the `Contents/Resources` subdirectory of the application's - * bundle, if present. This can be disabled with the @ref - * GLFW_COCOA_CHDIR_RESOURCES init hint. - * - * @remark @macos This function will create the main menu and dock icon for the - * application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to - * contain a menu bar. Otherwise a minimal menu bar is created manually with - * common commands like Hide, Quit and About. The About entry opens a minimal - * about dialog with information from the application's bundle. The menu bar - * and dock icon can be disabled entirely with the @ref GLFW_COCOA_MENUBAR init - * hint. - * - * @remark __Wayland, X11:__ If the library was compiled with support for both - * Wayland and X11, and the @ref GLFW_PLATFORM init hint is set to - * `GLFW_ANY_PLATFORM`, the `XDG_SESSION_TYPE` environment variable affects - * which platform is picked. If the environment variable is not set, or is set - * to something other than `wayland` or `x11`, the regular detection mechanism - * will be used instead. - * - * @remark @x11 This function will set the `LC_CTYPE` category of the - * application locale according to the current environment if that category is - * still "C". This is because the "C" locale breaks Unicode text input. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref intro_init - * @sa @ref glfwInitHint - * @sa @ref glfwInitAllocator - * @sa @ref glfwTerminate - * - * @since Added in version 1.0. - * - * @ingroup init - */ -GLFWAPI int glfwInit(void); - -/*! @brief Terminates the GLFW library. - * - * This function destroys all remaining windows and cursors, restores any - * modified gamma ramps and frees any other allocated resources. Once this - * function is called, you must again call @ref glfwInit successfully before - * you will be able to use most GLFW functions. - * - * If GLFW has been successfully initialized, this function should be called - * before the application exits. If initialization fails, there is no need to - * call this function, as it is called by @ref glfwInit before it returns - * failure. - * - * This function has no effect if GLFW is not initialized. - * - * @errors Possible errors include @ref GLFW_PLATFORM_ERROR. - * - * @remark This function may be called before @ref glfwInit. - * - * @warning The contexts of any remaining windows must not be current on any - * other thread when this function is called. - * - * @reentrancy This function must not be called from a callback. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref intro_init - * @sa @ref glfwInit - * - * @since Added in version 1.0. - * - * @ingroup init - */ -GLFWAPI void glfwTerminate(void); - -/*! @brief Sets the specified init hint to the desired value. - * - * This function sets hints for the next initialization of GLFW. - * - * The values you set hints to are never reset by GLFW, but they only take - * effect during initialization. Once GLFW has been initialized, any values - * you set will be ignored until the library is terminated and initialized - * again. - * - * Some hints are platform specific. These may be set on any platform but they - * will only affect their specific platform. Other platforms will ignore them. - * Setting these hints requires no platform specific headers or functions. - * - * @param[in] hint The [init hint](@ref init_hints) to set. - * @param[in] value The new value of the init hint. - * - * @errors Possible errors include @ref GLFW_INVALID_ENUM and @ref - * GLFW_INVALID_VALUE. - * - * @remarks This function may be called before @ref glfwInit. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa init_hints - * @sa glfwInit - * - * @since Added in version 3.3. - * - * @ingroup init - */ -GLFWAPI void glfwInitHint(int hint, int value); - -/*! @brief Sets the init allocator to the desired value. - * - * To use the default allocator, call this function with a `NULL` argument. - * - * If you specify an allocator struct, every member must be a valid function - * pointer. If any member is `NULL`, this function will emit @ref - * GLFW_INVALID_VALUE and the init allocator will be unchanged. - * - * The functions in the allocator must fulfil a number of requirements. See the - * documentation for @ref GLFWallocatefun, @ref GLFWreallocatefun and @ref - * GLFWdeallocatefun for details. - * - * @param[in] allocator The allocator to use at the next initialization, or - * `NULL` to use the default one. - * - * @errors Possible errors include @ref GLFW_INVALID_VALUE. - * - * @pointer_lifetime The specified allocator is copied before this function - * returns. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref init_allocator - * @sa @ref glfwInit - * - * @since Added in version 3.4. - * - * @ingroup init - */ -GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator); - -#if defined(VK_VERSION_1_0) - -/*! @brief Sets the desired Vulkan `vkGetInstanceProcAddr` function. - * - * This function sets the `vkGetInstanceProcAddr` function that GLFW will use for all - * Vulkan related entry point queries. - * - * This feature is mostly useful on macOS, if your copy of the Vulkan loader is in - * a location where GLFW cannot find it through dynamic loading, or if you are still - * using the static library version of the loader. - * - * If set to `NULL`, GLFW will try to load the Vulkan loader dynamically by its standard - * name and get this function from there. This is the default behavior. - * - * The standard name of the loader is `vulkan-1.dll` on Windows, `libvulkan.so.1` on - * Linux and other Unix-like systems and `libvulkan.1.dylib` on macOS. If your code is - * also loading it via these names then you probably don't need to use this function. - * - * The function address you set is never reset by GLFW, but it only takes effect during - * initialization. Once GLFW has been initialized, any updates will be ignored until the - * library is terminated and initialized again. - * - * @param[in] loader The address of the function to use, or `NULL`. - * - * @par Loader function signature - * @code - * PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance instance, const char* name) - * @endcode - * For more information about this function, see the - * [Vulkan Registry](https://www.khronos.org/registry/vulkan/). - * - * @errors None. - * - * @remark This function may be called before @ref glfwInit. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref vulkan_loader - * @sa @ref glfwInit - * - * @since Added in version 3.4. - * - * @ingroup init - */ -GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader); - -#endif /*VK_VERSION_1_0*/ - -/*! @brief Retrieves the version of the GLFW library. - * - * This function retrieves the major, minor and revision numbers of the GLFW - * library. It is intended for when you are using GLFW as a shared library and - * want to ensure that you are using the minimum required version. - * - * Any or all of the version arguments may be `NULL`. - * - * @param[out] major Where to store the major version number, or `NULL`. - * @param[out] minor Where to store the minor version number, or `NULL`. - * @param[out] rev Where to store the revision number, or `NULL`. - * - * @errors None. - * - * @remark This function may be called before @ref glfwInit. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref intro_version - * @sa @ref glfwGetVersionString - * - * @since Added in version 1.0. - * - * @ingroup init - */ -GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); - -/*! @brief Returns a string describing the compile-time configuration. - * - * This function returns the compile-time generated - * [version string](@ref intro_version_string) of the GLFW library binary. It describes - * the version, platforms, compiler and any platform or operating system specific - * compile-time options. It should not be confused with the OpenGL or OpenGL ES version - * string, queried with `glGetString`. - * - * __Do not use the version string__ to parse the GLFW library version. The - * @ref glfwGetVersion function provides the version of the running library - * binary in numerical format. - * - * __Do not use the version string__ to parse what platforms are supported. The @ref - * glfwPlatformSupported function lets you query platform support. - * - * @return The ASCII encoded GLFW version string. - * - * @errors None. - * - * @remark This function may be called before @ref glfwInit. - * - * @pointer_lifetime The returned string is static and compile-time generated. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref intro_version - * @sa @ref glfwGetVersion - * - * @since Added in version 3.0. - * - * @ingroup init - */ -GLFWAPI const char* glfwGetVersionString(void); - -/*! @brief Returns and clears the last error for the calling thread. - * - * This function returns and clears the [error code](@ref errors) of the last - * error that occurred on the calling thread, and optionally a UTF-8 encoded - * human-readable description of it. If no error has occurred since the last - * call, it returns @ref GLFW_NO_ERROR (zero) and the description pointer is - * set to `NULL`. - * - * @param[in] description Where to store the error description pointer, or `NULL`. - * @return The last error code for the calling thread, or @ref GLFW_NO_ERROR - * (zero). - * - * @errors None. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is guaranteed to be valid only until the - * next error occurs or the library is terminated. - * - * @remark This function may be called before @ref glfwInit. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref error_handling - * @sa @ref glfwSetErrorCallback - * - * @since Added in version 3.3. - * - * @ingroup init - */ -GLFWAPI int glfwGetError(const char** description); - -/*! @brief Sets the error callback. - * - * This function sets the error callback, which is called with an error code - * and a human-readable description each time a GLFW error occurs. - * - * The error code is set before the callback is called. Calling @ref - * glfwGetError from the error callback will return the same value as the error - * code argument. - * - * The error callback is called on the thread where the error occurred. If you - * are using GLFW from multiple threads, your error callback needs to be - * written accordingly. - * - * Because the description string may have been generated specifically for that - * error, it is not guaranteed to be valid after the callback has returned. If - * you wish to use it after the callback returns, you need to make a copy. - * - * Once set, the error callback remains set even after the library has been - * terminated. - * - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set. - * - * @callback_signature - * @code - * void callback_name(int error_code, const char* description) - * @endcode - * For more information about the callback parameters, see the - * [callback pointer type](@ref GLFWerrorfun). - * - * @errors None. - * - * @remark This function may be called before @ref glfwInit. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref error_handling - * @sa @ref glfwGetError - * - * @since Added in version 3.0. - * - * @ingroup init - */ -GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun callback); - -/*! @brief Returns the currently selected platform. - * - * This function returns the platform that was selected during initialization. The - * returned value will be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, - * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`. - * - * @return The currently selected platform, or zero if an error occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref platform - * @sa @ref glfwPlatformSupported - * - * @since Added in version 3.4. - * - * @ingroup init - */ -GLFWAPI int glfwGetPlatform(void); - -/*! @brief Returns whether the library includes support for the specified platform. - * - * This function returns whether the library was compiled with support for the specified - * platform. The platform must be one of `GLFW_PLATFORM_WIN32`, `GLFW_PLATFORM_COCOA`, - * `GLFW_PLATFORM_WAYLAND`, `GLFW_PLATFORM_X11` or `GLFW_PLATFORM_NULL`. - * - * @param[in] platform The platform to query. - * @return `GLFW_TRUE` if the platform is supported, or `GLFW_FALSE` otherwise. - * - * @errors Possible errors include @ref GLFW_INVALID_ENUM. - * - * @remark This function may be called before @ref glfwInit. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref platform - * @sa @ref glfwGetPlatform - * - * @since Added in version 3.4. - * - * @ingroup init - */ -GLFWAPI int glfwPlatformSupported(int platform); - -/*! @brief Returns the currently connected monitors. - * - * This function returns an array of handles for all currently connected - * monitors. The primary monitor is always first in the returned array. If no - * monitors were found, this function returns `NULL`. - * - * @param[out] count Where to store the number of monitors in the returned - * array. This is set to zero if an error occurred. - * @return An array of monitor handles, or `NULL` if no monitors were found or - * if an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @pointer_lifetime The returned array is allocated and freed by GLFW. You - * should not free it yourself. It is guaranteed to be valid only until the - * monitor configuration changes or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_monitors - * @sa @ref monitor_event - * @sa @ref glfwGetPrimaryMonitor - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI GLFWmonitor** glfwGetMonitors(int* count); - -/*! @brief Returns the primary monitor. - * - * This function returns the primary monitor. This is usually the monitor - * where elements like the task bar or global menu bar are located. - * - * @return The primary monitor, or `NULL` if no monitors were found or if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @remark The primary monitor is always first in the array returned by @ref - * glfwGetMonitors. - * - * @sa @ref monitor_monitors - * @sa @ref glfwGetMonitors - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); - -/*! @brief Returns the position of the monitor's viewport on the virtual screen. - * - * This function returns the position, in screen coordinates, of the upper-left - * corner of the specified monitor. - * - * Any or all of the position arguments may be `NULL`. If an error occurs, all - * non-`NULL` position arguments will be set to zero. - * - * @param[in] monitor The monitor to query. - * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. - * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_properties - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); - -/*! @brief Retrieves the work area of the monitor. - * - * This function returns the position, in screen coordinates, of the upper-left - * corner of the work area of the specified monitor along with the work area - * size in screen coordinates. The work area is defined as the area of the - * monitor not occluded by the window system task bar where present. If no - * task bar exists then the work area is the monitor resolution in screen - * coordinates. - * - * Any or all of the position and size arguments may be `NULL`. If an error - * occurs, all non-`NULL` position and size arguments will be set to zero. - * - * @param[in] monitor The monitor to query. - * @param[out] xpos Where to store the monitor x-coordinate, or `NULL`. - * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. - * @param[out] width Where to store the monitor width, or `NULL`. - * @param[out] height Where to store the monitor height, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_workarea - * - * @since Added in version 3.3. - * - * @ingroup monitor - */ -GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height); - -/*! @brief Returns the physical size of the monitor. - * - * This function returns the size, in millimetres, of the display area of the - * specified monitor. - * - * Some platforms do not provide accurate monitor size information, either - * because the monitor [EDID][] data is incorrect or because the driver does - * not report it accurately. - * - * [EDID]: https://en.wikipedia.org/wiki/Extended_display_identification_data - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] monitor The monitor to query. - * @param[out] widthMM Where to store the width, in millimetres, of the - * monitor's display area, or `NULL`. - * @param[out] heightMM Where to store the height, in millimetres, of the - * monitor's display area, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @remark @win32 On Windows 8 and earlier the physical size is calculated from - * the current resolution and system DPI instead of querying the monitor EDID data. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_properties - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int* heightMM); - -/*! @brief Retrieves the content scale for the specified monitor. - * - * This function retrieves the content scale for the specified monitor. The - * content scale is the ratio between the current DPI and the platform's - * default DPI. This is especially important for text and any UI elements. If - * the pixel dimensions of your UI scaled by this look appropriate on your - * machine then it should appear at a reasonable size on other machines - * regardless of their DPI and scaling settings. This relies on the system DPI - * and scaling settings being somewhat correct. - * - * The content scale may depend on both the monitor resolution and pixel - * density and on user settings. It may be very different from the raw DPI - * calculated from the physical size and current resolution. - * - * @param[in] monitor The monitor to query. - * @param[out] xscale Where to store the x-axis content scale, or `NULL`. - * @param[out] yscale Where to store the y-axis content scale, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @wayland Fractional scaling information is not yet available for - * monitors, so this function only returns integer content scales. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_scale - * @sa @ref glfwGetWindowContentScale - * - * @since Added in version 3.3. - * - * @ingroup monitor - */ -GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* monitor, float* xscale, float* yscale); - -/*! @brief Returns the name of the specified monitor. - * - * This function returns a human-readable name, encoded as UTF-8, of the - * specified monitor. The name typically reflects the make and model of the - * monitor and is not guaranteed to be unique among the connected monitors. - * - * @param[in] monitor The monitor to query. - * @return The UTF-8 encoded name of the monitor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified monitor is - * disconnected or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_properties - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); - -/*! @brief Sets the user pointer of the specified monitor. - * - * This function sets the user-defined pointer of the specified monitor. The - * current value is retained until the monitor is disconnected. The initial - * value is `NULL`. - * - * This function may be called from the monitor callback, even for a monitor - * that is being disconnected. - * - * @param[in] monitor The monitor whose pointer to set. - * @param[in] pointer The new value. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref monitor_userptr - * @sa @ref glfwGetMonitorUserPointer - * - * @since Added in version 3.3. - * - * @ingroup monitor - */ -GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* monitor, void* pointer); - -/*! @brief Returns the user pointer of the specified monitor. - * - * This function returns the current value of the user-defined pointer of the - * specified monitor. The initial value is `NULL`. - * - * This function may be called from the monitor callback, even for a monitor - * that is being disconnected. - * - * @param[in] monitor The monitor whose pointer to return. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref monitor_userptr - * @sa @ref glfwSetMonitorUserPointer - * - * @since Added in version 3.3. - * - * @ingroup monitor - */ -GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* monitor); - -/*! @brief Sets the monitor configuration callback. - * - * This function sets the monitor configuration callback, or removes the - * currently set callback. This is called when a monitor is connected to or - * disconnected from the system. - * - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWmonitor* monitor, int event) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWmonitorfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_event - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback); - -/*! @brief Returns the available video modes for the specified monitor. - * - * This function returns an array of all video modes supported by the specified - * monitor. The returned array is sorted in ascending order, first by color - * bit depth (the sum of all channel depths), then by resolution area (the - * product of width and height), then resolution width and finally by refresh - * rate. - * - * @param[in] monitor The monitor to query. - * @param[out] count Where to store the number of video modes in the returned - * array. This is set to zero if an error occurred. - * @return An array of video modes, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned array is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified monitor is - * disconnected, this function is called again for that monitor or the library - * is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_modes - * @sa @ref glfwGetVideoMode - * - * @since Added in version 1.0. - * @glfw3 Changed to return an array of modes for a specific monitor. - * - * @ingroup monitor - */ -GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count); - -/*! @brief Returns the current mode of the specified monitor. - * - * This function returns the current video mode of the specified monitor. If - * you have created a full screen window for that monitor, the return value - * will depend on whether that window is iconified. - * - * @param[in] monitor The monitor to query. - * @return The current mode of the monitor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned array is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified monitor is - * disconnected or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_modes - * @sa @ref glfwGetVideoModes - * - * @since Added in version 3.0. Replaces `glfwGetDesktopMode`. - * - * @ingroup monitor - */ -GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); - -/*! @brief Generates a gamma ramp and sets it for the specified monitor. - * - * This function generates an appropriately sized gamma ramp from the specified - * exponent and then calls @ref glfwSetGammaRamp with it. The value must be - * a finite number greater than zero. - * - * The software controlled gamma ramp is applied _in addition_ to the hardware - * gamma correction, which today is usually an approximation of sRGB gamma. - * This means that setting a perfectly linear ramp, or gamma 1.0, will produce - * the default (usually sRGB-like) behavior. - * - * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref - * GLFW_SRGB_CAPABLE hint. - * - * @param[in] monitor The monitor whose gamma ramp to set. - * @param[in] gamma The desired exponent. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE, - * @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_gamma - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); - -/*! @brief Returns the current gamma ramp for the specified monitor. - * - * This function returns the current gamma ramp of the specified monitor. - * - * @param[in] monitor The monitor to query. - * @return The current gamma ramp, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR - * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while - * returning `NULL`. - * - * @pointer_lifetime The returned structure and its arrays are allocated and - * freed by GLFW. You should not free them yourself. They are valid until the - * specified monitor is disconnected, this function is called again for that - * monitor or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_gamma - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); - -/*! @brief Sets the current gamma ramp for the specified monitor. - * - * This function sets the current gamma ramp for the specified monitor. The - * original gamma ramp for that monitor is saved by GLFW the first time this - * function is called and is restored by @ref glfwTerminate. - * - * The software controlled gamma ramp is applied _in addition_ to the hardware - * gamma correction, which today is usually an approximation of sRGB gamma. - * This means that setting a perfectly linear ramp, or gamma 1.0, will produce - * the default (usually sRGB-like) behavior. - * - * For gamma correct rendering with OpenGL or OpenGL ES, see the @ref - * GLFW_SRGB_CAPABLE hint. - * - * @param[in] monitor The monitor whose gamma ramp to set. - * @param[in] ramp The gamma ramp to use. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR - * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark The size of the specified gamma ramp should match the size of the - * current ramp for that monitor. - * - * @remark @win32 The gamma ramp size must be 256. - * - * @remark @wayland Gamma handling is a privileged protocol, this function - * will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. - * - * @pointer_lifetime The specified gamma ramp is copied before this function - * returns. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref monitor_gamma - * - * @since Added in version 3.0. - * - * @ingroup monitor - */ -GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp); - -/*! @brief Resets all window hints to their default values. - * - * This function resets all window hints to their - * [default values](@ref window_hints_values). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_hints - * @sa @ref glfwWindowHint - * @sa @ref glfwWindowHintString - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwDefaultWindowHints(void); - -/*! @brief Sets the specified window hint to the desired value. - * - * This function sets hints for the next call to @ref glfwCreateWindow. The - * hints, once set, retain their values until changed by a call to this - * function or @ref glfwDefaultWindowHints, or until the library is terminated. - * - * Only integer value hints can be set with this function. String value hints - * are set with @ref glfwWindowHintString. - * - * This function does not check whether the specified hint values are valid. - * If you set hints to invalid values this will instead be reported by the next - * call to @ref glfwCreateWindow. - * - * Some hints are platform specific. These may be set on any platform but they - * will only affect their specific platform. Other platforms will ignore them. - * Setting these hints requires no platform specific headers or functions. - * - * @param[in] hint The [window hint](@ref window_hints) to set. - * @param[in] value The new value of the window hint. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_hints - * @sa @ref glfwWindowHintString - * @sa @ref glfwDefaultWindowHints - * - * @since Added in version 3.0. Replaces `glfwOpenWindowHint`. - * - * @ingroup window - */ -GLFWAPI void glfwWindowHint(int hint, int value); - -/*! @brief Sets the specified window hint to the desired value. - * - * This function sets hints for the next call to @ref glfwCreateWindow. The - * hints, once set, retain their values until changed by a call to this - * function or @ref glfwDefaultWindowHints, or until the library is terminated. - * - * Only string type hints can be set with this function. Integer value hints - * are set with @ref glfwWindowHint. - * - * This function does not check whether the specified hint values are valid. - * If you set hints to invalid values this will instead be reported by the next - * call to @ref glfwCreateWindow. - * - * Some hints are platform specific. These may be set on any platform but they - * will only affect their specific platform. Other platforms will ignore them. - * Setting these hints requires no platform specific headers or functions. - * - * @param[in] hint The [window hint](@ref window_hints) to set. - * @param[in] value The new value of the window hint. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @pointer_lifetime The specified string is copied before this function - * returns. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_hints - * @sa @ref glfwWindowHint - * @sa @ref glfwDefaultWindowHints - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI void glfwWindowHintString(int hint, const char* value); - -/*! @brief Creates a window and its associated context. - * - * This function creates a window and its associated OpenGL or OpenGL ES - * context. Most of the options controlling how the window and its context - * should be created are specified with [window hints](@ref window_hints). - * - * Successful creation does not change which context is current. Before you - * can use the newly created context, you need to - * [make it current](@ref context_current). For information about the `share` - * parameter, see @ref context_sharing. - * - * The created window, framebuffer and context may differ from what you - * requested, as not all parameters and hints are - * [hard constraints](@ref window_hints_hard). This includes the size of the - * window, especially for full screen windows. To query the actual attributes - * of the created window, framebuffer and context, see @ref - * glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. - * - * To create a full screen window, you need to specify the monitor the window - * will cover. If no monitor is specified, the window will be windowed mode. - * Unless you have a way for the user to choose a specific monitor, it is - * recommended that you pick the primary monitor. For more information on how - * to query connected monitors, see @ref monitor_monitors. - * - * For full screen windows, the specified size becomes the resolution of the - * window's _desired video mode_. As long as a full screen window is not - * iconified, the supported video mode most closely matching the desired video - * mode is set for the specified monitor. For more information about full - * screen windows, including the creation of so called _windowed full screen_ - * or _borderless full screen_ windows, see @ref window_windowed_full_screen. - * - * Once you have created the window, you can switch it between windowed and - * full screen mode with @ref glfwSetWindowMonitor. This will not affect its - * OpenGL or OpenGL ES context. - * - * By default, newly created windows use the placement recommended by the - * window system. To create the window at a specific position, set the @ref - * GLFW_POSITION_X and @ref GLFW_POSITION_Y window hints before creation. To - * restore the default behavior, set either or both hints back to - * `GLFW_ANY_POSITION`. - * - * As long as at least one full screen window is not iconified, the screensaver - * is prohibited from starting. - * - * Window systems put limits on window sizes. Very large or very small window - * dimensions may be overridden by the window system on creation. Check the - * actual [size](@ref window_size) after creation. - * - * The [swap interval](@ref buffer_swap) is not set during window creation and - * the initial value may vary depending on driver settings and defaults. - * - * @param[in] width The desired width, in screen coordinates, of the window. - * This must be greater than zero. - * @param[in] height The desired height, in screen coordinates, of the window. - * This must be greater than zero. - * @param[in] title The initial, UTF-8 encoded window title. - * @param[in] monitor The monitor to use for full screen mode, or `NULL` for - * windowed mode. - * @param[in] share The window whose context to share resources with, or `NULL` - * to not share resources. - * @return The handle of the created window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref - * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref - * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. - * - * @remark @win32 Window creation will fail if the Microsoft GDI software - * OpenGL implementation is the only one available. - * - * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it - * will be set as the initial icon for the window. If no such icon is present, - * the `IDI_APPLICATION` icon will be used instead. To set a different icon, - * see @ref glfwSetWindowIcon. - * - * @remark @win32 The context to share resources with must not be current on - * any other thread. - * - * @remark @macos The OS only supports core profile contexts for OpenGL - * versions 3.2 and later. Before creating an OpenGL context of version 3.2 or - * later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) - * hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all - * on macOS. - * - * @remark @macos The GLFW window has no icon, as it is not a document - * window, but the dock icon will be the same as the application bundle's icon. - * For more information on bundles, see the - * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. - * - * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ - * - * @remark @macos On OS X 10.10 and later the window frame will not be rendered - * at full resolution on Retina displays unless the - * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) - * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the - * application bundle's `Info.plist`. For more information, see - * [High Resolution Guidelines for OS X][hidpi-guide] in the Mac Developer - * Library. The GLFW test and example programs use a custom `Info.plist` - * template for this, which can be found as `CMake/Info.plist.in` in the source - * tree. - * - * [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html - * - * @remark @macos When activating frame autosaving with - * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified - * window size and position may be overridden by previously saved values. - * - * @remark @wayland GLFW uses [libdecor][] where available to create its window - * decorations. This in turn uses server-side XDG decorations where available - * and provides high quality client-side decorations on compositors like GNOME. - * If both XDG decorations and libdecor are unavailable, GLFW falls back to - * a very simple set of window decorations that only support moving, resizing - * and the window manager's right-click menu. - * - * [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor - * - * @remark @x11 Some window managers will not respect the placement of - * initially hidden windows. - * - * @remark @x11 Due to the asynchronous nature of X11, it may take a moment for - * a window to reach its requested state. This means you may not be able to - * query the final size, position or other attributes directly after window - * creation. - * - * @remark @x11 The class part of the `WM_CLASS` window property will by - * default be set to the window title passed to this function. The instance - * part will use the contents of the `RESOURCE_NAME` environment variable, if - * present and not empty, or fall back to the window title. Set the - * [GLFW_X11_CLASS_NAME](@ref GLFW_X11_CLASS_NAME_hint) and - * [GLFW_X11_INSTANCE_NAME](@ref GLFW_X11_INSTANCE_NAME_hint) window hints to - * override this. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_creation - * @sa @ref glfwDestroyWindow - * - * @since Added in version 3.0. Replaces `glfwOpenWindow`. - * - * @ingroup window - */ -GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share); - -/*! @brief Destroys the specified window and its context. - * - * This function destroys the specified window and its context. On calling - * this function, no further callbacks will be called for that window. - * - * If the context of the specified window is current on the main thread, it is - * detached before being destroyed. - * - * @param[in] window The window to destroy. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @note The context of the specified window must not be current on any other - * thread when this function is called. - * - * @reentrancy This function must not be called from a callback. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_creation - * @sa @ref glfwCreateWindow - * - * @since Added in version 3.0. Replaces `glfwCloseWindow`. - * - * @ingroup window - */ -GLFWAPI void glfwDestroyWindow(GLFWwindow* window); - -/*! @brief Checks the close flag of the specified window. - * - * This function returns the value of the close flag of the specified window. - * - * @param[in] window The window to query. - * @return The value of the close flag. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref window_close - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI int glfwWindowShouldClose(GLFWwindow* window); - -/*! @brief Sets the close flag of the specified window. - * - * This function sets the value of the close flag of the specified window. - * This can be used to override the user's attempt to close the window, or - * to signal that it should be closed. - * - * @param[in] window The window whose flag to change. - * @param[in] value The new value. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref window_close - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value); - -/*! @brief Returns the title of the specified window. - * - * This function returns the window title, encoded as UTF-8, of the specified - * window. This is the title set previously by @ref glfwCreateWindow - * or @ref glfwSetWindowTitle. - * - * @param[in] window The window to query. - * @return The UTF-8 encoded window title, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @remark The returned title is currently a copy of the title last set by @ref - * glfwCreateWindow or @ref glfwSetWindowTitle. It does not include any - * additional text which may be appended by the platform or another program. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the next call to @ref - * glfwGetWindowTitle or @ref glfwSetWindowTitle, or until the library is - * terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_title - * @sa @ref glfwSetWindowTitle - * - * @since Added in version 3.4. - * - * @ingroup window - */ -GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window); - -/*! @brief Sets the title of the specified window. - * - * This function sets the window title, encoded as UTF-8, of the specified - * window. - * - * @param[in] window The window whose title to change. - * @param[in] title The UTF-8 encoded window title. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @macos The window title will not be updated until the next time you - * process events. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_title - * @sa @ref glfwGetWindowTitle - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title); - -/*! @brief Sets the icon for the specified window. - * - * This function sets the icon of the specified window. If passed an array of - * candidate images, those of or closest to the sizes desired by the system are - * selected. If no images are specified, the window reverts to its default - * icon. - * - * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight - * bits per channel with the red channel first. They are arranged canonically - * as packed sequential rows, starting from the top-left corner. - * - * The desired image sizes varies depending on platform and system settings. - * The selected images will be rescaled as needed. Good sizes include 16x16, - * 32x32 and 48x48. - * - * @param[in] window The window whose icon to set. - * @param[in] count The number of images in the specified array, or zero to - * revert to the default window icon. - * @param[in] images The images to create the icon from. This is ignored if - * count is zero. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref - * GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @pointer_lifetime The specified image data is copied before this function - * returns. - * - * @remark @macos Regular windows do not have icons on macOS. This function - * will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as - * the application bundle's icon. For more information on bundles, see the - * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. - * - * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ - * - * @remark @wayland There is no existing protocol to change an icon, the - * window will thus inherit the one defined in the application's desktop file. - * This function will emit @ref GLFW_FEATURE_UNAVAILABLE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_icon - * - * @since Added in version 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* images); - -/*! @brief Retrieves the position of the content area of the specified window. - * - * This function retrieves the position, in screen coordinates, of the - * upper-left corner of the content area of the specified window. - * - * Any or all of the position arguments may be `NULL`. If an error occurs, all - * non-`NULL` position arguments will be set to zero. - * - * @param[in] window The window to query. - * @param[out] xpos Where to store the x-coordinate of the upper-left corner of - * the content area, or `NULL`. - * @param[out] ypos Where to store the y-coordinate of the upper-left corner of - * the content area, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark @wayland There is no way for an application to retrieve the global - * position of its windows. This function will emit @ref - * GLFW_FEATURE_UNAVAILABLE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_pos - * @sa @ref glfwSetWindowPos - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos); - -/*! @brief Sets the position of the content area of the specified window. - * - * This function sets the position, in screen coordinates, of the upper-left - * corner of the content area of the specified windowed mode window. If the - * window is a full screen window, this function does nothing. - * - * __Do not use this function__ to move an already visible window unless you - * have very good reasons for doing so, as it will confuse and annoy the user. - * - * The window manager may put limits on what positions are allowed. GLFW - * cannot and should not override these limits. - * - * @param[in] window The window to query. - * @param[in] xpos The x-coordinate of the upper-left corner of the content area. - * @param[in] ypos The y-coordinate of the upper-left corner of the content area. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark @wayland There is no way for an application to set the global - * position of its windows. This function will emit @ref - * GLFW_FEATURE_UNAVAILABLE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_pos - * @sa @ref glfwGetWindowPos - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos); - -/*! @brief Retrieves the size of the content area of the specified window. - * - * This function retrieves the size, in screen coordinates, of the content area - * of the specified window. If you wish to retrieve the size of the - * framebuffer of the window in pixels, see @ref glfwGetFramebufferSize. - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] window The window whose size to retrieve. - * @param[out] width Where to store the width, in screen coordinates, of the - * content area, or `NULL`. - * @param[out] height Where to store the height, in screen coordinates, of the - * content area, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_size - * @sa @ref glfwSetWindowSize - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); - -/*! @brief Sets the size limits of the specified window. - * - * This function sets the size limits of the content area of the specified - * window. If the window is full screen, the size limits only take effect - * once it is made windowed. If the window is not resizable, this function - * does nothing. - * - * The size limits are applied immediately to a windowed mode window and may - * cause it to be resized. - * - * The maximum dimensions must be greater than or equal to the minimum - * dimensions and all must be greater than or equal to zero. - * - * @param[in] window The window to set limits for. - * @param[in] minwidth The minimum width, in screen coordinates, of the content - * area, or `GLFW_DONT_CARE`. - * @param[in] minheight The minimum height, in screen coordinates, of the - * content area, or `GLFW_DONT_CARE`. - * @param[in] maxwidth The maximum width, in screen coordinates, of the content - * area, or `GLFW_DONT_CARE`. - * @param[in] maxheight The maximum height, in screen coordinates, of the - * content area, or `GLFW_DONT_CARE`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. - * - * @remark If you set size limits and an aspect ratio that conflict, the - * results are undefined. - * - * @remark @wayland The size limits will not be applied until the window is - * actually resized, either by the user or by the compositor. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_sizelimits - * @sa @ref glfwSetWindowAspectRatio - * - * @since Added in version 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight); - -/*! @brief Sets the aspect ratio of the specified window. - * - * This function sets the required aspect ratio of the content area of the - * specified window. If the window is full screen, the aspect ratio only takes - * effect once it is made windowed. If the window is not resizable, this - * function does nothing. - * - * The aspect ratio is specified as a numerator and a denominator and both - * values must be greater than zero. For example, the common 16:9 aspect ratio - * is specified as 16 and 9, respectively. - * - * If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect - * ratio limit is disabled. - * - * The aspect ratio is applied immediately to a windowed mode window and may - * cause it to be resized. - * - * @param[in] window The window to set limits for. - * @param[in] numer The numerator of the desired aspect ratio, or - * `GLFW_DONT_CARE`. - * @param[in] denom The denominator of the desired aspect ratio, or - * `GLFW_DONT_CARE`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. - * - * @remark If you set size limits and an aspect ratio that conflict, the - * results are undefined. - * - * @remark @wayland The aspect ratio will not be applied until the window is - * actually resized, either by the user or by the compositor. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_sizelimits - * @sa @ref glfwSetWindowSizeLimits - * - * @since Added in version 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); - -/*! @brief Sets the size of the content area of the specified window. - * - * This function sets the size, in screen coordinates, of the content area of - * the specified window. - * - * For full screen windows, this function updates the resolution of its desired - * video mode and switches to the video mode closest to it, without affecting - * the window's context. As the context is unaffected, the bit depths of the - * framebuffer remain unchanged. - * - * If you wish to update the refresh rate of the desired video mode in addition - * to its resolution, see @ref glfwSetWindowMonitor. - * - * The window manager may put limits on what sizes are allowed. GLFW cannot - * and should not override these limits. - * - * @param[in] window The window to resize. - * @param[in] width The desired width, in screen coordinates, of the window - * content area. - * @param[in] height The desired height, in screen coordinates, of the window - * content area. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_size - * @sa @ref glfwGetWindowSize - * @sa @ref glfwSetWindowMonitor - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height); - -/*! @brief Retrieves the size of the framebuffer of the specified window. - * - * This function retrieves the size, in pixels, of the framebuffer of the - * specified window. If you wish to retrieve the size of the window in screen - * coordinates, see @ref glfwGetWindowSize. - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] window The window whose framebuffer to query. - * @param[out] width Where to store the width, in pixels, of the framebuffer, - * or `NULL`. - * @param[out] height Where to store the height, in pixels, of the framebuffer, - * or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_fbsize - * @sa @ref glfwSetFramebufferSizeCallback - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height); - -/*! @brief Retrieves the size of the frame of the window. - * - * This function retrieves the size, in screen coordinates, of each edge of the - * frame of the specified window. This size includes the title bar, if the - * window has one. The size of the frame may vary depending on the - * [window-related hints](@ref window_hints_wnd) used to create it. - * - * Because this function retrieves the size of each window frame edge and not - * the offset along a particular coordinate axis, the retrieved values will - * always be zero or positive. - * - * Any or all of the size arguments may be `NULL`. If an error occurs, all - * non-`NULL` size arguments will be set to zero. - * - * @param[in] window The window whose frame size to query. - * @param[out] left Where to store the size, in screen coordinates, of the left - * edge of the window frame, or `NULL`. - * @param[out] top Where to store the size, in screen coordinates, of the top - * edge of the window frame, or `NULL`. - * @param[out] right Where to store the size, in screen coordinates, of the - * right edge of the window frame, or `NULL`. - * @param[out] bottom Where to store the size, in screen coordinates, of the - * bottom edge of the window frame, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_size - * - * @since Added in version 3.1. - * - * @ingroup window - */ -GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int* right, int* bottom); - -/*! @brief Retrieves the content scale for the specified window. - * - * This function retrieves the content scale for the specified window. The - * content scale is the ratio between the current DPI and the platform's - * default DPI. This is especially important for text and any UI elements. If - * the pixel dimensions of your UI scaled by this look appropriate on your - * machine then it should appear at a reasonable size on other machines - * regardless of their DPI and scaling settings. This relies on the system DPI - * and scaling settings being somewhat correct. - * - * On platforms where each monitors can have its own content scale, the window - * content scale will depend on which monitor the system considers the window - * to be on. - * - * @param[in] window The window to query. - * @param[out] xscale Where to store the x-axis content scale, or `NULL`. - * @param[out] yscale Where to store the y-axis content scale, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_scale - * @sa @ref glfwSetWindowContentScaleCallback - * @sa @ref glfwGetMonitorContentScale - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI void glfwGetWindowContentScale(GLFWwindow* window, float* xscale, float* yscale); - -/*! @brief Returns the opacity of the whole window. - * - * This function returns the opacity of the window, including any decorations. - * - * The opacity (or alpha) value is a positive finite number between zero and - * one, where zero is fully transparent and one is fully opaque. If the system - * does not support whole window transparency, this function always returns one. - * - * The initial opacity value for newly created windows is one. - * - * @param[in] window The window to query. - * @return The opacity value of the specified window. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_transparency - * @sa @ref glfwSetWindowOpacity - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window); - -/*! @brief Sets the opacity of the whole window. - * - * This function sets the opacity of the window, including any decorations. - * - * The opacity (or alpha) value is a positive finite number between zero and - * one, where zero is fully transparent and one is fully opaque. - * - * The initial opacity value for newly created windows is one. - * - * A window created with framebuffer transparency may not use whole window - * transparency. The results of doing this are undefined. - * - * @param[in] window The window to set the opacity for. - * @param[in] opacity The desired opacity of the specified window. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark @wayland There is no way to set an opacity factor for a window. - * This function will emit @ref GLFW_FEATURE_UNAVAILABLE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_transparency - * @sa @ref glfwGetWindowOpacity - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity); - -/*! @brief Iconifies the specified window. - * - * This function iconifies (minimizes) the specified window if it was - * previously restored. If the window is already iconified, this function does - * nothing. - * - * If the specified window is a full screen window, GLFW restores the original - * video mode of the monitor. The window's desired video mode is set again - * when the window is restored. - * - * @param[in] window The window to iconify. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @wayland Once a window is iconified, @ref glfwRestoreWindow won’t - * be able to restore it. This is a design decision of the xdg-shell - * protocol. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_iconify - * @sa @ref glfwRestoreWindow - * @sa @ref glfwMaximizeWindow - * - * @since Added in version 2.1. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwIconifyWindow(GLFWwindow* window); - -/*! @brief Restores the specified window. - * - * This function restores the specified window if it was previously iconified - * (minimized) or maximized. If the window is already restored, this function - * does nothing. - * - * If the specified window is an iconified full screen window, its desired - * video mode is set again for its monitor when the window is restored. - * - * @param[in] window The window to restore. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_iconify - * @sa @ref glfwIconifyWindow - * @sa @ref glfwMaximizeWindow - * - * @since Added in version 2.1. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwRestoreWindow(GLFWwindow* window); - -/*! @brief Maximizes the specified window. - * - * This function maximizes the specified window if it was previously not - * maximized. If the window is already maximized, this function does nothing. - * - * If the specified window is a full screen window, this function does nothing. - * - * @param[in] window The window to maximize. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @par Thread Safety - * This function may only be called from the main thread. - * - * @sa @ref window_iconify - * @sa @ref glfwIconifyWindow - * @sa @ref glfwRestoreWindow - * - * @since Added in GLFW 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwMaximizeWindow(GLFWwindow* window); - -/*! @brief Makes the specified window visible. - * - * This function makes the specified window visible if it was previously - * hidden. If the window is already visible or is in full screen mode, this - * function does nothing. - * - * By default, windowed mode windows are focused when shown - * Set the [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) window hint - * to change this behavior for all newly created windows, or change the - * behavior for an existing window with @ref glfwSetWindowAttrib. - * - * @param[in] window The window to make visible. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @wayland Because Wayland wants every frame of the desktop to be - * complete, this function does not immediately make the window visible. - * Instead it will become visible the next time the window framebuffer is - * updated after this call. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_hide - * @sa @ref glfwHideWindow - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwShowWindow(GLFWwindow* window); - -/*! @brief Hides the specified window. - * - * This function hides the specified window if it was previously visible. If - * the window is already hidden or is in full screen mode, this function does - * nothing. - * - * @param[in] window The window to hide. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_hide - * @sa @ref glfwShowWindow - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwHideWindow(GLFWwindow* window); - -/*! @brief Brings the specified window to front and sets input focus. - * - * This function brings the specified window to front and sets input focus. - * The window should already be visible and not iconified. - * - * By default, both windowed and full screen mode windows are focused when - * initially created. Set the [GLFW_FOCUSED](@ref GLFW_FOCUSED_hint) to - * disable this behavior. - * - * Also by default, windowed mode windows are focused when shown - * with @ref glfwShowWindow. Set the - * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_hint) to disable this behavior. - * - * __Do not use this function__ to steal focus from other applications unless - * you are certain that is what the user wants. Focus stealing can be - * extremely disruptive. - * - * For a less disruptive way of getting the user's attention, see - * [attention requests](@ref window_attention). - * - * @param[in] window The window to give input focus. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @wayland The compositor will likely ignore focus requests unless - * another window created by the same application already has input focus. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_focus - * @sa @ref window_attention - * - * @since Added in version 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwFocusWindow(GLFWwindow* window); - -/*! @brief Requests user attention to the specified window. - * - * This function requests user attention to the specified window. On - * platforms where this is not supported, attention is requested to the - * application as a whole. - * - * Once the user has given attention, usually by focusing the window or - * application, the system will end the request automatically. - * - * @param[in] window The window to request attention to. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @macos Attention is requested to the application as a whole, not the - * specific window. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_attention - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI void glfwRequestWindowAttention(GLFWwindow* window); - -/*! @brief Returns the monitor that the window uses for full screen mode. - * - * This function returns the handle of the monitor that the specified window is - * in full screen on. - * - * @param[in] window The window to query. - * @return The monitor, or `NULL` if the window is in windowed mode or an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_monitor - * @sa @ref glfwSetWindowMonitor - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); - -/*! @brief Sets the mode, monitor, video mode and placement of a window. - * - * This function sets the monitor that the window uses for full screen mode or, - * if the monitor is `NULL`, makes it windowed mode. - * - * When setting a monitor, this function updates the width, height and refresh - * rate of the desired video mode and switches to the video mode closest to it. - * The window position is ignored when setting a monitor. - * - * When the monitor is `NULL`, the position, width and height are used to - * place the window content area. The refresh rate is ignored when no monitor - * is specified. - * - * If you only wish to update the resolution of a full screen window or the - * size of a windowed mode window, see @ref glfwSetWindowSize. - * - * When a window transitions from full screen to windowed mode, this function - * restores any previous window settings such as whether it is decorated, - * floating, resizable, has size or aspect ratio limits, etc. - * - * @param[in] window The window whose monitor, size or video mode to set. - * @param[in] monitor The desired monitor, or `NULL` to set windowed mode. - * @param[in] xpos The desired x-coordinate of the upper-left corner of the - * content area. - * @param[in] ypos The desired y-coordinate of the upper-left corner of the - * content area. - * @param[in] width The desired with, in screen coordinates, of the content - * area or video mode. - * @param[in] height The desired height, in screen coordinates, of the content - * area or video mode. - * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode, - * or `GLFW_DONT_CARE`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark The OpenGL or OpenGL ES context will not be destroyed or otherwise - * affected by any resizing or mode switching, although you may need to update - * your viewport if the framebuffer size has changed. - * - * @remark @wayland The desired window position is ignored, as there is no way - * for an application to set this property. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_monitor - * @sa @ref window_full_screen - * @sa @ref glfwGetWindowMonitor - * @sa @ref glfwSetWindowSize - * - * @since Added in version 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); - -/*! @brief Returns an attribute of the specified window. - * - * This function returns the value of an attribute of the specified window or - * its OpenGL or OpenGL ES context. - * - * @param[in] window The window to query. - * @param[in] attrib The [window attribute](@ref window_attribs) whose value to - * return. - * @return The value of the attribute, or zero if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @remark Framebuffer related hints are not window attributes. See @ref - * window_attribs_fb for more information. - * - * @remark Zero is a valid value for many window and context related - * attributes so you cannot use a return value of zero as an indication of - * errors. However, this function should not fail as long as it is passed - * valid arguments and the library has been [initialized](@ref intro_init). - * - * @remark @wayland The Wayland protocol provides no way to check whether a - * window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_attribs - * @sa @ref glfwSetWindowAttrib - * - * @since Added in version 3.0. Replaces `glfwGetWindowParam` and - * `glfwGetGLVersion`. - * - * @ingroup window - */ -GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib); - -/*! @brief Sets an attribute of the specified window. - * - * This function sets the value of an attribute of the specified window. - * - * The supported attributes are [GLFW_DECORATED](@ref GLFW_DECORATED_attrib), - * [GLFW_RESIZABLE](@ref GLFW_RESIZABLE_attrib), - * [GLFW_FLOATING](@ref GLFW_FLOATING_attrib), - * [GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) and - * [GLFW_FOCUS_ON_SHOW](@ref GLFW_FOCUS_ON_SHOW_attrib). - * [GLFW_MOUSE_PASSTHROUGH](@ref GLFW_MOUSE_PASSTHROUGH_attrib) - * - * Some of these attributes are ignored for full screen windows. The new - * value will take effect if the window is later made windowed. - * - * Some of these attributes are ignored for windowed mode windows. The new - * value will take effect if the window is later made full screen. - * - * @param[in] window The window to set the attribute for. - * @param[in] attrib A supported window attribute. - * @param[in] value `GLFW_TRUE` or `GLFW_FALSE`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_PLATFORM_ERROR and @ref - * GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark Calling @ref glfwGetWindowAttrib will always return the latest - * value, even if that value is ignored by the current mode of the window. - * - * @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is - * not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_attribs - * @sa @ref glfwGetWindowAttrib - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowAttrib(GLFWwindow* window, int attrib, int value); - -/*! @brief Sets the user pointer of the specified window. - * - * This function sets the user-defined pointer of the specified window. The - * current value is retained until the window is destroyed. The initial value - * is `NULL`. - * - * @param[in] window The window whose pointer to set. - * @param[in] pointer The new value. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref window_userptr - * @sa @ref glfwGetWindowUserPointer - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* window, void* pointer); - -/*! @brief Returns the user pointer of the specified window. - * - * This function returns the current value of the user-defined pointer of the - * specified window. The initial value is `NULL`. - * - * @param[in] window The window whose pointer to return. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref window_userptr - * @sa @ref glfwSetWindowUserPointer - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window); - -/*! @brief Sets the position callback for the specified window. - * - * This function sets the position callback of the specified window, which is - * called when the window is moved. The callback is provided with the - * position, in screen coordinates, of the upper-left corner of the content - * area of the window. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int xpos, int ypos) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowposfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @remark @wayland This callback will never be called, as there is no way for - * an application to know its global position. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_pos - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindowposfun callback); - -/*! @brief Sets the size callback for the specified window. - * - * This function sets the size callback of the specified window, which is - * called when the window is resized. The callback is provided with the size, - * in screen coordinates, of the content area of the window. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int width, int height) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowsizefun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_size - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter and return value. - * - * @ingroup window - */ -GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwindowsizefun callback); - -/*! @brief Sets the close callback for the specified window. - * - * This function sets the close callback of the specified window, which is - * called when the user attempts to close the window, for example by clicking - * the close widget in the title bar. - * - * The close flag is set before this callback is called, but you can modify it - * at any time with @ref glfwSetWindowShouldClose. - * - * The close callback is not triggered by @ref glfwDestroyWindow. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowclosefun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @remark @macos Selecting Quit from the application menu will trigger the - * close callback for all windows. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_close - * - * @since Added in version 2.5. - * @glfw3 Added window handle parameter and return value. - * - * @ingroup window - */ -GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwindowclosefun callback); - -/*! @brief Sets the refresh callback for the specified window. - * - * This function sets the refresh callback of the specified window, which is - * called when the content area of the window needs to be redrawn, for example - * if the window has been exposed after having been covered by another window. - * - * On compositing window systems such as Aero, Compiz, Aqua or Wayland, where - * the window contents are saved off-screen, this callback may be called only - * very infrequently or never at all. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window); - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowrefreshfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_refresh - * - * @since Added in version 2.5. - * @glfw3 Added window handle parameter and return value. - * - * @ingroup window - */ -GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun callback); - -/*! @brief Sets the focus callback for the specified window. - * - * This function sets the focus callback of the specified window, which is - * called when the window gains or loses input focus. - * - * After the focus callback is called for a window that lost input focus, - * synthetic key and mouse button release events will be generated for all such - * that had been pressed. For more information, see @ref glfwSetKeyCallback - * and @ref glfwSetMouseButtonCallback. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int focused) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowfocusfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_focus - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun callback); - -/*! @brief Sets the iconify callback for the specified window. - * - * This function sets the iconification callback of the specified window, which - * is called when the window is iconified or restored. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int iconified) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowiconifyfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_iconify - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GLFWwindowiconifyfun callback); - -/*! @brief Sets the maximize callback for the specified window. - * - * This function sets the maximization callback of the specified window, which - * is called when the window is maximized or restored. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int maximized) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowmaximizefun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_maximize - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window, GLFWwindowmaximizefun callback); - -/*! @brief Sets the framebuffer resize callback for the specified window. - * - * This function sets the framebuffer resize callback of the specified window, - * which is called when the framebuffer of the specified window is resized. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int width, int height) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWframebuffersizefun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_fbsize - * - * @since Added in version 3.0. - * - * @ingroup window - */ -GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun callback); - -/*! @brief Sets the window content scale callback for the specified window. - * - * This function sets the window content scale callback of the specified window, - * which is called when the content scale of the specified window changes. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, float xscale, float yscale) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWwindowcontentscalefun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref window_scale - * @sa @ref glfwGetWindowContentScale - * - * @since Added in version 3.3. - * - * @ingroup window - */ -GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* window, GLFWwindowcontentscalefun callback); - -/*! @brief Processes all pending events. - * - * This function processes only those events that are already in the event - * queue and then returns immediately. Processing events will cause the window - * and input callbacks associated with those events to be called. - * - * On some platforms, a window move, resize or menu operation will cause event - * processing to block. This is due to how event processing is designed on - * those platforms. You can use the - * [window refresh callback](@ref window_refresh) to redraw the contents of - * your window when necessary during such operations. - * - * Do not assume that callbacks you set will _only_ be called in response to - * event processing functions like this one. While it is necessary to poll for - * events, window systems that require GLFW to register callbacks of its own - * can pass events to GLFW in response to many window system function calls. - * GLFW will pass those events on to the application callbacks before - * returning. - * - * Event processing is not required for joystick input to work. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @reentrancy This function must not be called from a callback. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref events - * @sa @ref glfwWaitEvents - * @sa @ref glfwWaitEventsTimeout - * - * @since Added in version 1.0. - * - * @ingroup window - */ -GLFWAPI void glfwPollEvents(void); - -/*! @brief Waits until events are queued and processes them. - * - * This function puts the calling thread to sleep until at least one event is - * available in the event queue. Once one or more events are available, - * it behaves exactly like @ref glfwPollEvents, i.e. the events in the queue - * are processed and the function then returns immediately. Processing events - * will cause the window and input callbacks associated with those events to be - * called. - * - * Since not all events are associated with callbacks, this function may return - * without a callback having been called even if you are monitoring all - * callbacks. - * - * On some platforms, a window move, resize or menu operation will cause event - * processing to block. This is due to how event processing is designed on - * those platforms. You can use the - * [window refresh callback](@ref window_refresh) to redraw the contents of - * your window when necessary during such operations. - * - * Do not assume that callbacks you set will _only_ be called in response to - * event processing functions like this one. While it is necessary to poll for - * events, window systems that require GLFW to register callbacks of its own - * can pass events to GLFW in response to many window system function calls. - * GLFW will pass those events on to the application callbacks before - * returning. - * - * Event processing is not required for joystick input to work. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @reentrancy This function must not be called from a callback. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref events - * @sa @ref glfwPollEvents - * @sa @ref glfwWaitEventsTimeout - * - * @since Added in version 2.5. - * - * @ingroup window - */ -GLFWAPI void glfwWaitEvents(void); - -/*! @brief Waits with timeout until events are queued and processes them. - * - * This function puts the calling thread to sleep until at least one event is - * available in the event queue, or until the specified timeout is reached. If - * one or more events are available, it behaves exactly like @ref - * glfwPollEvents, i.e. the events in the queue are processed and the function - * then returns immediately. Processing events will cause the window and input - * callbacks associated with those events to be called. - * - * The timeout value must be a positive finite number. - * - * Since not all events are associated with callbacks, this function may return - * without a callback having been called even if you are monitoring all - * callbacks. - * - * On some platforms, a window move, resize or menu operation will cause event - * processing to block. This is due to how event processing is designed on - * those platforms. You can use the - * [window refresh callback](@ref window_refresh) to redraw the contents of - * your window when necessary during such operations. - * - * Do not assume that callbacks you set will _only_ be called in response to - * event processing functions like this one. While it is necessary to poll for - * events, window systems that require GLFW to register callbacks of its own - * can pass events to GLFW in response to many window system function calls. - * GLFW will pass those events on to the application callbacks before - * returning. - * - * Event processing is not required for joystick input to work. - * - * @param[in] timeout The maximum amount of time, in seconds, to wait. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. - * - * @reentrancy This function must not be called from a callback. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref events - * @sa @ref glfwPollEvents - * @sa @ref glfwWaitEvents - * - * @since Added in version 3.2. - * - * @ingroup window - */ -GLFWAPI void glfwWaitEventsTimeout(double timeout); - -/*! @brief Posts an empty event to the event queue. - * - * This function posts an empty event from the current thread to the event - * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref events - * @sa @ref glfwWaitEvents - * @sa @ref glfwWaitEventsTimeout - * - * @since Added in version 3.1. - * - * @ingroup window - */ -GLFWAPI void glfwPostEmptyEvent(void); - -/*! @brief Returns the value of an input option for the specified window. - * - * This function returns the value of an input option for the specified window. - * The mode must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, - * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or - * @ref GLFW_RAW_MOUSE_MOTION. - * - * @param[in] window The window to query. - * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or - * `GLFW_RAW_MOUSE_MOTION`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref glfwSetInputMode - * - * @since Added in version 3.0. - * - * @ingroup input - */ -GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode); - -/*! @brief Sets an input option for the specified window. - * - * This function sets an input mode option for the specified window. The mode - * must be one of @ref GLFW_CURSOR, @ref GLFW_STICKY_KEYS, - * @ref GLFW_STICKY_MOUSE_BUTTONS, @ref GLFW_LOCK_KEY_MODS or - * @ref GLFW_RAW_MOUSE_MOTION. - * - * If the mode is `GLFW_CURSOR`, the value must be one of the following cursor - * modes: - * - `GLFW_CURSOR_NORMAL` makes the cursor visible and behaving normally. - * - `GLFW_CURSOR_HIDDEN` makes the cursor invisible when it is over the - * content area of the window but does not restrict the cursor from leaving. - * - `GLFW_CURSOR_DISABLED` hides and grabs the cursor, providing virtual - * and unlimited cursor movement. This is useful for implementing for - * example 3D camera controls. - * - `GLFW_CURSOR_CAPTURED` makes the cursor visible and confines it to the - * content area of the window. - * - * If the mode is `GLFW_STICKY_KEYS`, the value must be either `GLFW_TRUE` to - * enable sticky keys, or `GLFW_FALSE` to disable it. If sticky keys are - * enabled, a key press will ensure that @ref glfwGetKey returns `GLFW_PRESS` - * the next time it is called even if the key had been released before the - * call. This is useful when you are only interested in whether keys have been - * pressed but not when or in which order. - * - * If the mode is `GLFW_STICKY_MOUSE_BUTTONS`, the value must be either - * `GLFW_TRUE` to enable sticky mouse buttons, or `GLFW_FALSE` to disable it. - * If sticky mouse buttons are enabled, a mouse button press will ensure that - * @ref glfwGetMouseButton returns `GLFW_PRESS` the next time it is called even - * if the mouse button had been released before the call. This is useful when - * you are only interested in whether mouse buttons have been pressed but not - * when or in which order. - * - * If the mode is `GLFW_LOCK_KEY_MODS`, the value must be either `GLFW_TRUE` to - * enable lock key modifier bits, or `GLFW_FALSE` to disable them. If enabled, - * callbacks that receive modifier bits will also have the @ref - * GLFW_MOD_CAPS_LOCK bit set when the event was generated with Caps Lock on, - * and the @ref GLFW_MOD_NUM_LOCK bit when Num Lock was on. - * - * If the mode is `GLFW_RAW_MOUSE_MOTION`, the value must be either `GLFW_TRUE` - * to enable raw (unscaled and unaccelerated) mouse motion when the cursor is - * disabled, or `GLFW_FALSE` to disable it. If raw motion is not supported, - * attempting to set this will emit @ref GLFW_FEATURE_UNAVAILABLE. Call @ref - * glfwRawMouseMotionSupported to check for support. - * - * @param[in] window The window whose input mode to set. - * @param[in] mode One of `GLFW_CURSOR`, `GLFW_STICKY_KEYS`, - * `GLFW_STICKY_MOUSE_BUTTONS`, `GLFW_LOCK_KEY_MODS` or - * `GLFW_RAW_MOUSE_MOTION`. - * @param[in] value The new value of the specified input mode. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM, @ref GLFW_PLATFORM_ERROR and @ref - * GLFW_FEATURE_UNAVAILABLE (see above). - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref glfwGetInputMode - * - * @since Added in version 3.0. Replaces `glfwEnable` and `glfwDisable`. - * - * @ingroup input - */ -GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value); - -/*! @brief Returns whether raw mouse motion is supported. - * - * This function returns whether raw mouse motion is supported on the current - * system. This status does not change after GLFW has been initialized so you - * only need to check this once. If you attempt to enable raw motion on - * a system that does not support it, @ref GLFW_PLATFORM_ERROR will be emitted. - * - * Raw mouse motion is closer to the actual motion of the mouse across - * a surface. It is not affected by the scaling and acceleration applied to - * the motion of the desktop cursor. That processing is suitable for a cursor - * while raw motion is better for controlling for example a 3D camera. Because - * of this, raw mouse motion is only provided when the cursor is disabled. - * - * @return `GLFW_TRUE` if raw mouse motion is supported on the current machine, - * or `GLFW_FALSE` otherwise. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref raw_mouse_motion - * @sa @ref glfwSetInputMode - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI int glfwRawMouseMotionSupported(void); - -/*! @brief Returns the layout-specific name of the specified printable key. - * - * This function returns the name of the specified printable key, encoded as - * UTF-8. This is typically the character that key would produce without any - * modifier keys, intended for displaying key bindings to the user. For dead - * keys, it is typically the diacritic it would add to a character. - * - * __Do not use this function__ for [text input](@ref input_char). You will - * break text input for many languages even if it happens to work for yours. - * - * If the key is `GLFW_KEY_UNKNOWN`, the scancode is used to identify the key, - * otherwise the scancode is ignored. If you specify a non-printable key, or - * `GLFW_KEY_UNKNOWN` and a scancode that maps to a non-printable key, this - * function returns `NULL` but does not emit an error. - * - * This behavior allows you to always pass in the arguments in the - * [key callback](@ref input_key) without modification. - * - * The printable keys are: - * - `GLFW_KEY_APOSTROPHE` - * - `GLFW_KEY_COMMA` - * - `GLFW_KEY_MINUS` - * - `GLFW_KEY_PERIOD` - * - `GLFW_KEY_SLASH` - * - `GLFW_KEY_SEMICOLON` - * - `GLFW_KEY_EQUAL` - * - `GLFW_KEY_LEFT_BRACKET` - * - `GLFW_KEY_RIGHT_BRACKET` - * - `GLFW_KEY_BACKSLASH` - * - `GLFW_KEY_WORLD_1` - * - `GLFW_KEY_WORLD_2` - * - `GLFW_KEY_0` to `GLFW_KEY_9` - * - `GLFW_KEY_A` to `GLFW_KEY_Z` - * - `GLFW_KEY_KP_0` to `GLFW_KEY_KP_9` - * - `GLFW_KEY_KP_DECIMAL` - * - `GLFW_KEY_KP_DIVIDE` - * - `GLFW_KEY_KP_MULTIPLY` - * - `GLFW_KEY_KP_SUBTRACT` - * - `GLFW_KEY_KP_ADD` - * - `GLFW_KEY_KP_EQUAL` - * - * Names for printable keys depend on keyboard layout, while names for - * non-printable keys are the same across layouts but depend on the application - * language and should be localized along with other user interface text. - * - * @param[in] key The key to query, or `GLFW_KEY_UNKNOWN`. - * @param[in] scancode The scancode of the key to query. - * @return The UTF-8 encoded, layout-specific name of the key, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE, @ref GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @remark The contents of the returned string may change when a keyboard - * layout change event is received. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref input_key_name - * - * @since Added in version 3.2. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetKeyName(int key, int scancode); - -/*! @brief Returns the platform-specific scancode of the specified key. - * - * This function returns the platform-specific scancode of the specified key. - * - * If the specified [key token](@ref keys) corresponds to a physical key not - * supported on the current platform then this method will return `-1`. - * Calling this function with anything other than a key token will return `-1` - * and generate a @ref GLFW_INVALID_ENUM error. - * - * @param[in] key Any [key token](@ref keys). - * @return The platform-specific scancode for the key, or `-1` if the key is - * not supported on the current platform or an [error](@ref error_handling) - * occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref input_key - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI int glfwGetKeyScancode(int key); - -/*! @brief Returns the last reported state of a keyboard key for the specified - * window. - * - * This function returns the last state reported for the specified key to the - * specified window. The returned state is one of `GLFW_PRESS` or - * `GLFW_RELEASE`. The action `GLFW_REPEAT` is only reported to the key callback. - * - * If the @ref GLFW_STICKY_KEYS input mode is enabled, this function returns - * `GLFW_PRESS` the first time you call it for a key that was pressed, even if - * that key has already been released. - * - * The key functions deal with physical keys, with [key tokens](@ref keys) - * named after their use on the standard US keyboard layout. If you want to - * input text, use the Unicode character callback instead. - * - * The [modifier key bit masks](@ref mods) are not key tokens and cannot be - * used with this function. - * - * __Do not use this function__ to implement [text input](@ref input_char). - * - * @param[in] window The desired window. - * @param[in] key The desired [keyboard key](@ref keys). `GLFW_KEY_UNKNOWN` is - * not a valid key for this function. - * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref input_key - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup input - */ -GLFWAPI int glfwGetKey(GLFWwindow* window, int key); - -/*! @brief Returns the last reported state of a mouse button for the specified - * window. - * - * This function returns the last state reported for the specified mouse button - * to the specified window. The returned state is one of `GLFW_PRESS` or - * `GLFW_RELEASE`. - * - * If the @ref GLFW_STICKY_MOUSE_BUTTONS input mode is enabled, this function - * returns `GLFW_PRESS` the first time you call it for a mouse button that was - * pressed, even if that mouse button has already been released. - * - * @param[in] window The desired window. - * @param[in] button The desired [mouse button](@ref buttons). - * @return One of `GLFW_PRESS` or `GLFW_RELEASE`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref input_mouse_button - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup input - */ -GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button); - -/*! @brief Retrieves the position of the cursor relative to the content area of - * the window. - * - * This function returns the position of the cursor, in screen coordinates, - * relative to the upper-left corner of the content area of the specified - * window. - * - * If the cursor is disabled (with `GLFW_CURSOR_DISABLED`) then the cursor - * position is unbounded and limited only by the minimum and maximum values of - * a `double`. - * - * The coordinate can be converted to their integer equivalents with the - * `floor` function. Casting directly to an integer type works for positive - * coordinates, but fails for negative ones. - * - * Any or all of the position arguments may be `NULL`. If an error occurs, all - * non-`NULL` position arguments will be set to zero. - * - * @param[in] window The desired window. - * @param[out] xpos Where to store the cursor x-coordinate, relative to the - * left edge of the content area, or `NULL`. - * @param[out] ypos Where to store the cursor y-coordinate, relative to the to - * top edge of the content area, or `NULL`. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_pos - * @sa @ref glfwSetCursorPos - * - * @since Added in version 3.0. Replaces `glfwGetMousePos`. - * - * @ingroup input - */ -GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos); - -/*! @brief Sets the position of the cursor, relative to the content area of the - * window. - * - * This function sets the position, in screen coordinates, of the cursor - * relative to the upper-left corner of the content area of the specified - * window. The window must have input focus. If the window does not have - * input focus when this function is called, it fails silently. - * - * __Do not use this function__ to implement things like camera controls. GLFW - * already provides the `GLFW_CURSOR_DISABLED` cursor mode that hides the - * cursor, transparently re-centers it and provides unconstrained cursor - * motion. See @ref glfwSetInputMode for more information. - * - * If the cursor mode is `GLFW_CURSOR_DISABLED` then the cursor position is - * unconstrained and limited only by the minimum and maximum values of - * a `double`. - * - * @param[in] window The desired window. - * @param[in] xpos The desired x-coordinate, relative to the left edge of the - * content area. - * @param[in] ypos The desired y-coordinate, relative to the top edge of the - * content area. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). - * - * @remark @wayland This function will only work when the cursor mode is - * `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_pos - * @sa @ref glfwGetCursorPos - * - * @since Added in version 3.0. Replaces `glfwSetMousePos`. - * - * @ingroup input - */ -GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos); - -/*! @brief Creates a custom cursor. - * - * Creates a new custom cursor image that can be set for a window with @ref - * glfwSetCursor. The cursor can be destroyed with @ref glfwDestroyCursor. - * Any remaining cursors are destroyed by @ref glfwTerminate. - * - * The pixels are 32-bit, little-endian, non-premultiplied RGBA, i.e. eight - * bits per channel with the red channel first. They are arranged canonically - * as packed sequential rows, starting from the top-left corner. - * - * The cursor hotspot is specified in pixels, relative to the upper-left corner - * of the cursor image. Like all other coordinate systems in GLFW, the X-axis - * points to the right and the Y-axis points down. - * - * @param[in] image The desired cursor image. - * @param[in] xhot The desired x-coordinate, in pixels, of the cursor hotspot. - * @param[in] yhot The desired y-coordinate, in pixels, of the cursor hotspot. - * @return The handle of the created cursor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The specified image data is copied before this function - * returns. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_object - * @sa @ref glfwDestroyCursor - * @sa @ref glfwCreateStandardCursor - * - * @since Added in version 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); - -/*! @brief Creates a cursor with a standard shape. - * - * Returns a cursor with a standard shape, that can be set for a window with - * @ref glfwSetCursor. The images for these cursors come from the system - * cursor theme and their exact appearance will vary between platforms. - * - * Most of these shapes are guaranteed to exist on every supported platform but - * a few may not be present. See the table below for details. - * - * Cursor shape | Windows | macOS | X11 | Wayland - * ------------------------------ | ------- | ----- | ------ | ------- - * @ref GLFW_ARROW_CURSOR | Yes | Yes | Yes | Yes - * @ref GLFW_IBEAM_CURSOR | Yes | Yes | Yes | Yes - * @ref GLFW_CROSSHAIR_CURSOR | Yes | Yes | Yes | Yes - * @ref GLFW_POINTING_HAND_CURSOR | Yes | Yes | Yes | Yes - * @ref GLFW_RESIZE_EW_CURSOR | Yes | Yes | Yes | Yes - * @ref GLFW_RESIZE_NS_CURSOR | Yes | Yes | Yes | Yes - * @ref GLFW_RESIZE_NWSE_CURSOR | Yes | Yes1 | Maybe2 | Maybe2 - * @ref GLFW_RESIZE_NESW_CURSOR | Yes | Yes1 | Maybe2 | Maybe2 - * @ref GLFW_RESIZE_ALL_CURSOR | Yes | Yes | Yes | Yes - * @ref GLFW_NOT_ALLOWED_CURSOR | Yes | Yes | Maybe2 | Maybe2 - * - * 1) This uses a private system API and may fail in the future. - * - * 2) This uses a newer standard that not all cursor themes support. - * - * If the requested shape is not available, this function emits a @ref - * GLFW_CURSOR_UNAVAILABLE error and returns `NULL`. - * - * @param[in] shape One of the [standard shapes](@ref shapes). - * @return A new cursor ready to use or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM, @ref GLFW_CURSOR_UNAVAILABLE and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_standard - * @sa @ref glfwCreateCursor - * - * @since Added in version 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape); - -/*! @brief Destroys a cursor. - * - * This function destroys a cursor previously created with @ref - * glfwCreateCursor. Any remaining cursors will be destroyed by @ref - * glfwTerminate. - * - * If the specified cursor is current for any window, that window will be - * reverted to the default cursor. This does not affect the cursor mode. - * - * @param[in] cursor The cursor object to destroy. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @reentrancy This function must not be called from a callback. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_object - * @sa @ref glfwCreateCursor - * - * @since Added in version 3.1. - * - * @ingroup input - */ -GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor); - -/*! @brief Sets the cursor for the window. - * - * This function sets the cursor image to be used when the cursor is over the - * content area of the specified window. The set cursor will only be visible - * when the [cursor mode](@ref cursor_mode) of the window is - * `GLFW_CURSOR_NORMAL`. - * - * On some platforms, the set cursor may not be visible unless the window also - * has input focus. - * - * @param[in] window The window to set the cursor for. - * @param[in] cursor The cursor to set, or `NULL` to switch back to the default - * arrow cursor. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_object - * - * @since Added in version 3.1. - * - * @ingroup input - */ -GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor); - -/*! @brief Sets the key callback. - * - * This function sets the key callback of the specified window, which is called - * when a key is pressed, repeated or released. - * - * The key functions deal with physical keys, with layout independent - * [key tokens](@ref keys) named after their values in the standard US keyboard - * layout. If you want to input text, use the - * [character callback](@ref glfwSetCharCallback) instead. - * - * When a window loses input focus, it will generate synthetic key release - * events for all pressed keys with associated key tokens. You can tell these - * events from user-generated events by the fact that the synthetic ones are - * generated after the focus loss event has been processed, i.e. after the - * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. - * - * The scancode of a key is specific to that platform or sometimes even to that - * machine. Scancodes are intended to allow users to bind keys that don't have - * a GLFW key token. Such keys have `key` set to `GLFW_KEY_UNKNOWN`, their - * state is not saved and so it cannot be queried with @ref glfwGetKey. - * - * Sometimes GLFW needs to generate synthetic key events, in which case the - * scancode may be zero. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new key callback, or `NULL` to remove the currently - * set callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int key, int scancode, int action, int mods) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWkeyfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref input_key - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter and return value. - * - * @ingroup input - */ -GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback); - -/*! @brief Sets the Unicode character callback. - * - * This function sets the character callback of the specified window, which is - * called when a Unicode character is input. - * - * The character callback is intended for Unicode text input. As it deals with - * characters, it is keyboard layout dependent, whereas the - * [key callback](@ref glfwSetKeyCallback) is not. Characters do not map 1:1 - * to physical keys, as a key may produce zero, one or more characters. If you - * want to know whether a specific physical key was pressed or released, see - * the key callback instead. - * - * The character callback behaves as system text input normally does and will - * not be called if modifier keys are held down that would prevent normal text - * input on that platform, for example a Super (Command) key on macOS or Alt key - * on Windows. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, unsigned int codepoint) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWcharfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref input_char - * - * @since Added in version 2.4. - * @glfw3 Added window handle parameter and return value. - * - * @ingroup input - */ -GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun callback); - -/*! @brief Sets the Unicode character with modifiers callback. - * - * This function sets the character with modifiers callback of the specified - * window, which is called when a Unicode character is input regardless of what - * modifier keys are used. - * - * The character with modifiers callback is intended for implementing custom - * Unicode character input. For regular Unicode text input, see the - * [character callback](@ref glfwSetCharCallback). Like the character - * callback, the character with modifiers callback deals with characters and is - * keyboard layout dependent. Characters do not map 1:1 to physical keys, as - * a key may produce zero, one or more characters. If you want to know whether - * a specific physical key was pressed or released, see the - * [key callback](@ref glfwSetKeyCallback) instead. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or an - * [error](@ref error_handling) occurred. - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, unsigned int codepoint, int mods) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWcharmodsfun). - * - * @deprecated Scheduled for removal in version 4.0. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref input_char - * - * @since Added in version 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmodsfun callback); - -/*! @brief Sets the mouse button callback. - * - * This function sets the mouse button callback of the specified window, which - * is called when a mouse button is pressed or released. - * - * When a window loses input focus, it will generate synthetic mouse button - * release events for all pressed mouse buttons. You can tell these events - * from user-generated events by the fact that the synthetic ones are generated - * after the focus loss event has been processed, i.e. after the - * [window focus callback](@ref glfwSetWindowFocusCallback) has been called. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int button, int action, int mods) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWmousebuttonfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref input_mouse_button - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter and return value. - * - * @ingroup input - */ -GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmousebuttonfun callback); - -/*! @brief Sets the cursor position callback. - * - * This function sets the cursor position callback of the specified window, - * which is called when the cursor is moved. The callback is provided with the - * position, in screen coordinates, relative to the upper-left corner of the - * content area of the window. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, double xpos, double ypos); - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWcursorposfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_pos - * - * @since Added in version 3.0. Replaces `glfwSetMousePosCallback`. - * - * @ingroup input - */ -GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursorposfun callback); - -/*! @brief Sets the cursor enter/leave callback. - * - * This function sets the cursor boundary crossing callback of the specified - * window, which is called when the cursor enters or leaves the content area of - * the window. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int entered) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWcursorenterfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref cursor_enter - * - * @since Added in version 3.0. - * - * @ingroup input - */ -GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcursorenterfun callback); - -/*! @brief Sets the scroll callback. - * - * This function sets the scroll callback of the specified window, which is - * called when a scrolling device is used, such as a mouse wheel or scrolling - * area of a touchpad. - * - * The scroll callback receives all scrolling input, like that from a mouse - * wheel or a touchpad scrolling area. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new scroll callback, or `NULL` to remove the - * currently set callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, double xoffset, double yoffset) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWscrollfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref scrolling - * - * @since Added in version 3.0. Replaces `glfwSetMouseWheelCallback`. - * - * @ingroup input - */ -GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun callback); - -/*! @brief Sets the path drop callback. - * - * This function sets the path drop callback of the specified window, which is - * called when one or more dragged paths are dropped on the window. - * - * Because the path array and its strings may have been generated specifically - * for that event, they are not guaranteed to be valid after the callback has - * returned. If you wish to use them after the callback returns, you need to - * make a deep copy. - * - * @param[in] window The window whose callback to set. - * @param[in] callback The new file drop callback, or `NULL` to remove the - * currently set callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(GLFWwindow* window, int path_count, const char* paths[]) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWdropfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref path_drop - * - * @since Added in version 3.1. - * - * @ingroup input - */ -GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun callback); - -/*! @brief Returns whether the specified joystick is present. - * - * This function returns whether the specified joystick is present. - * - * There is no need to call this function before other functions that accept - * a joystick ID, as they all check for presence before performing any other - * work. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref joystick - * - * @since Added in version 3.0. Replaces `glfwGetJoystickParam`. - * - * @ingroup input - */ -GLFWAPI int glfwJoystickPresent(int jid); - -/*! @brief Returns the values of all axes of the specified joystick. - * - * This function returns the values of all axes of the specified joystick. - * Each element in the array is a value between -1.0 and 1.0. - * - * If the specified joystick is not present this function will return `NULL` - * but will not generate an error. This can be used instead of first calling - * @ref glfwJoystickPresent. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @param[out] count Where to store the number of axis values in the returned - * array. This is set to zero if the joystick is not present or an error - * occurred. - * @return An array of axis values, or `NULL` if the joystick is not present or - * an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned array is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified joystick is - * disconnected or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref joystick_axis - * - * @since Added in version 3.0. Replaces `glfwGetJoystickPos`. - * - * @ingroup input - */ -GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count); - -/*! @brief Returns the state of all buttons of the specified joystick. - * - * This function returns the state of all buttons of the specified joystick. - * Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`. - * - * For backward compatibility with earlier versions that did not have @ref - * glfwGetJoystickHats, the button array also includes all hats, each - * represented as four buttons. The hats are in the same order as returned by - * __glfwGetJoystickHats__ and are in the order _up_, _right_, _down_ and - * _left_. To disable these extra buttons, set the @ref - * GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization. - * - * If the specified joystick is not present this function will return `NULL` - * but will not generate an error. This can be used instead of first calling - * @ref glfwJoystickPresent. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @param[out] count Where to store the number of button states in the returned - * array. This is set to zero if the joystick is not present or an error - * occurred. - * @return An array of button states, or `NULL` if the joystick is not present - * or an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned array is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified joystick is - * disconnected or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref joystick_button - * - * @since Added in version 2.2. - * @glfw3 Changed to return a dynamic array. - * - * @ingroup input - */ -GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count); - -/*! @brief Returns the state of all hats of the specified joystick. - * - * This function returns the state of all hats of the specified joystick. - * Each element in the array is one of the following values: - * - * Name | Value - * ---- | ----- - * `GLFW_HAT_CENTERED` | 0 - * `GLFW_HAT_UP` | 1 - * `GLFW_HAT_RIGHT` | 2 - * `GLFW_HAT_DOWN` | 4 - * `GLFW_HAT_LEFT` | 8 - * `GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP` - * `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN` - * `GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP` - * `GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN` - * - * The diagonal directions are bitwise combinations of the primary (up, right, - * down and left) directions and you can test for these individually by ANDing - * it with the corresponding direction. - * - * @code - * if (hats[2] & GLFW_HAT_RIGHT) - * { - * // State of hat 2 could be right-up, right or right-down - * } - * @endcode - * - * If the specified joystick is not present this function will return `NULL` - * but will not generate an error. This can be used instead of first calling - * @ref glfwJoystickPresent. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @param[out] count Where to store the number of hat states in the returned - * array. This is set to zero if the joystick is not present or an error - * occurred. - * @return An array of hat states, or `NULL` if the joystick is not present - * or an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned array is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified joystick is - * disconnected, this function is called again for that joystick or the library - * is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref joystick_hat - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count); - -/*! @brief Returns the name of the specified joystick. - * - * This function returns the name, encoded as UTF-8, of the specified joystick. - * The returned string is allocated and freed by GLFW. You should not free it - * yourself. - * - * If the specified joystick is not present this function will return `NULL` - * but will not generate an error. This can be used instead of first calling - * @ref glfwJoystickPresent. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick - * is not present or an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified joystick is - * disconnected or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref joystick_name - * - * @since Added in version 3.0. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetJoystickName(int jid); - -/*! @brief Returns the SDL compatible GUID of the specified joystick. - * - * This function returns the SDL compatible GUID, as a UTF-8 encoded - * hexadecimal string, of the specified joystick. The returned string is - * allocated and freed by GLFW. You should not free it yourself. - * - * The GUID is what connects a joystick to a gamepad mapping. A connected - * joystick will always have a GUID even if there is no gamepad mapping - * assigned to it. - * - * If the specified joystick is not present this function will return `NULL` - * but will not generate an error. This can be used instead of first calling - * @ref glfwJoystickPresent. - * - * The GUID uses the format introduced in SDL 2.0.5. This GUID tries to - * uniquely identify the make and model of a joystick but does not identify - * a specific unit, e.g. all wired Xbox 360 controllers will have the same - * GUID on that platform. The GUID for a unit may vary between platforms - * depending on what hardware information the platform specific APIs provide. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @return The UTF-8 encoded GUID of the joystick, or `NULL` if the joystick - * is not present or an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified joystick is - * disconnected or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref gamepad - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetJoystickGUID(int jid); - -/*! @brief Sets the user pointer of the specified joystick. - * - * This function sets the user-defined pointer of the specified joystick. The - * current value is retained until the joystick is disconnected. The initial - * value is `NULL`. - * - * This function may be called from the joystick callback, even for a joystick - * that is being disconnected. - * - * @param[in] jid The joystick whose pointer to set. - * @param[in] pointer The new value. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref joystick_userptr - * @sa @ref glfwGetJoystickUserPointer - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer); - -/*! @brief Returns the user pointer of the specified joystick. - * - * This function returns the current value of the user-defined pointer of the - * specified joystick. The initial value is `NULL`. - * - * This function may be called from the joystick callback, even for a joystick - * that is being disconnected. - * - * @param[in] jid The joystick whose pointer to return. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @sa @ref joystick_userptr - * @sa @ref glfwSetJoystickUserPointer - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI void* glfwGetJoystickUserPointer(int jid); - -/*! @brief Returns whether the specified joystick has a gamepad mapping. - * - * This function returns whether the specified joystick is both present and has - * a gamepad mapping. - * - * If the specified joystick is present but does not have a gamepad mapping - * this function will return `GLFW_FALSE` but will not generate an error. Call - * @ref glfwJoystickPresent to check if a joystick is present regardless of - * whether it has a mapping. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping, - * or `GLFW_FALSE` otherwise. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref gamepad - * @sa @ref glfwGetGamepadState - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI int glfwJoystickIsGamepad(int jid); - -/*! @brief Sets the joystick configuration callback. - * - * This function sets the joystick configuration callback, or removes the - * currently set callback. This is called when a joystick is connected to or - * disconnected from the system. - * - * For joystick connection and disconnection events to be delivered on all - * platforms, you need to call one of the [event processing](@ref events) - * functions. Joystick disconnection may also be detected and the callback - * called by joystick functions. The function will then return whatever it - * returns if the joystick is not present. - * - * @param[in] callback The new callback, or `NULL` to remove the currently set - * callback. - * @return The previously set callback, or `NULL` if no callback was set or the - * library had not been [initialized](@ref intro_init). - * - * @callback_signature - * @code - * void function_name(int jid, int event) - * @endcode - * For more information about the callback parameters, see the - * [function pointer type](@ref GLFWjoystickfun). - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref joystick_event - * - * @since Added in version 3.2. - * - * @ingroup input - */ -GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback); - -/*! @brief Adds the specified SDL_GameControllerDB gamepad mappings. - * - * This function parses the specified ASCII encoded string and updates the - * internal list with any gamepad mappings it finds. This string may - * contain either a single gamepad mapping or many mappings separated by - * newlines. The parser supports the full format of the `gamecontrollerdb.txt` - * source file including empty lines and comments. - * - * See @ref gamepad_mapping for a description of the format. - * - * If there is already a gamepad mapping for a given GUID in the internal list, - * it will be replaced by the one passed to this function. If the library is - * terminated and re-initialized the internal list will revert to the built-in - * default. - * - * @param[in] string The string containing the gamepad mappings. - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_VALUE. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref gamepad - * @sa @ref glfwJoystickIsGamepad - * @sa @ref glfwGetGamepadName - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI int glfwUpdateGamepadMappings(const char* string); - -/*! @brief Returns the human-readable gamepad name for the specified joystick. - * - * This function returns the human-readable name of the gamepad from the - * gamepad mapping assigned to the specified joystick. - * - * If the specified joystick is not present or does not have a gamepad mapping - * this function will return `NULL` but will not generate an error. Call - * @ref glfwJoystickPresent to check whether it is present regardless of - * whether it has a mapping. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @return The UTF-8 encoded name of the gamepad, or `NULL` if the - * joystick is not present, does not have a mapping or an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the specified joystick is - * disconnected, the gamepad mappings are updated or the library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref gamepad - * @sa @ref glfwJoystickIsGamepad - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetGamepadName(int jid); - -/*! @brief Retrieves the state of the specified joystick remapped as a gamepad. - * - * This function retrieves the state of the specified joystick remapped to - * an Xbox-like gamepad. - * - * If the specified joystick is not present or does not have a gamepad mapping - * this function will return `GLFW_FALSE` but will not generate an error. Call - * @ref glfwJoystickPresent to check whether it is present regardless of - * whether it has a mapping. - * - * The Guide button may not be available for input as it is often hooked by the - * system or the Steam client. - * - * Not all devices have all the buttons or axes provided by @ref - * GLFWgamepadstate. Unavailable buttons and axes will always report - * `GLFW_RELEASE` and 0.0 respectively. - * - * @param[in] jid The [joystick](@ref joysticks) to query. - * @param[out] state The gamepad input state of the joystick. - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is - * connected, it has no gamepad mapping or an [error](@ref error_handling) - * occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_ENUM. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref gamepad - * @sa @ref glfwUpdateGamepadMappings - * @sa @ref glfwJoystickIsGamepad - * - * @since Added in version 3.3. - * - * @ingroup input - */ -GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state); - -/*! @brief Sets the clipboard to the specified string. - * - * This function sets the system clipboard to the specified, UTF-8 encoded - * string. - * - * @param[in] window Deprecated. Any valid window or `NULL`. - * @param[in] string A UTF-8 encoded string. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_ERROR. - * - * @remark @win32 The clipboard on Windows has a single global lock for reading and - * writing. GLFW tries to acquire it a few times, which is almost always enough. If it - * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. - * It is safe to try this multiple times. - * - * @pointer_lifetime The specified string is copied before this function - * returns. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref clipboard - * @sa @ref glfwGetClipboardString - * - * @since Added in version 3.0. - * - * @ingroup input - */ -GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string); - -/*! @brief Returns the contents of the clipboard as a string. - * - * This function returns the contents of the system clipboard, if it contains - * or is convertible to a UTF-8 encoded string. If the clipboard is empty or - * if its contents cannot be converted, `NULL` is returned and a @ref - * GLFW_FORMAT_UNAVAILABLE error is generated. - * - * @param[in] window Deprecated. Any valid window or `NULL`. - * @return The contents of the clipboard as a UTF-8 encoded string, or `NULL` - * if an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. - * - * @remark @win32 The clipboard on Windows has a single global lock for reading and - * writing. GLFW tries to acquire it a few times, which is almost always enough. If it - * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. - * It is safe to try this multiple times. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the next call to @ref - * glfwGetClipboardString or @ref glfwSetClipboardString, or until the library - * is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref clipboard - * @sa @ref glfwSetClipboardString - * - * @since Added in version 3.0. - * - * @ingroup input - */ -GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window); - -/*! @brief Returns the GLFW time. - * - * This function returns the current GLFW time, in seconds. Unless the time - * has been set using @ref glfwSetTime it measures time elapsed since GLFW was - * initialized. - * - * This function and @ref glfwSetTime are helper functions on top of @ref - * glfwGetTimerFrequency and @ref glfwGetTimerValue. - * - * The resolution of the timer is system dependent, but is usually on the order - * of a few micro- or nanoseconds. It uses the highest-resolution monotonic - * time source on each operating system. - * - * @return The current time, in seconds, or zero if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. Reading and - * writing of the internal base time is not atomic, so it needs to be - * externally synchronized with calls to @ref glfwSetTime. - * - * @sa @ref time - * - * @since Added in version 1.0. - * - * @ingroup input - */ -GLFWAPI double glfwGetTime(void); - -/*! @brief Sets the GLFW time. - * - * This function sets the current GLFW time, in seconds. The value must be - * a positive finite number less than or equal to 18446744073.0, which is - * approximately 584.5 years. - * - * This function and @ref glfwGetTime are helper functions on top of @ref - * glfwGetTimerFrequency and @ref glfwGetTimerValue. - * - * @param[in] time The new value, in seconds. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_INVALID_VALUE. - * - * @remark The upper limit of GLFW time is calculated as - * floor((264 - 1) / 109) and is due to implementations - * storing nanoseconds in 64 bits. The limit may be increased in the future. - * - * @thread_safety This function may be called from any thread. Reading and - * writing of the internal base time is not atomic, so it needs to be - * externally synchronized with calls to @ref glfwGetTime. - * - * @sa @ref time - * - * @since Added in version 2.2. - * - * @ingroup input - */ -GLFWAPI void glfwSetTime(double time); - -/*! @brief Returns the current value of the raw timer. - * - * This function returns the current value of the raw timer, measured in - * 1 / frequency seconds. To get the frequency, call @ref - * glfwGetTimerFrequency. - * - * @return The value of the timer, or zero if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref time - * @sa @ref glfwGetTimerFrequency - * - * @since Added in version 3.2. - * - * @ingroup input - */ -GLFWAPI uint64_t glfwGetTimerValue(void); - -/*! @brief Returns the frequency, in Hz, of the raw timer. - * - * This function returns the frequency, in Hz, of the raw timer. - * - * @return The frequency of the timer, in Hz, or zero if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref time - * @sa @ref glfwGetTimerValue - * - * @since Added in version 3.2. - * - * @ingroup input - */ -GLFWAPI uint64_t glfwGetTimerFrequency(void); - -/*! @brief Makes the context of the specified window current for the calling - * thread. - * - * This function makes the OpenGL or OpenGL ES context of the specified window - * current on the calling thread. It can also detach the current context from - * the calling thread without making a new one current by passing in `NULL`. - * - * A context must only be made current on a single thread at a time and each - * thread can have only a single current context at a time. Making a context - * current detaches any previously current context on the calling thread. - * - * When moving a context between threads, you must detach it (make it - * non-current) on the old thread before making it current on the new one. - * - * By default, making a context non-current implicitly forces a pipeline flush. - * On machines that support `GL_KHR_context_flush_control`, you can control - * whether a context performs this flush by setting the - * [GLFW_CONTEXT_RELEASE_BEHAVIOR](@ref GLFW_CONTEXT_RELEASE_BEHAVIOR_hint) - * hint. - * - * The specified window must have an OpenGL or OpenGL ES context. Specifying - * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT - * error. - * - * @param[in] window The window whose context to make current, or `NULL` to - * detach the current context. - * - * @remarks If the previously current context was created via a different - * context creation API than the one passed to this function, GLFW will still - * detach the previous one from its API before making the new one current. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref context_current - * @sa @ref glfwGetCurrentContext - * - * @since Added in version 3.0. - * - * @ingroup context - */ -GLFWAPI void glfwMakeContextCurrent(GLFWwindow* window); - -/*! @brief Returns the window whose context is current on the calling thread. - * - * This function returns the window whose OpenGL or OpenGL ES context is - * current on the calling thread. - * - * @return The window whose context is current, or `NULL` if no window's - * context is current. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref context_current - * @sa @ref glfwMakeContextCurrent - * - * @since Added in version 3.0. - * - * @ingroup context - */ -GLFWAPI GLFWwindow* glfwGetCurrentContext(void); - -/*! @brief Swaps the front and back buffers of the specified window. - * - * This function swaps the front and back buffers of the specified window when - * rendering with OpenGL or OpenGL ES. If the swap interval is greater than - * zero, the GPU driver waits the specified number of screen updates before - * swapping the buffers. - * - * The specified window must have an OpenGL or OpenGL ES context. Specifying - * a window without a context will generate a @ref GLFW_NO_WINDOW_CONTEXT - * error. - * - * This function does not apply to Vulkan. If you are rendering with Vulkan, - * see `vkQueuePresentKHR` instead. - * - * @param[in] window The window whose buffers to swap. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. - * - * @remark __EGL:__ The context of the specified window must be current on the - * calling thread. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref buffer_swap - * @sa @ref glfwSwapInterval - * - * @since Added in version 1.0. - * @glfw3 Added window handle parameter. - * - * @ingroup window - */ -GLFWAPI void glfwSwapBuffers(GLFWwindow* window); - -/*! @brief Sets the swap interval for the current context. - * - * This function sets the swap interval for the current OpenGL or OpenGL ES - * context, i.e. the number of screen updates to wait from the time @ref - * glfwSwapBuffers was called before swapping the buffers and returning. This - * is sometimes called _vertical synchronization_, _vertical retrace - * synchronization_ or just _vsync_. - * - * A context that supports either of the `WGL_EXT_swap_control_tear` and - * `GLX_EXT_swap_control_tear` extensions also accepts _negative_ swap - * intervals, which allows the driver to swap immediately even if a frame - * arrives a little bit late. You can check for these extensions with @ref - * glfwExtensionSupported. - * - * A context must be current on the calling thread. Calling this function - * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. - * - * This function does not apply to Vulkan. If you are rendering with Vulkan, - * see the present mode of your swapchain instead. - * - * @param[in] interval The minimum number of screen updates to wait for - * until the buffers are swapped by @ref glfwSwapBuffers. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. - * - * @remark This function is not called during context creation, leaving the - * swap interval set to whatever is the default for that API. This is done - * because some swap interval extensions used by GLFW do not allow the swap - * interval to be reset to zero once it has been set to a non-zero value. - * - * @remark Some GPU drivers do not honor the requested swap interval, either - * because of a user setting that overrides the application's request or due to - * bugs in the driver. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref buffer_swap - * @sa @ref glfwSwapBuffers - * - * @since Added in version 1.0. - * - * @ingroup context - */ -GLFWAPI void glfwSwapInterval(int interval); - -/*! @brief Returns whether the specified extension is available. - * - * This function returns whether the specified - * [API extension](@ref context_glext) is supported by the current OpenGL or - * OpenGL ES context. It searches both for client API extension and context - * creation API extensions. - * - * A context must be current on the calling thread. Calling this function - * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. - * - * As this functions retrieves and searches one or more extension strings each - * call, it is recommended that you cache its results if it is going to be used - * frequently. The extension strings will not change during the lifetime of - * a context, so there is no danger in doing this. - * - * This function does not apply to Vulkan. If you are using Vulkan, see @ref - * glfwGetRequiredInstanceExtensions, `vkEnumerateInstanceExtensionProperties` - * and `vkEnumerateDeviceExtensionProperties` instead. - * - * @param[in] extension The ASCII encoded name of the extension. - * @return `GLFW_TRUE` if the extension is available, or `GLFW_FALSE` - * otherwise. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_NO_CURRENT_CONTEXT, @ref GLFW_INVALID_VALUE and @ref - * GLFW_PLATFORM_ERROR. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref context_glext - * @sa @ref glfwGetProcAddress - * - * @since Added in version 1.0. - * - * @ingroup context - */ -GLFWAPI int glfwExtensionSupported(const char* extension); - -/*! @brief Returns the address of the specified function for the current - * context. - * - * This function returns the address of the specified OpenGL or OpenGL ES - * [core or extension function](@ref context_glext), if it is supported - * by the current context. - * - * A context must be current on the calling thread. Calling this function - * without a current context will cause a @ref GLFW_NO_CURRENT_CONTEXT error. - * - * This function does not apply to Vulkan. If you are rendering with Vulkan, - * see @ref glfwGetInstanceProcAddress, `vkGetInstanceProcAddr` and - * `vkGetDeviceProcAddr` instead. - * - * @param[in] procname The ASCII encoded name of the function. - * @return The address of the function, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_NO_CURRENT_CONTEXT and @ref GLFW_PLATFORM_ERROR. - * - * @remark The address of a given function is not guaranteed to be the same - * between contexts. - * - * @remark This function may return a non-`NULL` address despite the - * associated version or extension not being available. Always check the - * context version or extension string first. - * - * @pointer_lifetime The returned function pointer is valid until the context - * is destroyed or the library is terminated. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref context_glext - * @sa @ref glfwExtensionSupported - * - * @since Added in version 1.0. - * - * @ingroup context - */ -GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); - -/*! @brief Returns whether the Vulkan loader and an ICD have been found. - * - * This function returns whether the Vulkan loader and any minimally functional - * ICD have been found. - * - * The availability of a Vulkan loader and even an ICD does not by itself guarantee that - * surface creation or even instance creation is possible. Call @ref - * glfwGetRequiredInstanceExtensions to check whether the extensions necessary for Vulkan - * surface creation are available and @ref glfwGetPhysicalDevicePresentationSupport to - * check whether a queue family of a physical device supports image presentation. - * - * @return `GLFW_TRUE` if Vulkan is minimally available, or `GLFW_FALSE` - * otherwise. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref vulkan_support - * - * @since Added in version 3.2. - * - * @ingroup vulkan - */ -GLFWAPI int glfwVulkanSupported(void); - -/*! @brief Returns the Vulkan instance extensions required by GLFW. - * - * This function returns an array of names of Vulkan instance extensions required - * by GLFW for creating Vulkan surfaces for GLFW windows. If successful, the - * list will always contain `VK_KHR_surface`, so if you don't require any - * additional extensions you can pass this list directly to the - * `VkInstanceCreateInfo` struct. - * - * If Vulkan is not available on the machine, this function returns `NULL` and - * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported - * to check whether Vulkan is at least minimally available. - * - * If Vulkan is available but no set of extensions allowing window surface - * creation was found, this function returns `NULL`. You may still use Vulkan - * for off-screen rendering and compute work. - * - * @param[out] count Where to store the number of extensions in the returned - * array. This is set to zero if an error occurred. - * @return An array of ASCII encoded extension names, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_API_UNAVAILABLE. - * - * @remark Additional extensions may be required by future versions of GLFW. - * You should check if any extensions you wish to enable are already in the - * returned array, as it is an error to specify an extension more than once in - * the `VkInstanceCreateInfo` struct. - * - * @pointer_lifetime The returned array is allocated and freed by GLFW. You - * should not free it yourself. It is guaranteed to be valid only until the - * library is terminated. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref vulkan_ext - * @sa @ref glfwCreateWindowSurface - * - * @since Added in version 3.2. - * - * @ingroup vulkan - */ -GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count); - -#if defined(VK_VERSION_1_0) - -/*! @brief Returns the address of the specified Vulkan instance function. - * - * This function returns the address of the specified Vulkan core or extension - * function for the specified instance. If instance is set to `NULL` it can - * return any function exported from the Vulkan loader, including at least the - * following functions: - * - * - `vkEnumerateInstanceExtensionProperties` - * - `vkEnumerateInstanceLayerProperties` - * - `vkCreateInstance` - * - `vkGetInstanceProcAddr` - * - * If Vulkan is not available on the machine, this function returns `NULL` and - * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported - * to check whether Vulkan is at least minimally available. - * - * This function is equivalent to calling `vkGetInstanceProcAddr` with - * a platform-specific query of the Vulkan loader as a fallback. - * - * @param[in] instance The Vulkan instance to query, or `NULL` to retrieve - * functions related to instance creation. - * @param[in] procname The ASCII encoded name of the function. - * @return The address of the function, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_API_UNAVAILABLE. - * - * @pointer_lifetime The returned function pointer is valid until the library - * is terminated. - * - * @thread_safety This function may be called from any thread. - * - * @sa @ref vulkan_proc - * - * @since Added in version 3.2. - * - * @ingroup vulkan - */ -GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* procname); - -/*! @brief Returns whether the specified queue family can present images. - * - * This function returns whether the specified queue family of the specified - * physical device supports presentation to the platform GLFW was built for. - * - * If Vulkan or the required window surface creation instance extensions are - * not available on the machine, or if the specified instance was not created - * with the required extensions, this function returns `GLFW_FALSE` and - * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported - * to check whether Vulkan is at least minimally available and @ref - * glfwGetRequiredInstanceExtensions to check what instance extensions are - * required. - * - * @param[in] instance The instance that the physical device belongs to. - * @param[in] device The physical device that the queue family belongs to. - * @param[in] queuefamily The index of the queue family to query. - * @return `GLFW_TRUE` if the queue family supports presentation, or - * `GLFW_FALSE` otherwise. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. - * - * @remark @macos This function currently always returns `GLFW_TRUE`, as the - * `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide - * a `vkGetPhysicalDevice*PresentationSupport` type function. - * - * @thread_safety This function may be called from any thread. For - * synchronization details of Vulkan objects, see the Vulkan specification. - * - * @sa @ref vulkan_present - * - * @since Added in version 3.2. - * - * @ingroup vulkan - */ -GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily); - -/*! @brief Creates a Vulkan surface for the specified window. - * - * This function creates a Vulkan surface for the specified window. - * - * If the Vulkan loader or at least one minimally functional ICD were not found, - * this function returns `VK_ERROR_INITIALIZATION_FAILED` and generates a @ref - * GLFW_API_UNAVAILABLE error. Call @ref glfwVulkanSupported to check whether - * Vulkan is at least minimally available. - * - * If the required window surface creation instance extensions are not - * available or if the specified instance was not created with these extensions - * enabled, this function returns `VK_ERROR_EXTENSION_NOT_PRESENT` and - * generates a @ref GLFW_API_UNAVAILABLE error. Call @ref - * glfwGetRequiredInstanceExtensions to check what instance extensions are - * required. - * - * The window surface cannot be shared with another API so the window must - * have been created with the [client api hint](@ref GLFW_CLIENT_API_attrib) - * set to `GLFW_NO_API` otherwise it generates a @ref GLFW_INVALID_VALUE error - * and returns `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`. - * - * The window surface must be destroyed before the specified Vulkan instance. - * It is the responsibility of the caller to destroy the window surface. GLFW - * does not destroy it for you. Call `vkDestroySurfaceKHR` to destroy the - * surface. - * - * @param[in] instance The Vulkan instance to create the surface in. - * @param[in] window The window to create the surface for. - * @param[in] allocator The allocator to use, or `NULL` to use the default - * allocator. - * @param[out] surface Where to store the handle of the surface. This is set - * to `VK_NULL_HANDLE` if an error occurred. - * @return `VK_SUCCESS` if successful, or a Vulkan error code if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_API_UNAVAILABLE, @ref GLFW_PLATFORM_ERROR and @ref GLFW_INVALID_VALUE - * - * @remark If an error occurs before the creation call is made, GLFW returns - * the Vulkan error code most appropriate for the error. Appropriate use of - * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should - * eliminate almost all occurrences of these errors. - * - * @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the - * `VK_MVK_macos_surface` extension as a fallback. The name of the selected - * extension, if any, is included in the array returned by @ref - * glfwGetRequiredInstanceExtensions. - * - * @remark @macos This function creates and sets a `CAMetalLayer` instance for - * the window content view, which is required for MoltenVK to function. - * - * @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension, - * with the `VK_KHR_xlib_surface` extension as a fallback. You can make - * `VK_KHR_xlib_surface` the preferred extension by setting the - * [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init - * hint. The name of the selected extension, if any, is included in the array - * returned by @ref glfwGetRequiredInstanceExtensions. - * - * @thread_safety This function may be called from any thread. For - * synchronization details of Vulkan objects, see the Vulkan specification. - * - * @sa @ref vulkan_surface - * @sa @ref glfwGetRequiredInstanceExtensions - * - * @since Added in version 3.2. - * - * @ingroup vulkan - */ -GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); - -#endif /*VK_VERSION_1_0*/ - - -/************************************************************************* - * Global definition cleanup - *************************************************************************/ - -/* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ - -#ifdef GLFW_WINGDIAPI_DEFINED - #undef WINGDIAPI - #undef GLFW_WINGDIAPI_DEFINED -#endif - -#ifdef GLFW_CALLBACK_DEFINED - #undef CALLBACK - #undef GLFW_CALLBACK_DEFINED -#endif - -/* Some OpenGL related headers need GLAPIENTRY, but it is unconditionally - * defined by some gl.h variants (OpenBSD) so define it after if needed. - */ -#ifndef GLAPIENTRY - #define GLAPIENTRY APIENTRY - #define GLFW_GLAPIENTRY_DEFINED -#endif - -/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _glfw3_h_ */ - diff --git a/vendor/glfw/glfw3native.h b/vendor/glfw/glfw3native.h deleted file mode 100644 index 92f0d32..0000000 --- a/vendor/glfw/glfw3native.h +++ /dev/null @@ -1,663 +0,0 @@ -/************************************************************************* - * GLFW 3.4 - www.glfw.org - * A library for OpenGL, window and input - *------------------------------------------------------------------------ - * Copyright (c) 2002-2006 Marcus Geelnard - * Copyright (c) 2006-2018 Camilla Löwy - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would - * be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not - * be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - * - *************************************************************************/ - -#ifndef _glfw3_native_h_ -#define _glfw3_native_h_ - -#ifdef __cplusplus -extern "C" { -#endif - - -/************************************************************************* - * Doxygen documentation - *************************************************************************/ - -/*! @file glfw3native.h - * @brief The header of the native access functions. - * - * This is the header file of the native access functions. See @ref native for - * more information. - */ -/*! @defgroup native Native access - * @brief Functions related to accessing native handles. - * - * **By using the native access functions you assert that you know what you're - * doing and how to fix problems caused by using them. If you don't, you - * shouldn't be using them.** - * - * Before the inclusion of @ref glfw3native.h, you may define zero or more - * window system API macro and zero or more context creation API macros. - * - * The chosen backends must match those the library was compiled for. Failure - * to do this will cause a link-time error. - * - * The available window API macros are: - * * `GLFW_EXPOSE_NATIVE_WIN32` - * * `GLFW_EXPOSE_NATIVE_COCOA` - * * `GLFW_EXPOSE_NATIVE_X11` - * * `GLFW_EXPOSE_NATIVE_WAYLAND` - * - * The available context API macros are: - * * `GLFW_EXPOSE_NATIVE_WGL` - * * `GLFW_EXPOSE_NATIVE_NSGL` - * * `GLFW_EXPOSE_NATIVE_GLX` - * * `GLFW_EXPOSE_NATIVE_EGL` - * * `GLFW_EXPOSE_NATIVE_OSMESA` - * - * These macros select which of the native access functions that are declared - * and which platform-specific headers to include. It is then up your (by - * definition platform-specific) code to handle which of these should be - * defined. - * - * If you do not want the platform-specific headers to be included, define - * `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header. - * - * @code - * #define GLFW_EXPOSE_NATIVE_WIN32 - * #define GLFW_EXPOSE_NATIVE_WGL - * #define GLFW_NATIVE_INCLUDE_NONE - * #include - * @endcode - */ - - -/************************************************************************* - * System headers and types - *************************************************************************/ - -#if !defined(GLFW_NATIVE_INCLUDE_NONE) - - #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) - /* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for - * example to allow applications to correctly declare a GL_KHR_debug callback) - * but windows.h assumes no one will define APIENTRY before it does - */ - #if defined(GLFW_APIENTRY_DEFINED) - #undef APIENTRY - #undef GLFW_APIENTRY_DEFINED - #endif - #include - #endif - - #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) - #if defined(__OBJC__) - #import - #else - #include - #include - #endif - #endif - - #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) - #include - #include - #endif - - #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) - #include - #endif - - #if defined(GLFW_EXPOSE_NATIVE_WGL) - /* WGL is declared by windows.h */ - #endif - #if defined(GLFW_EXPOSE_NATIVE_NSGL) - /* NSGL is declared by Cocoa.h */ - #endif - #if defined(GLFW_EXPOSE_NATIVE_GLX) - /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by - * default it also acts as an OpenGL header - * However, glx.h will include gl.h, which will define it unconditionally - */ - #if defined(GLFW_GLAPIENTRY_DEFINED) - #undef GLAPIENTRY - #undef GLFW_GLAPIENTRY_DEFINED - #endif - #include - #endif - #if defined(GLFW_EXPOSE_NATIVE_EGL) - #include - #endif - #if defined(GLFW_EXPOSE_NATIVE_OSMESA) - /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by - * default it also acts as an OpenGL header - * However, osmesa.h will include gl.h, which will define it unconditionally - */ - #if defined(GLFW_GLAPIENTRY_DEFINED) - #undef GLAPIENTRY - #undef GLFW_GLAPIENTRY_DEFINED - #endif - #include - #endif - -#endif /*GLFW_NATIVE_INCLUDE_NONE*/ - - -/************************************************************************* - * Functions - *************************************************************************/ - -#if defined(GLFW_EXPOSE_NATIVE_WIN32) -/*! @brief Returns the adapter device name of the specified monitor. - * - * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) - * of the specified monitor, or `NULL` if an [error](@ref error_handling) - * occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.1. - * - * @ingroup native - */ -GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); - -/*! @brief Returns the display device name of the specified monitor. - * - * @return The UTF-8 encoded display device name (for example - * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.1. - * - * @ingroup native - */ -GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); - -/*! @brief Returns the `HWND` of the specified window. - * - * @return The `HWND` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @remark The `HDC` associated with the window can be queried with the - * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) - * function. - * @code - * HDC dc = GetDC(glfwGetWin32Window(window)); - * @endcode - * This DC is private and does not need to be released. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_WGL) -/*! @brief Returns the `HGLRC` of the specified window. - * - * @return The `HGLRC` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. - * - * @remark The `HDC` associated with the window can be queried with the - * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) - * function. - * @code - * HDC dc = GetDC(glfwGetWin32Window(window)); - * @endcode - * This DC is private and does not need to be released. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_COCOA) -/*! @brief Returns the `CGDirectDisplayID` of the specified monitor. - * - * @return The `CGDirectDisplayID` of the specified monitor, or - * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.1. - * - * @ingroup native - */ -GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); - -/*! @brief Returns the `NSWindow` of the specified window. - * - * @return The `NSWindow` of the specified window, or `nil` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); - -/*! @brief Returns the `NSView` of the specified window. - * - * @return The `NSView` of the specified window, or `nil` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.4. - * - * @ingroup native - */ -GLFWAPI id glfwGetCocoaView(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_NSGL) -/*! @brief Returns the `NSOpenGLContext` of the specified window. - * - * @return The `NSOpenGLContext` of the specified window, or `nil` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_X11) -/*! @brief Returns the `Display` used by GLFW. - * - * @return The `Display` used by GLFW, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI Display* glfwGetX11Display(void); - -/*! @brief Returns the `RRCrtc` of the specified monitor. - * - * @return The `RRCrtc` of the specified monitor, or `None` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.1. - * - * @ingroup native - */ -GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); - -/*! @brief Returns the `RROutput` of the specified monitor. - * - * @return The `RROutput` of the specified monitor, or `None` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.1. - * - * @ingroup native - */ -GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); - -/*! @brief Returns the `Window` of the specified window. - * - * @return The `Window` of the specified window, or `None` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI Window glfwGetX11Window(GLFWwindow* window); - -/*! @brief Sets the current primary selection to the specified string. - * - * @param[in] string A UTF-8 encoded string. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The specified string is copied before this function - * returns. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref clipboard - * @sa glfwGetX11SelectionString - * @sa glfwSetClipboardString - * - * @since Added in version 3.3. - * - * @ingroup native - */ -GLFWAPI void glfwSetX11SelectionString(const char* string); - -/*! @brief Returns the contents of the current primary selection as a string. - * - * If the selection is empty or if its contents cannot be converted, `NULL` - * is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated. - * - * @return The contents of the selection as a UTF-8 encoded string, or `NULL` - * if an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. - * - * @pointer_lifetime The returned string is allocated and freed by GLFW. You - * should not free it yourself. It is valid until the next call to @ref - * glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the - * library is terminated. - * - * @thread_safety This function must only be called from the main thread. - * - * @sa @ref clipboard - * @sa glfwSetX11SelectionString - * @sa glfwGetClipboardString - * - * @since Added in version 3.3. - * - * @ingroup native - */ -GLFWAPI const char* glfwGetX11SelectionString(void); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_GLX) -/*! @brief Returns the `GLXContext` of the specified window. - * - * @return The `GLXContext` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); - -/*! @brief Returns the `GLXWindow` of the specified window. - * - * @return The `GLXWindow` of the specified window, or `None` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.2. - * - * @ingroup native - */ -GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_WAYLAND) -/*! @brief Returns the `struct wl_display*` used by GLFW. - * - * @return The `struct wl_display*` used by GLFW, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.2. - * - * @ingroup native - */ -GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); - -/*! @brief Returns the `struct wl_output*` of the specified monitor. - * - * @return The `struct wl_output*` of the specified monitor, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.2. - * - * @ingroup native - */ -GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); - -/*! @brief Returns the main `struct wl_surface*` of the specified window. - * - * @return The main `struct wl_surface*` of the specified window, or `NULL` if - * an [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_PLATFORM_UNAVAILABLE. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.2. - * - * @ingroup native - */ -GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_EGL) -/*! @brief Returns the `EGLDisplay` used by GLFW. - * - * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. - * - * @remark Because EGL is initialized on demand, this function will return - * `EGL_NO_DISPLAY` until the first context has been created via EGL. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI EGLDisplay glfwGetEGLDisplay(void); - -/*! @brief Returns the `EGLContext` of the specified window. - * - * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_NO_WINDOW_CONTEXT. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); - -/*! @brief Returns the `EGLSurface` of the specified window. - * - * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_NO_WINDOW_CONTEXT. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.0. - * - * @ingroup native - */ -GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); -#endif - -#if defined(GLFW_EXPOSE_NATIVE_OSMESA) -/*! @brief Retrieves the color buffer associated with the specified window. - * - * @param[in] window The window whose color buffer to retrieve. - * @param[out] width Where to store the width of the color buffer, or `NULL`. - * @param[out] height Where to store the height of the color buffer, or `NULL`. - * @param[out] format Where to store the OSMesa pixel format of the color - * buffer, or `NULL`. - * @param[out] buffer Where to store the address of the color buffer, or - * `NULL`. - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_NO_WINDOW_CONTEXT. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.3. - * - * @ingroup native - */ -GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer); - -/*! @brief Retrieves the depth buffer associated with the specified window. - * - * @param[in] window The window whose depth buffer to retrieve. - * @param[out] width Where to store the width of the depth buffer, or `NULL`. - * @param[out] height Where to store the height of the depth buffer, or `NULL`. - * @param[out] bytesPerValue Where to store the number of bytes per depth - * buffer element, or `NULL`. - * @param[out] buffer Where to store the address of the depth buffer, or - * `NULL`. - * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_NO_WINDOW_CONTEXT. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.3. - * - * @ingroup native - */ -GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer); - -/*! @brief Returns the `OSMesaContext` of the specified window. - * - * @return The `OSMesaContext` of the specified window, or `NULL` if an - * [error](@ref error_handling) occurred. - * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref - * GLFW_NO_WINDOW_CONTEXT. - * - * @thread_safety This function may be called from any thread. Access is not - * synchronized. - * - * @since Added in version 3.3. - * - * @ingroup native - */ -GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _glfw3_native_h_ */ - diff --git a/vendor/glfw/libglfw3.a b/vendor/glfw/libglfw3.a deleted file mode 100644 index fee383d72b2864f9e4c28a79a881c2fa659f32f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 334770 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�O&+Pp8`5t&@GBGK<5b81H^}F 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 hi{Am&-#CvxUfDanv?{uf&LF-`yg diff --git a/vendor/glfw/libglfw3dll.a b/vendor/glfw/libglfw3dll.a deleted file mode 100644 index 535cd3b8e40d346050f0246e073ad0c018f7641d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 89452 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 xTeq@%VRN!rsBCj&XS