├── Images ├── Screenshot.png └── brushImage.jpg ├── Libraries ├── lib │ └── glfw3.lib └── include │ ├── KHR │ └── khrplatform.h │ ├── GLFW │ └── glfw3native.h │ └── stb │ └── stb_image_write.h ├── vertex_shader.vert ├── fragment_shader.frag ├── imgui.ini ├── Drawing.h ├── SaveManager.h ├── DrawingUtils.h ├── OpenGLUtils.h ├── Callbacks.h ├── ShaderManager.h ├── WindowManager.h ├── GuiManager.h ├── Drawing.cpp ├── Callbacks.cpp ├── OpenGLUtils.cpp ├── README.md ├── ShaderManager.cpp ├── wackyDrawingSoft_tutorial.sln ├── DrawingUtils.cpp ├── WindowManager.cpp ├── SaveManager.cpp ├── Main.cpp ├── .gitattributes ├── GuiManager.cpp ├── wackyDrawingSoft_tutorial.vcxproj.filters ├── .gitignore ├── wackyDrawingSoft_tutorial.vcxproj └── glad.c /Images/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wassimcodes/drawing-software/HEAD/Images/Screenshot.png -------------------------------------------------------------------------------- /Images/brushImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wassimcodes/drawing-software/HEAD/Images/brushImage.jpg -------------------------------------------------------------------------------- /Libraries/lib/glfw3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wassimcodes/drawing-software/HEAD/Libraries/lib/glfw3.lib -------------------------------------------------------------------------------- /vertex_shader.vert: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | layout (location = 0) in vec2 aPos; 4 | 5 | void main() { 6 | gl_Position = vec4(aPos, 0.0, 1.0); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /fragment_shader.frag: -------------------------------------------------------------------------------- 1 | #version 330 core 2 | 3 | out vec4 FragColor; 4 | uniform vec4 u_BrushColor; 5 | 6 | void main() { 7 | FragColor = u_BrushColor; 8 | } 9 | -------------------------------------------------------------------------------- /imgui.ini: -------------------------------------------------------------------------------- 1 | [Window][Debug##Default] 2 | Pos=60,60 3 | Size=400,400 4 | Collapsed=0 5 | 6 | [Window][UI Panel] 7 | Pos=0,0 8 | Size=720,35 9 | Collapsed=0 10 | 11 | -------------------------------------------------------------------------------- /Drawing.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class DrawingCircle { 7 | public: 8 | static std::vector drawCircle(float x, float y, float radius, int sides = 30); 9 | }; 10 | -------------------------------------------------------------------------------- /SaveManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | std::vector CaptureFramebuffer(GLFWwindow* window, int& width, int& height); 8 | void SaveDrawingAsPNG(GLFWwindow* window); -------------------------------------------------------------------------------- /DrawingUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void handleCursorMovement(GLFWwindow* window, double& prevXpos, double& prevYpos, std::vector>& circles, GLuint VBO, GLuint VAO, float radius, int sides); 8 | -------------------------------------------------------------------------------- /OpenGLUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | void initializeBuffers(GLuint& VAO, GLuint& VBO); 6 | void updateVertexBuffer(GLuint VBO, const std::vector& vertices); 7 | void drawCircle(GLuint VAO, GLuint VBO, const std::vector& vertices, GLenum mode); 8 | -------------------------------------------------------------------------------- /Callbacks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); 6 | void cursor_position_callback(GLFWwindow* window, double xpos, double ypos); 7 | void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); -------------------------------------------------------------------------------- /ShaderManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | std::string readShaderFile(const char* filename); 7 | 8 | GLuint compileShader(GLenum shaderType, const std::string& source); 9 | 10 | GLuint createShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath); 11 | -------------------------------------------------------------------------------- /WindowManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class WindowManager { 6 | public: 7 | static GLFWwindow* createWindow(int width, int height, const char* title); 8 | static void setupCallbacks(GLFWwindow* window); 9 | }; 10 | 11 | void setWindowIcon(GLFWwindow* window, const char* imagePath); 12 | 13 | -------------------------------------------------------------------------------- /GuiManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class GuiManager { 10 | public: 11 | static void Init(GLFWwindow* window); 12 | static void Shutdown(); 13 | static void NewFrame(); 14 | static void Render(); 15 | static void CreateUI(std::vector>& circles); 16 | }; -------------------------------------------------------------------------------- /Drawing.cpp: -------------------------------------------------------------------------------- 1 | #include "Drawing.h" 2 | #include 3 | #include 4 | #include 5 | 6 | std::vector DrawingCircle::drawCircle(float x, float y, float radius, int sides) { 7 | std::vector vertices; 8 | for (int i = 0; i < sides; ++i) { 9 | float theta = 2.0f * 3.1415926f * float(i) / float(sides); 10 | float vx = x + radius * cosf(theta); 11 | float vy = y + radius * sinf(theta); 12 | vertices.push_back(vx); 13 | vertices.push_back(vy); 14 | } 15 | //std::cout << "First vertex coordinates:" << std::endl; 16 | //std::cout << "(" << vertices[0] << ", " << vertices[1] << ")" << std::endl; 17 | 18 | return vertices; 19 | } -------------------------------------------------------------------------------- /Callbacks.cpp: -------------------------------------------------------------------------------- 1 | #include "Callbacks.h" 2 | #include "iostream" 3 | 4 | void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) 5 | { 6 | if (button == GLFW_MOUSE_BUTTON_LEFT) 7 | { 8 | if (action == GLFW_PRESS) 9 | { 10 | std::cout << "left mouse is pressed" << std::endl; 11 | } 12 | else if (action == GLFW_RELEASE) 13 | { 14 | std::cout << "left mouse is released" << std::endl; 15 | } 16 | } 17 | } 18 | 19 | void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) 20 | { 21 | std::cout << "cursor position:( " << xpos << ", " << ypos << " )" << std::endl; 22 | } 23 | void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 24 | { 25 | { 26 | std::cout << "key pressed: " << key << std::endl; 27 | } 28 | } -------------------------------------------------------------------------------- /OpenGLUtils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void initializeBuffers(GLuint& VAO, GLuint& VBO) { 7 | glGenVertexArrays(1, &VAO); 8 | glBindVertexArray(VAO); 9 | 10 | glGenBuffers(1, &VBO); 11 | glBindBuffer(GL_ARRAY_BUFFER, VBO); 12 | 13 | glEnableVertexAttribArray(0); 14 | glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); 15 | } 16 | 17 | void updateVertexBuffer(GLuint VBO, const std::vector& vertices) { 18 | glBindBuffer(GL_ARRAY_BUFFER, VBO); 19 | glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW); 20 | } 21 | 22 | void drawCircle(GLuint VAO, GLuint VBO, const std::vector& vertices, GLenum mode) { 23 | glBindVertexArray(VAO); 24 | glDrawArrays(mode, 0, static_cast(vertices.size() / 2)); 25 | glBindVertexArray(0); 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wacky Drawing Software 2 | 3 | ## Introduction 4 | 5 | Welcome to **Wacky Drawing Software**, a project I've worked on for a month. This is my first venture into using C++ and OpenGL, and I'm excited to share it with you. This software serves as a testament to my learning journey, and I hope it inspires others. 6 | 7 | ![Screenshot](Images/Screenshot.png) 8 | 9 | ## Goal 10 | 11 | The primary goal of this project is self-learning. While I didn't initially intend to publish it for professional use, I'm making it available for anyone who might find it helpful or interesting. It's a great starting point for those looking to understand the basics of C++ and OpenGL. 12 | 13 | ## Permission 14 | 15 | Feel free to use and modify this code as you wish. You don't need my permission to do so. Whether you're looking to learn, tinker, or build upon this project, you're welcome to explore and innovate. 16 | 17 | ## Libraries 18 | 19 | The libraries used in this project are listed in the [Libraries folder](Libraries). These libraries are crucial for the functionality and performance of the software. 20 | -------------------------------------------------------------------------------- /ShaderManager.cpp: -------------------------------------------------------------------------------- 1 | #include "ShaderManager.h" 2 | #include 3 | #include 4 | #include 5 | 6 | std::string readShaderFile(const char* filename) { 7 | std::ifstream file(filename); 8 | std::stringstream buffer; 9 | buffer << file.rdbuf(); 10 | return buffer.str(); 11 | } 12 | 13 | GLuint compileShader(GLenum shaderType, const std::string& source) { 14 | GLuint shader = glCreateShader(shaderType); 15 | const char* sourceCStr = source.c_str(); 16 | glShaderSource(shader, 1, &sourceCStr, nullptr); 17 | glCompileShader(shader); 18 | return shader; 19 | } 20 | 21 | GLuint createShaderProgram(const char* vertexShaderPath, const char* fragmentShaderPath) { 22 | std::string vertexShaderSource = readShaderFile(vertexShaderPath); 23 | std::string fragmentShaderSource = readShaderFile(fragmentShaderPath); 24 | GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource); 25 | GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource); 26 | GLuint shaderProgram = glCreateProgram(); 27 | glAttachShader(shaderProgram, vertexShader); 28 | glAttachShader(shaderProgram, fragmentShader); 29 | glLinkProgram(shaderProgram); 30 | glDeleteShader(vertexShader); 31 | glDeleteShader(fragmentShader); 32 | 33 | return shaderProgram; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /wackyDrawingSoft_tutorial.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32519.379 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wackyDrawingSoft_tutorial", "wackyDrawingSoft_tutorial.vcxproj", "{3DCF5598-3790-4872-A08D-DA96CE2AA4D1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Debug|x64.ActiveCfg = Debug|x64 17 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Debug|x64.Build.0 = Debug|x64 18 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Debug|x86.ActiveCfg = Debug|Win32 19 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Debug|x86.Build.0 = Debug|Win32 20 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Release|x64.ActiveCfg = Release|x64 21 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Release|x64.Build.0 = Release|x64 22 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Release|x86.ActiveCfg = Release|Win32 23 | {3DCF5598-3790-4872-A08D-DA96CE2AA4D1}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {1C1C33CD-ABA3-45ED-A25D-33AE3DFAAF66} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /DrawingUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "DrawingUtils.h" 2 | #include "Drawing.h" 3 | #include "OpenGLUtils.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | void handleCursorMovement(GLFWwindow* window, double& prevXpos, double& prevYpos, std::vector>& circles, GLuint VBO, GLuint VAO, float radius, int sides) { 9 | double xpos, ypos; 10 | glfwGetCursorPos(window, &xpos, &ypos); 11 | int width, height; 12 | glfwGetFramebufferSize(window, &width, &height); 13 | 14 | float x1 = static_cast(prevXpos) / width * 2.0f - 1.0f; 15 | float y1 = -static_cast(prevYpos) / height * 2.0f + 1.0f; 16 | float x2 = static_cast(xpos) / width * 2.0f - 1.0f; 17 | float y2 = -static_cast(ypos) / height * 2.0f + 1.0f; 18 | 19 | std::vector currentCircle = DrawingCircle::drawCircle(x2, y2, radius, sides); 20 | updateVertexBuffer(VBO, currentCircle); 21 | drawCircle(VAO, VBO, currentCircle, GL_TRIANGLE_FAN); 22 | 23 | if (ImGui::IsAnyItemHovered()) 24 | { 25 | return; 26 | } 27 | 28 | if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) { 29 | int num_samples = std::max(static_cast(sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / radius), 1); 30 | for (int i = 0; i <= num_samples; ++i) { 31 | float t = static_cast(i) / num_samples; 32 | float vx = x1 * (1 - t) + x2 * t; 33 | float vy = y1 * (1 - t) + y2 * t; 34 | std::vector currentCircle = DrawingCircle::drawCircle(vx, vy, radius, sides); 35 | circles.push_back(currentCircle); 36 | } 37 | } 38 | 39 | 40 | prevXpos = xpos; 41 | prevYpos = ypos; 42 | } 43 | -------------------------------------------------------------------------------- /WindowManager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "WindowManager.h" 3 | #include "Callbacks.h" 4 | #include 5 | #include 6 | #include 7 | #define STB_IMAGE_IMPLEMENTATION 8 | #include "stb_image.h" 9 | 10 | GLFWwindow* WindowManager::createWindow(int width, int height, const char* title) { 11 | glfwInit(); 12 | glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); 13 | GLFWwindow* window = glfwCreateWindow(width, height, title, nullptr, nullptr); 14 | glfwMakeContextCurrent(window); 15 | if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { 16 | std::cerr << "Failed to initialize GLAD" << std::endl; 17 | return nullptr; 18 | } 19 | glViewport(0, 0, width, height); 20 | return window; 21 | } 22 | 23 | void WindowManager::setupCallbacks(GLFWwindow* window) { 24 | glfwSetMouseButtonCallback(window, mouse_button_callback); 25 | glfwSetCursorPosCallback(window, cursor_position_callback); 26 | glfwSetKeyCallback(window, key_callback); 27 | } 28 | 29 | 30 | // Window Icon 31 | 32 | void setWindowIcon(GLFWwindow* window, const char* imagePath) { 33 | int width, height, channels; 34 | 35 | std::ifstream file(imagePath, std::ios::binary); 36 | if (!file) { 37 | std::cerr << "Failed to open image file: " << imagePath << std::endl; 38 | return; 39 | } 40 | 41 | file.seekg(0, std::ios::end); 42 | size_t fileSize = file.tellg(); 43 | file.seekg(0, std::ios::beg); 44 | 45 | std::vector buffer(fileSize); 46 | file.read(buffer.data(), fileSize); 47 | file.close(); 48 | 49 | unsigned char* pixels = stbi_load_from_memory(reinterpret_cast(buffer.data()), fileSize, &width, &height, &channels, STBI_rgb_alpha); 50 | if (!pixels) { 51 | std::cerr << "Failed to load image: " << imagePath << std::endl; 52 | return; 53 | } 54 | 55 | GLFWimage image; 56 | image.width = width; 57 | image.height = height; 58 | image.pixels = pixels; 59 | 60 | glfwSetWindowIcon(window, 1, &image); 61 | 62 | stbi_image_free(pixels); 63 | } 64 | -------------------------------------------------------------------------------- /SaveManager.cpp: -------------------------------------------------------------------------------- 1 | #include "SaveManager.h" 2 | #include 3 | #include 4 | #define STB_IMAGE_WRITE_IMPLEMENTATION 5 | #include "stb_image_write.h" 6 | #include 7 | 8 | std::vector CaptureFramebuffer(GLFWwindow* window, int& width, int& height) { 9 | glfwGetFramebufferSize(window, &width, &height); 10 | std::vector pixels(width * height * 4); 11 | glReadBuffer(GL_FRONT); 12 | glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); 13 | 14 | for (int y = 0; y < height / 2; ++y) { 15 | for (int x = 0; x < width * 4; ++x) { 16 | std::swap(pixels[y * width * 4 + x], pixels[(height - 1 - y) * width * 4 + x]); 17 | } 18 | } 19 | 20 | return pixels; 21 | } 22 | 23 | void SaveDrawingAsPNG(GLFWwindow* window) { 24 | int width, height; 25 | std::vector pixels = CaptureFramebuffer(window, width, height); 26 | OPENFILENAMEA ofn; 27 | CHAR szFile[260] = { 0 }; 28 | ZeroMemory(&ofn, sizeof(ofn)); 29 | ofn.lStructSize = sizeof(ofn); 30 | ofn.hwndOwner = NULL; 31 | ofn.lpstrFile = szFile; 32 | ofn.lpstrFile[0] = '\0'; 33 | ofn.nMaxFile = sizeof(szFile); 34 | ofn.lpstrFilter = "PNG Files\0*.png\0All Files\0*.*\0"; 35 | ofn.nFilterIndex = 1; 36 | ofn.lpstrFileTitle = NULL; 37 | ofn.nMaxFileTitle = 0; 38 | ofn.lpstrInitialDir = NULL; 39 | ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT; 40 | 41 | if (GetSaveFileNameA(&ofn) == TRUE) { 42 | std::string filePath = ofn.lpstrFile; 43 | if (filePath.find(".png") == std::string::npos) { 44 | filePath += ".png"; 45 | } 46 | if (stbi_write_png(filePath.c_str(), width, height, 4, pixels.data(), width * 4)) { 47 | std::cout << "Saved drawing as PNG successfully to: " << filePath << std::endl; 48 | } 49 | else { 50 | std::cout << "Failed to save drawing as PNG." << std::endl; 51 | } 52 | } 53 | else { 54 | std::cout << "User canceled saving." << std::endl; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "WindowManager.h" 4 | #include "Callbacks.h" 5 | #include "ShaderManager.h" 6 | #include "OpenGLUtils.h" 7 | #include "Drawing.h" 8 | #include "GuiManager.h" 9 | #include "DrawingUtils.h" 10 | #include 11 | #include 12 | 13 | extern bool darkMode; 14 | extern ImVec4 clear_color; 15 | extern ImVec4 selected_color; 16 | extern float brushSize; 17 | extern int brushSizeDisplay; 18 | 19 | // Window Screen 20 | void framebuffer_size_callback(GLFWwindow* window, int width, int height) { 21 | glViewport(0, 0, width, height); 22 | } 23 | 24 | // Main function 25 | int main() { 26 | GLFWwindow* window = WindowManager::createWindow(720, 720, "Wacky Drawing Software"); 27 | WindowManager::setupCallbacks(window); 28 | 29 | 30 | setWindowIcon(window, "C:/Users/woule/Documents/c++/DrawingSoftware/Images/brushImage.jpg"); 31 | 32 | glfwSwapInterval(0); 33 | GuiManager::Init(window); 34 | GLuint shaderProgram = createShaderProgram("vertex_shader.vert", "fragment_shader.frag"); 35 | glUseProgram(shaderProgram); 36 | GLuint VAO, VBO; 37 | initializeBuffers(VAO, VBO); 38 | const int sides = 60; 39 | 40 | std::vector> circles; 41 | 42 | // Main loop 43 | 44 | 45 | while (!glfwWindowShouldClose(window)) { 46 | glfwPollEvents(); 47 | glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); 48 | glClear(GL_COLOR_BUFFER_BIT); 49 | 50 | GuiManager::NewFrame(); 51 | GuiManager::CreateUI(circles); 52 | 53 | static double prevXpos, prevYpos; 54 | handleCursorMovement(window, prevXpos, prevYpos, circles, VBO, VAO, brushSize, sides); 55 | 56 | int brushColorLocation = glGetUniformLocation(shaderProgram, "u_BrushColor"); 57 | glUniform4f(brushColorLocation, selected_color.x, selected_color.y, selected_color.z, selected_color.w); 58 | 59 | for (const auto& circle : circles) { 60 | updateVertexBuffer(VBO, circle); 61 | drawCircle(VAO, VBO, circle, GL_TRIANGLE_FAN); 62 | } 63 | GuiManager::Render(); 64 | glfwSwapBuffers(window); 65 | } 66 | GuiManager::Shutdown(); 67 | glDeleteBuffers(1, &VBO); 68 | glDeleteVertexArrays(1, &VAO); 69 | glfwDestroyWindow(window); 70 | glfwTerminate(); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /GuiManager.cpp: -------------------------------------------------------------------------------- 1 | #include "GuiManager.h" 2 | #include "SaveManager.h" 3 | #include 4 | 5 | bool darkMode = true; 6 | ImVec4 clear_color = ImVec4(0, 0, 0, 0); 7 | ImVec4 selected_color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); 8 | 9 | float brushSize = 0.0055f; 10 | int brushSizeDisplay = 10; 11 | const float minBrushSize = 0.001f; 12 | const float maxBrushSize = 0.05f; 13 | 14 | 15 | void GuiManager::Init(GLFWwindow* window) { 16 | ImGui::CreateContext(); 17 | ImGui_ImplGlfw_InitForOpenGL(window, true); 18 | ImGui_ImplOpenGL3_Init("#version 330 core"); 19 | ImGui::StyleColorsDark(); 20 | } 21 | 22 | void GuiManager::Shutdown() { 23 | ImGui_ImplOpenGL3_Shutdown(); 24 | ImGui_ImplGlfw_Shutdown(); 25 | ImGui::DestroyContext(); 26 | } 27 | 28 | void GuiManager::NewFrame() { 29 | ImGui_ImplOpenGL3_NewFrame(); 30 | ImGui_ImplGlfw_NewFrame(); 31 | ImGui::NewFrame(); 32 | } 33 | 34 | void GuiManager::Render() { 35 | ImGui::Render(); 36 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); 37 | } 38 | 39 | void ResetDrawing(std::vector>& circles) { 40 | circles.clear(); 41 | std::cout << "Reset Drawing selected" << std::endl; 42 | } 43 | 44 | void ToggleDarkWhiteMode(bool& darkMode, ImVec4& clear_color) { 45 | if (darkMode) { 46 | ImGui::StyleColorsLight(); 47 | clear_color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); 48 | } 49 | else { 50 | ImGui::StyleColorsDark(); 51 | clear_color = ImVec4(0, 0, 0, 0); 52 | } 53 | darkMode = !darkMode; 54 | std::cout << "Dark/White Mode toggled" << std::endl; 55 | } 56 | 57 | void GuiManager::CreateUI(std::vector>& circles) { 58 | ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | 59 | ImGuiWindowFlags_NoMove | 60 | ImGuiWindowFlags_NoResize | 61 | ImGuiWindowFlags_NoCollapse | 62 | ImGuiWindowFlags_NoTitleBar; 63 | 64 | ImGui::SetNextWindowPos(ImVec2(0, 0)); 65 | ImGui::SetNextWindowSize(ImVec2(ImGui::GetIO().DisplaySize.x, 0)); 66 | ImGui::Begin("UI Panel", nullptr, windowFlags); 67 | 68 | if (ImGui::BeginMenuBar()) { 69 | if (ImGui::BeginMenu("File")) { 70 | if (ImGui::MenuItem("Save Drawing as PNG")) { 71 | SaveDrawingAsPNG(glfwGetCurrentContext()); 72 | } 73 | if (ImGui::MenuItem("Reset")) { 74 | ResetDrawing(circles); 75 | } 76 | if (ImGui::MenuItem("Dark/White Mode")) { 77 | ToggleDarkWhiteMode(darkMode, clear_color); 78 | } 79 | ImGui::EndMenu(); 80 | } 81 | if (ImGui::BeginMenu("Colors")) { 82 | ImGui::ColorEdit3("Color", (float*)&selected_color); 83 | ImGui::EndMenu(); 84 | } 85 | if (ImGui::BeginMenu("Brush")) { 86 | if (ImGui::SliderInt("Size", &brushSizeDisplay, 1, 100)) { 87 | brushSize = minBrushSize + (maxBrushSize - minBrushSize) * (brushSizeDisplay - 1) / 99.0f; 88 | } 89 | ImGui::EndMenu(); 90 | } 91 | if (ImGui::BeginMenu("Draw")) { 92 | ImGui::EndMenu(); 93 | } 94 | ImGui::EndMenuBar(); 95 | } 96 | 97 | //ImGui::Text("fps: %.1f ", ImGui::GetIO().Framerate); 98 | ImGui::End(); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /wackyDrawingSoft_tutorial.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {51b1b741-a3d1-4ee6-9f69-31557f54cb47} 18 | 19 | 20 | {ecafcf3a-4366-43a8-9ab6-9aa2732208cc} 21 | 22 | 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | ImGui 44 | 45 | 46 | ImGui 47 | 48 | 49 | ImGui 50 | 51 | 52 | ImGui 53 | 54 | 55 | ImGui 56 | 57 | 58 | ImGui 59 | 60 | 61 | ImGui 62 | 63 | 64 | Source Files 65 | 66 | 67 | Source Files 68 | 69 | 70 | Resource Files 71 | 72 | 73 | Source Files 74 | 75 | 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | ImGui 94 | 95 | 96 | ImGui 97 | 98 | 99 | ImGui 100 | 101 | 102 | ImGui 103 | 104 | 105 | ImGui 106 | 107 | 108 | ImGui 109 | 110 | 111 | ImGui 112 | 113 | 114 | ImGui 115 | 116 | 117 | Header Files 118 | 119 | 120 | Header Files 121 | 122 | 123 | Header Files 124 | 125 | 126 | 127 | 128 | Shaders 129 | 130 | 131 | Shaders 132 | 133 | 134 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /wackyDrawingSoft_tutorial.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 16.0 64 | Win32Proj 65 | {3dcf5598-3790-4872-a08d-da96ce2aa4d1} 66 | wackyDrawingSofttutorial 67 | 10.0 68 | 69 | 70 | 71 | Application 72 | true 73 | v143 74 | Unicode 75 | 76 | 77 | Application 78 | false 79 | v143 80 | true 81 | Unicode 82 | 83 | 84 | Application 85 | true 86 | v143 87 | Unicode 88 | 89 | 90 | Application 91 | false 92 | v143 93 | true 94 | Unicode 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | D:\C++\wackyDrawingSoft_tutorial\Libraries\include\stb;D:\C++\wackyDrawingSoft_tutorial\ImGuiApp\MyApplication;D:\C++\wackyDrawingSoft_tutorial\Libraries\include;D:\C++\wackyDrawingSoft_tutorial\ImGuiApp\MyApplication\backends;$(IncludePath) 116 | D:\C++\wackyDrawingSoft_tutorial\Libraries\lib;$(LibraryPath) 117 | 118 | 119 | D:\C++\wackyDrawingSoft_tutorial\Libraries\include\stb;D:\C++\wackyDrawingSoft_tutorial\ImGuiApp\MyApplication;D:\C++\wackyDrawingSoft_tutorial\Libraries\include;D:\C++\wackyDrawingSoft_tutorial\ImGuiApp\MyApplication\backends;$(IncludePath) 120 | D:\C++\wackyDrawingSoft_tutorial\Libraries\lib;$(LibraryPath) 121 | 122 | 123 | C:\Users\woule\Documents\c++\DrawingSoftware\Libraries\include\stb;C:\Users\woule\Documents\c++\DrawingSoftware\ImGuiApp\MyApplication;C:\Users\woule\Documents\c++\DrawingSoftware\Libraries\include;C:\Users\woule\Documents\c++\DrawingSoftware\ImGuiApp\MyApplication\backends;$(IncludePath) 124 | C:\Users\woule\Documents\c++\DrawingSoftware\Libraries\lib;$(LibraryPath) 125 | 126 | 127 | D:\C++\wackyDrawingSoft_tutorial\Libraries\include\stb;D:\C++\wackyDrawingSoft_tutorial\ImGuiApp\MyApplication;D:\C++\wackyDrawingSoft_tutorial\Libraries\include;D:\C++\wackyDrawingSoft_tutorial\ImGuiApp\MyApplication\backends;$(IncludePath) 128 | D:\C++\wackyDrawingSoft_tutorial\Libraries\lib;$(LibraryPath) 129 | 130 | 131 | 132 | Level3 133 | true 134 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 135 | true 136 | 137 | 138 | Console 139 | true 140 | glfw3.lib;opengl32.lib;%(AdditionalDependencies) 141 | 142 | 143 | 144 | 145 | Level3 146 | true 147 | true 148 | true 149 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 150 | true 151 | 152 | 153 | Console 154 | true 155 | true 156 | true 157 | glfw3.lib;opengl32.lib;%(AdditionalDependencies) 158 | 159 | 160 | 161 | 162 | Level3 163 | true 164 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 165 | true 166 | 167 | 168 | Console 169 | true 170 | glfw3.lib;opengl32.lib;%(AdditionalDependencies) 171 | 172 | 173 | 174 | 175 | Level3 176 | true 177 | true 178 | true 179 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 180 | true 181 | 182 | 183 | Console 184 | true 185 | true 186 | true 187 | glfw3.lib;opengl32.lib;%(AdditionalDependencies) 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /Libraries/include/KHR/khrplatform.h: -------------------------------------------------------------------------------- 1 | #ifndef __khrplatform_h_ 2 | #define __khrplatform_h_ 3 | 4 | /* 5 | ** Copyright (c) 2008-2018 The Khronos Group Inc. 6 | ** 7 | ** Permission is hereby granted, free of charge, to any person obtaining a 8 | ** copy of this software and/or associated documentation files (the 9 | ** "Materials"), to deal in the Materials without restriction, including 10 | ** without limitation the rights to use, copy, modify, merge, publish, 11 | ** distribute, sublicense, and/or sell copies of the Materials, and to 12 | ** permit persons to whom the Materials are furnished to do so, subject to 13 | ** the following conditions: 14 | ** 15 | ** The above copyright notice and this permission notice shall be included 16 | ** in all copies or substantial portions of the Materials. 17 | ** 18 | ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 25 | */ 26 | 27 | /* Khronos platform-specific types and definitions. 28 | * 29 | * The master copy of khrplatform.h is maintained in the Khronos EGL 30 | * Registry repository at https://github.com/KhronosGroup/EGL-Registry 31 | * The last semantic modification to khrplatform.h was at commit ID: 32 | * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 33 | * 34 | * Adopters may modify this file to suit their platform. Adopters are 35 | * encouraged to submit platform specific modifications to the Khronos 36 | * group so that they can be included in future versions of this file. 37 | * Please submit changes by filing pull requests or issues on 38 | * the EGL Registry repository linked above. 39 | * 40 | * 41 | * See the Implementer's Guidelines for information about where this file 42 | * should be located on your system and for more details of its use: 43 | * http://www.khronos.org/registry/implementers_guide.pdf 44 | * 45 | * This file should be included as 46 | * #include 47 | * by Khronos client API header files that use its types and defines. 48 | * 49 | * The types in khrplatform.h should only be used to define API-specific types. 50 | * 51 | * Types defined in khrplatform.h: 52 | * khronos_int8_t signed 8 bit 53 | * khronos_uint8_t unsigned 8 bit 54 | * khronos_int16_t signed 16 bit 55 | * khronos_uint16_t unsigned 16 bit 56 | * khronos_int32_t signed 32 bit 57 | * khronos_uint32_t unsigned 32 bit 58 | * khronos_int64_t signed 64 bit 59 | * khronos_uint64_t unsigned 64 bit 60 | * khronos_intptr_t signed same number of bits as a pointer 61 | * khronos_uintptr_t unsigned same number of bits as a pointer 62 | * khronos_ssize_t signed size 63 | * khronos_usize_t unsigned size 64 | * khronos_float_t signed 32 bit floating point 65 | * khronos_time_ns_t unsigned 64 bit time in nanoseconds 66 | * khronos_utime_nanoseconds_t unsigned time interval or absolute time in 67 | * nanoseconds 68 | * khronos_stime_nanoseconds_t signed time interval in nanoseconds 69 | * khronos_boolean_enum_t enumerated boolean type. This should 70 | * only be used as a base type when a client API's boolean type is 71 | * an enum. Client APIs which use an integer or other type for 72 | * booleans cannot use this as the base type for their boolean. 73 | * 74 | * Tokens defined in khrplatform.h: 75 | * 76 | * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. 77 | * 78 | * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. 79 | * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. 80 | * 81 | * Calling convention macros defined in this file: 82 | * KHRONOS_APICALL 83 | * KHRONOS_APIENTRY 84 | * KHRONOS_APIATTRIBUTES 85 | * 86 | * These may be used in function prototypes as: 87 | * 88 | * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( 89 | * int arg1, 90 | * int arg2) KHRONOS_APIATTRIBUTES; 91 | */ 92 | 93 | #if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) 94 | # define KHRONOS_STATIC 1 95 | #endif 96 | 97 | /*------------------------------------------------------------------------- 98 | * Definition of KHRONOS_APICALL 99 | *------------------------------------------------------------------------- 100 | * This precedes the return type of the function in the function prototype. 101 | */ 102 | #if defined(KHRONOS_STATIC) 103 | /* If the preprocessor constant KHRONOS_STATIC is defined, make the 104 | * header compatible with static linking. */ 105 | # define KHRONOS_APICALL 106 | #elif defined(_WIN32) 107 | # define KHRONOS_APICALL __declspec(dllimport) 108 | #elif defined (__SYMBIAN32__) 109 | # define KHRONOS_APICALL IMPORT_C 110 | #elif defined(__ANDROID__) 111 | # define KHRONOS_APICALL __attribute__((visibility("default"))) 112 | #else 113 | # define KHRONOS_APICALL 114 | #endif 115 | 116 | /*------------------------------------------------------------------------- 117 | * Definition of KHRONOS_APIENTRY 118 | *------------------------------------------------------------------------- 119 | * This follows the return type of the function and precedes the function 120 | * name in the function prototype. 121 | */ 122 | #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) 123 | /* Win32 but not WinCE */ 124 | # define KHRONOS_APIENTRY __stdcall 125 | #else 126 | # define KHRONOS_APIENTRY 127 | #endif 128 | 129 | /*------------------------------------------------------------------------- 130 | * Definition of KHRONOS_APIATTRIBUTES 131 | *------------------------------------------------------------------------- 132 | * This follows the closing parenthesis of the function prototype arguments. 133 | */ 134 | #if defined (__ARMCC_2__) 135 | #define KHRONOS_APIATTRIBUTES __softfp 136 | #else 137 | #define KHRONOS_APIATTRIBUTES 138 | #endif 139 | 140 | /*------------------------------------------------------------------------- 141 | * basic type definitions 142 | *-----------------------------------------------------------------------*/ 143 | #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) 144 | 145 | 146 | /* 147 | * Using 148 | */ 149 | #include 150 | typedef int32_t khronos_int32_t; 151 | typedef uint32_t khronos_uint32_t; 152 | typedef int64_t khronos_int64_t; 153 | typedef uint64_t khronos_uint64_t; 154 | #define KHRONOS_SUPPORT_INT64 1 155 | #define KHRONOS_SUPPORT_FLOAT 1 156 | /* 157 | * To support platform where unsigned long cannot be used interchangeably with 158 | * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. 159 | * Ideally, we could just use (u)intptr_t everywhere, but this could result in 160 | * ABI breakage if khronos_uintptr_t is changed from unsigned long to 161 | * unsigned long long or similar (this results in different C++ name mangling). 162 | * To avoid changes for existing platforms, we restrict usage of intptr_t to 163 | * platforms where the size of a pointer is larger than the size of long. 164 | */ 165 | #if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) 166 | #if __SIZEOF_POINTER__ > __SIZEOF_LONG__ 167 | #define KHRONOS_USE_INTPTR_T 168 | #endif 169 | #endif 170 | 171 | #elif defined(__VMS ) || defined(__sgi) 172 | 173 | /* 174 | * Using 175 | */ 176 | #include 177 | typedef int32_t khronos_int32_t; 178 | typedef uint32_t khronos_uint32_t; 179 | typedef int64_t khronos_int64_t; 180 | typedef uint64_t khronos_uint64_t; 181 | #define KHRONOS_SUPPORT_INT64 1 182 | #define KHRONOS_SUPPORT_FLOAT 1 183 | 184 | #elif defined(_WIN32) && !defined(__SCITECH_SNAP__) 185 | 186 | /* 187 | * Win32 188 | */ 189 | typedef __int32 khronos_int32_t; 190 | typedef unsigned __int32 khronos_uint32_t; 191 | typedef __int64 khronos_int64_t; 192 | typedef unsigned __int64 khronos_uint64_t; 193 | #define KHRONOS_SUPPORT_INT64 1 194 | #define KHRONOS_SUPPORT_FLOAT 1 195 | 196 | #elif defined(__sun__) || defined(__digital__) 197 | 198 | /* 199 | * Sun or Digital 200 | */ 201 | typedef int khronos_int32_t; 202 | typedef unsigned int khronos_uint32_t; 203 | #if defined(__arch64__) || defined(_LP64) 204 | typedef long int khronos_int64_t; 205 | typedef unsigned long int khronos_uint64_t; 206 | #else 207 | typedef long long int khronos_int64_t; 208 | typedef unsigned long long int khronos_uint64_t; 209 | #endif /* __arch64__ */ 210 | #define KHRONOS_SUPPORT_INT64 1 211 | #define KHRONOS_SUPPORT_FLOAT 1 212 | 213 | #elif 0 214 | 215 | /* 216 | * Hypothetical platform with no float or int64 support 217 | */ 218 | typedef int khronos_int32_t; 219 | typedef unsigned int khronos_uint32_t; 220 | #define KHRONOS_SUPPORT_INT64 0 221 | #define KHRONOS_SUPPORT_FLOAT 0 222 | 223 | #else 224 | 225 | /* 226 | * Generic fallback 227 | */ 228 | #include 229 | typedef int32_t khronos_int32_t; 230 | typedef uint32_t khronos_uint32_t; 231 | typedef int64_t khronos_int64_t; 232 | typedef uint64_t khronos_uint64_t; 233 | #define KHRONOS_SUPPORT_INT64 1 234 | #define KHRONOS_SUPPORT_FLOAT 1 235 | 236 | #endif 237 | 238 | 239 | /* 240 | * Types that are (so far) the same on all platforms 241 | */ 242 | typedef signed char khronos_int8_t; 243 | typedef unsigned char khronos_uint8_t; 244 | typedef signed short int khronos_int16_t; 245 | typedef unsigned short int khronos_uint16_t; 246 | 247 | /* 248 | * Types that differ between LLP64 and LP64 architectures - in LLP64, 249 | * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears 250 | * to be the only LLP64 architecture in current use. 251 | */ 252 | #ifdef KHRONOS_USE_INTPTR_T 253 | typedef intptr_t khronos_intptr_t; 254 | typedef uintptr_t khronos_uintptr_t; 255 | #elif defined(_WIN64) 256 | typedef signed long long int khronos_intptr_t; 257 | typedef unsigned long long int khronos_uintptr_t; 258 | #else 259 | typedef signed long int khronos_intptr_t; 260 | typedef unsigned long int khronos_uintptr_t; 261 | #endif 262 | 263 | #if defined(_WIN64) 264 | typedef signed long long int khronos_ssize_t; 265 | typedef unsigned long long int khronos_usize_t; 266 | #else 267 | typedef signed long int khronos_ssize_t; 268 | typedef unsigned long int khronos_usize_t; 269 | #endif 270 | 271 | #if KHRONOS_SUPPORT_FLOAT 272 | /* 273 | * Float type 274 | */ 275 | typedef float khronos_float_t; 276 | #endif 277 | 278 | #if KHRONOS_SUPPORT_INT64 279 | /* Time types 280 | * 281 | * These types can be used to represent a time interval in nanoseconds or 282 | * an absolute Unadjusted System Time. Unadjusted System Time is the number 283 | * of nanoseconds since some arbitrary system event (e.g. since the last 284 | * time the system booted). The Unadjusted System Time is an unsigned 285 | * 64 bit value that wraps back to 0 every 584 years. Time intervals 286 | * may be either signed or unsigned. 287 | */ 288 | typedef khronos_uint64_t khronos_utime_nanoseconds_t; 289 | typedef khronos_int64_t khronos_stime_nanoseconds_t; 290 | #endif 291 | 292 | /* 293 | * Dummy value used to pad enum types to 32 bits. 294 | */ 295 | #ifndef KHRONOS_MAX_ENUM 296 | #define KHRONOS_MAX_ENUM 0x7FFFFFFF 297 | #endif 298 | 299 | /* 300 | * Enumerated boolean type 301 | * 302 | * Values other than zero should be considered to be true. Therefore 303 | * comparisons should not be made against KHRONOS_TRUE. 304 | */ 305 | typedef enum { 306 | KHRONOS_FALSE = 0, 307 | KHRONOS_TRUE = 1, 308 | KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM 309 | } khronos_boolean_enum_t; 310 | 311 | #endif /* __khrplatform_h_ */ 312 | -------------------------------------------------------------------------------- /Libraries/include/GLFW/glfw3native.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * GLFW 3.4 - www.glfw.org 3 | * A library for OpenGL, window and input 4 | *------------------------------------------------------------------------ 5 | * Copyright (c) 2002-2006 Marcus Geelnard 6 | * Copyright (c) 2006-2018 Camilla Löwy 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would 19 | * be appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not 22 | * be misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | * 27 | *************************************************************************/ 28 | 29 | #ifndef _glfw3_native_h_ 30 | #define _glfw3_native_h_ 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | 37 | /************************************************************************* 38 | * Doxygen documentation 39 | *************************************************************************/ 40 | 41 | /*! @file glfw3native.h 42 | * @brief The header of the native access functions. 43 | * 44 | * This is the header file of the native access functions. See @ref native for 45 | * more information. 46 | */ 47 | /*! @defgroup native Native access 48 | * @brief Functions related to accessing native handles. 49 | * 50 | * **By using the native access functions you assert that you know what you're 51 | * doing and how to fix problems caused by using them. If you don't, you 52 | * shouldn't be using them.** 53 | * 54 | * Before the inclusion of @ref glfw3native.h, you may define zero or more 55 | * window system API macro and zero or more context creation API macros. 56 | * 57 | * The chosen backends must match those the library was compiled for. Failure 58 | * to do this will cause a link-time error. 59 | * 60 | * The available window API macros are: 61 | * * `GLFW_EXPOSE_NATIVE_WIN32` 62 | * * `GLFW_EXPOSE_NATIVE_COCOA` 63 | * * `GLFW_EXPOSE_NATIVE_X11` 64 | * * `GLFW_EXPOSE_NATIVE_WAYLAND` 65 | * 66 | * The available context API macros are: 67 | * * `GLFW_EXPOSE_NATIVE_WGL` 68 | * * `GLFW_EXPOSE_NATIVE_NSGL` 69 | * * `GLFW_EXPOSE_NATIVE_GLX` 70 | * * `GLFW_EXPOSE_NATIVE_EGL` 71 | * * `GLFW_EXPOSE_NATIVE_OSMESA` 72 | * 73 | * These macros select which of the native access functions that are declared 74 | * and which platform-specific headers to include. It is then up your (by 75 | * definition platform-specific) code to handle which of these should be 76 | * defined. 77 | * 78 | * If you do not want the platform-specific headers to be included, define 79 | * `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header. 80 | * 81 | * @code 82 | * #define GLFW_EXPOSE_NATIVE_WIN32 83 | * #define GLFW_EXPOSE_NATIVE_WGL 84 | * #define GLFW_NATIVE_INCLUDE_NONE 85 | * #include 86 | * @endcode 87 | */ 88 | 89 | 90 | /************************************************************************* 91 | * System headers and types 92 | *************************************************************************/ 93 | 94 | #if !defined(GLFW_NATIVE_INCLUDE_NONE) 95 | 96 | #if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL) 97 | /* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for 98 | * example to allow applications to correctly declare a GL_KHR_debug callback) 99 | * but windows.h assumes no one will define APIENTRY before it does 100 | */ 101 | #if defined(GLFW_APIENTRY_DEFINED) 102 | #undef APIENTRY 103 | #undef GLFW_APIENTRY_DEFINED 104 | #endif 105 | #include 106 | #endif 107 | 108 | #if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL) 109 | #if defined(__OBJC__) 110 | #import 111 | #else 112 | #include 113 | #include 114 | #endif 115 | #endif 116 | 117 | #if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX) 118 | #include 119 | #include 120 | #endif 121 | 122 | #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) 123 | #include 124 | #endif 125 | 126 | #if defined(GLFW_EXPOSE_NATIVE_WGL) 127 | /* WGL is declared by windows.h */ 128 | #endif 129 | #if defined(GLFW_EXPOSE_NATIVE_NSGL) 130 | /* NSGL is declared by Cocoa.h */ 131 | #endif 132 | #if defined(GLFW_EXPOSE_NATIVE_GLX) 133 | /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by 134 | * default it also acts as an OpenGL header 135 | * However, glx.h will include gl.h, which will define it unconditionally 136 | */ 137 | #if defined(GLFW_GLAPIENTRY_DEFINED) 138 | #undef GLAPIENTRY 139 | #undef GLFW_GLAPIENTRY_DEFINED 140 | #endif 141 | #include 142 | #endif 143 | #if defined(GLFW_EXPOSE_NATIVE_EGL) 144 | #include 145 | #endif 146 | #if defined(GLFW_EXPOSE_NATIVE_OSMESA) 147 | /* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by 148 | * default it also acts as an OpenGL header 149 | * However, osmesa.h will include gl.h, which will define it unconditionally 150 | */ 151 | #if defined(GLFW_GLAPIENTRY_DEFINED) 152 | #undef GLAPIENTRY 153 | #undef GLFW_GLAPIENTRY_DEFINED 154 | #endif 155 | #include 156 | #endif 157 | 158 | #endif /*GLFW_NATIVE_INCLUDE_NONE*/ 159 | 160 | 161 | /************************************************************************* 162 | * Functions 163 | *************************************************************************/ 164 | 165 | #if defined(GLFW_EXPOSE_NATIVE_WIN32) 166 | /*! @brief Returns the adapter device name of the specified monitor. 167 | * 168 | * @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`) 169 | * of the specified monitor, or `NULL` if an [error](@ref error_handling) 170 | * occurred. 171 | * 172 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 173 | * GLFW_PLATFORM_UNAVAILABLE. 174 | * 175 | * @thread_safety This function may be called from any thread. Access is not 176 | * synchronized. 177 | * 178 | * @since Added in version 3.1. 179 | * 180 | * @ingroup native 181 | */ 182 | GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor); 183 | 184 | /*! @brief Returns the display device name of the specified monitor. 185 | * 186 | * @return The UTF-8 encoded display device name (for example 187 | * `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an 188 | * [error](@ref error_handling) occurred. 189 | * 190 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 191 | * GLFW_PLATFORM_UNAVAILABLE. 192 | * 193 | * @thread_safety This function may be called from any thread. Access is not 194 | * synchronized. 195 | * 196 | * @since Added in version 3.1. 197 | * 198 | * @ingroup native 199 | */ 200 | GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor); 201 | 202 | /*! @brief Returns the `HWND` of the specified window. 203 | * 204 | * @return The `HWND` of the specified window, or `NULL` if an 205 | * [error](@ref error_handling) occurred. 206 | * 207 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 208 | * GLFW_PLATFORM_UNAVAILABLE. 209 | * 210 | * @remark The `HDC` associated with the window can be queried with the 211 | * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) 212 | * function. 213 | * @code 214 | * HDC dc = GetDC(glfwGetWin32Window(window)); 215 | * @endcode 216 | * This DC is private and does not need to be released. 217 | * 218 | * @thread_safety This function may be called from any thread. Access is not 219 | * synchronized. 220 | * 221 | * @since Added in version 3.0. 222 | * 223 | * @ingroup native 224 | */ 225 | GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); 226 | #endif 227 | 228 | #if defined(GLFW_EXPOSE_NATIVE_WGL) 229 | /*! @brief Returns the `HGLRC` of the specified window. 230 | * 231 | * @return The `HGLRC` of the specified window, or `NULL` if an 232 | * [error](@ref error_handling) occurred. 233 | * 234 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref 235 | * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. 236 | * 237 | * @remark The `HDC` associated with the window can be queried with the 238 | * [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc) 239 | * function. 240 | * @code 241 | * HDC dc = GetDC(glfwGetWin32Window(window)); 242 | * @endcode 243 | * This DC is private and does not need to be released. 244 | * 245 | * @thread_safety This function may be called from any thread. Access is not 246 | * synchronized. 247 | * 248 | * @since Added in version 3.0. 249 | * 250 | * @ingroup native 251 | */ 252 | GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); 253 | #endif 254 | 255 | #if defined(GLFW_EXPOSE_NATIVE_COCOA) 256 | /*! @brief Returns the `CGDirectDisplayID` of the specified monitor. 257 | * 258 | * @return The `CGDirectDisplayID` of the specified monitor, or 259 | * `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred. 260 | * 261 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 262 | * GLFW_PLATFORM_UNAVAILABLE. 263 | * 264 | * @thread_safety This function may be called from any thread. Access is not 265 | * synchronized. 266 | * 267 | * @since Added in version 3.1. 268 | * 269 | * @ingroup native 270 | */ 271 | GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor); 272 | 273 | /*! @brief Returns the `NSWindow` of the specified window. 274 | * 275 | * @return The `NSWindow` of the specified window, or `nil` if an 276 | * [error](@ref error_handling) occurred. 277 | * 278 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 279 | * GLFW_PLATFORM_UNAVAILABLE. 280 | * 281 | * @thread_safety This function may be called from any thread. Access is not 282 | * synchronized. 283 | * 284 | * @since Added in version 3.0. 285 | * 286 | * @ingroup native 287 | */ 288 | GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); 289 | 290 | /*! @brief Returns the `NSView` of the specified window. 291 | * 292 | * @return The `NSView` of the specified window, or `nil` if an 293 | * [error](@ref error_handling) occurred. 294 | * 295 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 296 | * GLFW_PLATFORM_UNAVAILABLE. 297 | * 298 | * @thread_safety This function may be called from any thread. Access is not 299 | * synchronized. 300 | * 301 | * @since Added in version 3.4. 302 | * 303 | * @ingroup native 304 | */ 305 | GLFWAPI id glfwGetCocoaView(GLFWwindow* window); 306 | #endif 307 | 308 | #if defined(GLFW_EXPOSE_NATIVE_NSGL) 309 | /*! @brief Returns the `NSOpenGLContext` of the specified window. 310 | * 311 | * @return The `NSOpenGLContext` of the specified window, or `nil` if an 312 | * [error](@ref error_handling) occurred. 313 | * 314 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref 315 | * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT. 316 | * 317 | * @thread_safety This function may be called from any thread. Access is not 318 | * synchronized. 319 | * 320 | * @since Added in version 3.0. 321 | * 322 | * @ingroup native 323 | */ 324 | GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); 325 | #endif 326 | 327 | #if defined(GLFW_EXPOSE_NATIVE_X11) 328 | /*! @brief Returns the `Display` used by GLFW. 329 | * 330 | * @return The `Display` used by GLFW, or `NULL` if an 331 | * [error](@ref error_handling) occurred. 332 | * 333 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 334 | * GLFW_PLATFORM_UNAVAILABLE. 335 | * 336 | * @thread_safety This function may be called from any thread. Access is not 337 | * synchronized. 338 | * 339 | * @since Added in version 3.0. 340 | * 341 | * @ingroup native 342 | */ 343 | GLFWAPI Display* glfwGetX11Display(void); 344 | 345 | /*! @brief Returns the `RRCrtc` of the specified monitor. 346 | * 347 | * @return The `RRCrtc` of the specified monitor, or `None` if an 348 | * [error](@ref error_handling) occurred. 349 | * 350 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 351 | * GLFW_PLATFORM_UNAVAILABLE. 352 | * 353 | * @thread_safety This function may be called from any thread. Access is not 354 | * synchronized. 355 | * 356 | * @since Added in version 3.1. 357 | * 358 | * @ingroup native 359 | */ 360 | GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor); 361 | 362 | /*! @brief Returns the `RROutput` of the specified monitor. 363 | * 364 | * @return The `RROutput` of the specified monitor, or `None` if an 365 | * [error](@ref error_handling) occurred. 366 | * 367 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 368 | * GLFW_PLATFORM_UNAVAILABLE. 369 | * 370 | * @thread_safety This function may be called from any thread. Access is not 371 | * synchronized. 372 | * 373 | * @since Added in version 3.1. 374 | * 375 | * @ingroup native 376 | */ 377 | GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor); 378 | 379 | /*! @brief Returns the `Window` of the specified window. 380 | * 381 | * @return The `Window` of the specified window, or `None` if an 382 | * [error](@ref error_handling) occurred. 383 | * 384 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 385 | * GLFW_PLATFORM_UNAVAILABLE. 386 | * 387 | * @thread_safety This function may be called from any thread. Access is not 388 | * synchronized. 389 | * 390 | * @since Added in version 3.0. 391 | * 392 | * @ingroup native 393 | */ 394 | GLFWAPI Window glfwGetX11Window(GLFWwindow* window); 395 | 396 | /*! @brief Sets the current primary selection to the specified string. 397 | * 398 | * @param[in] string A UTF-8 encoded string. 399 | * 400 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref 401 | * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. 402 | * 403 | * @pointer_lifetime The specified string is copied before this function 404 | * returns. 405 | * 406 | * @thread_safety This function must only be called from the main thread. 407 | * 408 | * @sa @ref clipboard 409 | * @sa glfwGetX11SelectionString 410 | * @sa glfwSetClipboardString 411 | * 412 | * @since Added in version 3.3. 413 | * 414 | * @ingroup native 415 | */ 416 | GLFWAPI void glfwSetX11SelectionString(const char* string); 417 | 418 | /*! @brief Returns the contents of the current primary selection as a string. 419 | * 420 | * If the selection is empty or if its contents cannot be converted, `NULL` 421 | * is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated. 422 | * 423 | * @return The contents of the selection as a UTF-8 encoded string, or `NULL` 424 | * if an [error](@ref error_handling) occurred. 425 | * 426 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref 427 | * GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. 428 | * 429 | * @pointer_lifetime The returned string is allocated and freed by GLFW. You 430 | * should not free it yourself. It is valid until the next call to @ref 431 | * glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the 432 | * library is terminated. 433 | * 434 | * @thread_safety This function must only be called from the main thread. 435 | * 436 | * @sa @ref clipboard 437 | * @sa glfwSetX11SelectionString 438 | * @sa glfwGetClipboardString 439 | * 440 | * @since Added in version 3.3. 441 | * 442 | * @ingroup native 443 | */ 444 | GLFWAPI const char* glfwGetX11SelectionString(void); 445 | #endif 446 | 447 | #if defined(GLFW_EXPOSE_NATIVE_GLX) 448 | /*! @brief Returns the `GLXContext` of the specified window. 449 | * 450 | * @return The `GLXContext` of the specified window, or `NULL` if an 451 | * [error](@ref error_handling) occurred. 452 | * 453 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref 454 | * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. 455 | * 456 | * @thread_safety This function may be called from any thread. Access is not 457 | * synchronized. 458 | * 459 | * @since Added in version 3.0. 460 | * 461 | * @ingroup native 462 | */ 463 | GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); 464 | 465 | /*! @brief Returns the `GLXWindow` of the specified window. 466 | * 467 | * @return The `GLXWindow` of the specified window, or `None` if an 468 | * [error](@ref error_handling) occurred. 469 | * 470 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref 471 | * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE. 472 | * 473 | * @thread_safety This function may be called from any thread. Access is not 474 | * synchronized. 475 | * 476 | * @since Added in version 3.2. 477 | * 478 | * @ingroup native 479 | */ 480 | GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); 481 | #endif 482 | 483 | #if defined(GLFW_EXPOSE_NATIVE_WAYLAND) 484 | /*! @brief Returns the `struct wl_display*` used by GLFW. 485 | * 486 | * @return The `struct wl_display*` used by GLFW, or `NULL` if an 487 | * [error](@ref error_handling) occurred. 488 | * 489 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 490 | * GLFW_PLATFORM_UNAVAILABLE. 491 | * 492 | * @thread_safety This function may be called from any thread. Access is not 493 | * synchronized. 494 | * 495 | * @since Added in version 3.2. 496 | * 497 | * @ingroup native 498 | */ 499 | GLFWAPI struct wl_display* glfwGetWaylandDisplay(void); 500 | 501 | /*! @brief Returns the `struct wl_output*` of the specified monitor. 502 | * 503 | * @return The `struct wl_output*` of the specified monitor, or `NULL` if an 504 | * [error](@ref error_handling) occurred. 505 | * 506 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 507 | * GLFW_PLATFORM_UNAVAILABLE. 508 | * 509 | * @thread_safety This function may be called from any thread. Access is not 510 | * synchronized. 511 | * 512 | * @since Added in version 3.2. 513 | * 514 | * @ingroup native 515 | */ 516 | GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor); 517 | 518 | /*! @brief Returns the main `struct wl_surface*` of the specified window. 519 | * 520 | * @return The main `struct wl_surface*` of the specified window, or `NULL` if 521 | * an [error](@ref error_handling) occurred. 522 | * 523 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 524 | * GLFW_PLATFORM_UNAVAILABLE. 525 | * 526 | * @thread_safety This function may be called from any thread. Access is not 527 | * synchronized. 528 | * 529 | * @since Added in version 3.2. 530 | * 531 | * @ingroup native 532 | */ 533 | GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window); 534 | #endif 535 | 536 | #if defined(GLFW_EXPOSE_NATIVE_EGL) 537 | /*! @brief Returns the `EGLDisplay` used by GLFW. 538 | * 539 | * @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an 540 | * [error](@ref error_handling) occurred. 541 | * 542 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. 543 | * 544 | * @remark Because EGL is initialized on demand, this function will return 545 | * `EGL_NO_DISPLAY` until the first context has been created via EGL. 546 | * 547 | * @thread_safety This function may be called from any thread. Access is not 548 | * synchronized. 549 | * 550 | * @since Added in version 3.0. 551 | * 552 | * @ingroup native 553 | */ 554 | GLFWAPI EGLDisplay glfwGetEGLDisplay(void); 555 | 556 | /*! @brief Returns the `EGLContext` of the specified window. 557 | * 558 | * @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an 559 | * [error](@ref error_handling) occurred. 560 | * 561 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 562 | * GLFW_NO_WINDOW_CONTEXT. 563 | * 564 | * @thread_safety This function may be called from any thread. Access is not 565 | * synchronized. 566 | * 567 | * @since Added in version 3.0. 568 | * 569 | * @ingroup native 570 | */ 571 | GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); 572 | 573 | /*! @brief Returns the `EGLSurface` of the specified window. 574 | * 575 | * @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an 576 | * [error](@ref error_handling) occurred. 577 | * 578 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 579 | * GLFW_NO_WINDOW_CONTEXT. 580 | * 581 | * @thread_safety This function may be called from any thread. Access is not 582 | * synchronized. 583 | * 584 | * @since Added in version 3.0. 585 | * 586 | * @ingroup native 587 | */ 588 | GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); 589 | #endif 590 | 591 | #if defined(GLFW_EXPOSE_NATIVE_OSMESA) 592 | /*! @brief Retrieves the color buffer associated with the specified window. 593 | * 594 | * @param[in] window The window whose color buffer to retrieve. 595 | * @param[out] width Where to store the width of the color buffer, or `NULL`. 596 | * @param[out] height Where to store the height of the color buffer, or `NULL`. 597 | * @param[out] format Where to store the OSMesa pixel format of the color 598 | * buffer, or `NULL`. 599 | * @param[out] buffer Where to store the address of the color buffer, or 600 | * `NULL`. 601 | * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an 602 | * [error](@ref error_handling) occurred. 603 | * 604 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 605 | * GLFW_NO_WINDOW_CONTEXT. 606 | * 607 | * @thread_safety This function may be called from any thread. Access is not 608 | * synchronized. 609 | * 610 | * @since Added in version 3.3. 611 | * 612 | * @ingroup native 613 | */ 614 | GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer); 615 | 616 | /*! @brief Retrieves the depth buffer associated with the specified window. 617 | * 618 | * @param[in] window The window whose depth buffer to retrieve. 619 | * @param[out] width Where to store the width of the depth buffer, or `NULL`. 620 | * @param[out] height Where to store the height of the depth buffer, or `NULL`. 621 | * @param[out] bytesPerValue Where to store the number of bytes per depth 622 | * buffer element, or `NULL`. 623 | * @param[out] buffer Where to store the address of the depth buffer, or 624 | * `NULL`. 625 | * @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an 626 | * [error](@ref error_handling) occurred. 627 | * 628 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 629 | * GLFW_NO_WINDOW_CONTEXT. 630 | * 631 | * @thread_safety This function may be called from any thread. Access is not 632 | * synchronized. 633 | * 634 | * @since Added in version 3.3. 635 | * 636 | * @ingroup native 637 | */ 638 | GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer); 639 | 640 | /*! @brief Returns the `OSMesaContext` of the specified window. 641 | * 642 | * @return The `OSMesaContext` of the specified window, or `NULL` if an 643 | * [error](@ref error_handling) occurred. 644 | * 645 | * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref 646 | * GLFW_NO_WINDOW_CONTEXT. 647 | * 648 | * @thread_safety This function may be called from any thread. Access is not 649 | * synchronized. 650 | * 651 | * @since Added in version 3.3. 652 | * 653 | * @ingroup native 654 | */ 655 | GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window); 656 | #endif 657 | 658 | #ifdef __cplusplus 659 | } 660 | #endif 661 | 662 | #endif /* _glfw3_native_h_ */ 663 | 664 | -------------------------------------------------------------------------------- /glad.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | OpenGL loader generated by glad 0.1.36 on Wed Jun 5 17:49:26 2024. 4 | 5 | Language/Generator: C/C++ 6 | Specification: gl 7 | APIs: gl=3.3 8 | Profile: core 9 | Extensions: 10 | 11 | Loader: True 12 | Local files: False 13 | Omit khrplatform: False 14 | Reproducible: False 15 | 16 | Commandline: 17 | --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="" 18 | Online: 19 | https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D3.3 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | static void* get_proc(const char *namez); 28 | 29 | #if defined(_WIN32) || defined(__CYGWIN__) 30 | #ifndef _WINDOWS_ 31 | #undef APIENTRY 32 | #endif 33 | #include 34 | static HMODULE libGL; 35 | 36 | typedef void* (APIENTRYP PFNWGLGETPROCADDRESSPROC_PRIVATE)(const char*); 37 | static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; 38 | 39 | #ifdef _MSC_VER 40 | #ifdef __has_include 41 | #if __has_include() 42 | #define HAVE_WINAPIFAMILY 1 43 | #endif 44 | #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ 45 | #define HAVE_WINAPIFAMILY 1 46 | #endif 47 | #endif 48 | 49 | #ifdef HAVE_WINAPIFAMILY 50 | #include 51 | #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 52 | #define IS_UWP 1 53 | #endif 54 | #endif 55 | 56 | static 57 | int open_gl(void) { 58 | #ifndef IS_UWP 59 | libGL = LoadLibraryW(L"opengl32.dll"); 60 | if(libGL != NULL) { 61 | void (* tmp)(void); 62 | tmp = (void(*)(void)) GetProcAddress(libGL, "wglGetProcAddress"); 63 | gladGetProcAddressPtr = (PFNWGLGETPROCADDRESSPROC_PRIVATE) tmp; 64 | return gladGetProcAddressPtr != NULL; 65 | } 66 | #endif 67 | 68 | return 0; 69 | } 70 | 71 | static 72 | void close_gl(void) { 73 | if(libGL != NULL) { 74 | FreeLibrary((HMODULE) libGL); 75 | libGL = NULL; 76 | } 77 | } 78 | #else 79 | #include 80 | static void* libGL; 81 | 82 | #if !defined(__APPLE__) && !defined(__HAIKU__) 83 | typedef void* (APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char*); 84 | static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr; 85 | #endif 86 | 87 | static 88 | int open_gl(void) { 89 | #ifdef __APPLE__ 90 | static const char *NAMES[] = { 91 | "../Frameworks/OpenGL.framework/OpenGL", 92 | "/Library/Frameworks/OpenGL.framework/OpenGL", 93 | "/System/Library/Frameworks/OpenGL.framework/OpenGL", 94 | "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" 95 | }; 96 | #else 97 | static const char *NAMES[] = {"libGL.so.1", "libGL.so"}; 98 | #endif 99 | 100 | unsigned int index = 0; 101 | for(index = 0; index < (sizeof(NAMES) / sizeof(NAMES[0])); index++) { 102 | libGL = dlopen(NAMES[index], RTLD_NOW | RTLD_GLOBAL); 103 | 104 | if(libGL != NULL) { 105 | #if defined(__APPLE__) || defined(__HAIKU__) 106 | return 1; 107 | #else 108 | gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE)dlsym(libGL, 109 | "glXGetProcAddressARB"); 110 | return gladGetProcAddressPtr != NULL; 111 | #endif 112 | } 113 | } 114 | 115 | return 0; 116 | } 117 | 118 | static 119 | void close_gl(void) { 120 | if(libGL != NULL) { 121 | dlclose(libGL); 122 | libGL = NULL; 123 | } 124 | } 125 | #endif 126 | 127 | static 128 | void* get_proc(const char *namez) { 129 | void* result = NULL; 130 | if(libGL == NULL) return NULL; 131 | 132 | #if !defined(__APPLE__) && !defined(__HAIKU__) 133 | if(gladGetProcAddressPtr != NULL) { 134 | result = gladGetProcAddressPtr(namez); 135 | } 136 | #endif 137 | if(result == NULL) { 138 | #if defined(_WIN32) || defined(__CYGWIN__) 139 | result = (void*)GetProcAddress((HMODULE) libGL, namez); 140 | #else 141 | result = dlsym(libGL, namez); 142 | #endif 143 | } 144 | 145 | return result; 146 | } 147 | 148 | int gladLoadGL(void) { 149 | int status = 0; 150 | 151 | if(open_gl()) { 152 | status = gladLoadGLLoader(&get_proc); 153 | close_gl(); 154 | } 155 | 156 | return status; 157 | } 158 | 159 | struct gladGLversionStruct GLVersion = { 0, 0 }; 160 | 161 | #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) 162 | #define _GLAD_IS_SOME_NEW_VERSION 1 163 | #endif 164 | 165 | static int max_loaded_major; 166 | static int max_loaded_minor; 167 | 168 | static const char *exts = NULL; 169 | static int num_exts_i = 0; 170 | static char **exts_i = NULL; 171 | 172 | static int get_exts(void) { 173 | #ifdef _GLAD_IS_SOME_NEW_VERSION 174 | if(max_loaded_major < 3) { 175 | #endif 176 | exts = (const char *)glGetString(GL_EXTENSIONS); 177 | #ifdef _GLAD_IS_SOME_NEW_VERSION 178 | } else { 179 | unsigned int index; 180 | 181 | num_exts_i = 0; 182 | glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); 183 | if (num_exts_i > 0) { 184 | exts_i = (char **)malloc((size_t)num_exts_i * (sizeof *exts_i)); 185 | } 186 | 187 | if (exts_i == NULL) { 188 | return 0; 189 | } 190 | 191 | for(index = 0; index < (unsigned)num_exts_i; index++) { 192 | const char *gl_str_tmp = (const char*)glGetStringi(GL_EXTENSIONS, index); 193 | size_t len = strlen(gl_str_tmp); 194 | 195 | char *local_str = (char*)malloc((len+1) * sizeof(char)); 196 | if(local_str != NULL) { 197 | memcpy(local_str, gl_str_tmp, (len+1) * sizeof(char)); 198 | } 199 | exts_i[index] = local_str; 200 | } 201 | } 202 | #endif 203 | return 1; 204 | } 205 | 206 | static void free_exts(void) { 207 | if (exts_i != NULL) { 208 | int index; 209 | for(index = 0; index < num_exts_i; index++) { 210 | free((char *)exts_i[index]); 211 | } 212 | free((void *)exts_i); 213 | exts_i = NULL; 214 | } 215 | } 216 | 217 | static int has_ext(const char *ext) { 218 | #ifdef _GLAD_IS_SOME_NEW_VERSION 219 | if(max_loaded_major < 3) { 220 | #endif 221 | const char *extensions; 222 | const char *loc; 223 | const char *terminator; 224 | extensions = exts; 225 | if(extensions == NULL || ext == NULL) { 226 | return 0; 227 | } 228 | 229 | while(1) { 230 | loc = strstr(extensions, ext); 231 | if(loc == NULL) { 232 | return 0; 233 | } 234 | 235 | terminator = loc + strlen(ext); 236 | if((loc == extensions || *(loc - 1) == ' ') && 237 | (*terminator == ' ' || *terminator == '\0')) { 238 | return 1; 239 | } 240 | extensions = terminator; 241 | } 242 | #ifdef _GLAD_IS_SOME_NEW_VERSION 243 | } else { 244 | int index; 245 | if(exts_i == NULL) return 0; 246 | for(index = 0; index < num_exts_i; index++) { 247 | const char *e = exts_i[index]; 248 | 249 | if(exts_i[index] != NULL && strcmp(e, ext) == 0) { 250 | return 1; 251 | } 252 | } 253 | } 254 | #endif 255 | 256 | return 0; 257 | } 258 | int GLAD_GL_VERSION_1_0 = 0; 259 | int GLAD_GL_VERSION_1_1 = 0; 260 | int GLAD_GL_VERSION_1_2 = 0; 261 | int GLAD_GL_VERSION_1_3 = 0; 262 | int GLAD_GL_VERSION_1_4 = 0; 263 | int GLAD_GL_VERSION_1_5 = 0; 264 | int GLAD_GL_VERSION_2_0 = 0; 265 | int GLAD_GL_VERSION_2_1 = 0; 266 | int GLAD_GL_VERSION_3_0 = 0; 267 | int GLAD_GL_VERSION_3_1 = 0; 268 | int GLAD_GL_VERSION_3_2 = 0; 269 | int GLAD_GL_VERSION_3_3 = 0; 270 | PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; 271 | PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; 272 | PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; 273 | PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; 274 | PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; 275 | PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; 276 | PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; 277 | PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; 278 | PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; 279 | PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; 280 | PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; 281 | PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; 282 | PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; 283 | PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; 284 | PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; 285 | PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; 286 | PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; 287 | PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; 288 | PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; 289 | PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; 290 | PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; 291 | PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; 292 | PFNGLBUFFERDATAPROC glad_glBufferData = NULL; 293 | PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; 294 | PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; 295 | PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; 296 | PFNGLCLEARPROC glad_glClear = NULL; 297 | PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; 298 | PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; 299 | PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; 300 | PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; 301 | PFNGLCLEARCOLORPROC glad_glClearColor = NULL; 302 | PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; 303 | PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; 304 | PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; 305 | PFNGLCOLORMASKPROC glad_glColorMask = NULL; 306 | PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; 307 | PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; 308 | PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; 309 | PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; 310 | PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; 311 | PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; 312 | PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; 313 | PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; 314 | PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; 315 | PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; 316 | PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; 317 | PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; 318 | PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; 319 | PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; 320 | PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; 321 | PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; 322 | PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; 323 | PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; 324 | PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; 325 | PFNGLCREATESHADERPROC glad_glCreateShader = NULL; 326 | PFNGLCULLFACEPROC glad_glCullFace = NULL; 327 | PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; 328 | PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; 329 | PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; 330 | PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; 331 | PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; 332 | PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; 333 | PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; 334 | PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; 335 | PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; 336 | PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; 337 | PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; 338 | PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; 339 | PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; 340 | PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; 341 | PFNGLDISABLEPROC glad_glDisable = NULL; 342 | PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; 343 | PFNGLDISABLEIPROC glad_glDisablei = NULL; 344 | PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; 345 | PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; 346 | PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; 347 | PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; 348 | PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; 349 | PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; 350 | PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; 351 | PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; 352 | PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; 353 | PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; 354 | PFNGLENABLEPROC glad_glEnable = NULL; 355 | PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; 356 | PFNGLENABLEIPROC glad_glEnablei = NULL; 357 | PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; 358 | PFNGLENDQUERYPROC glad_glEndQuery = NULL; 359 | PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; 360 | PFNGLFENCESYNCPROC glad_glFenceSync = NULL; 361 | PFNGLFINISHPROC glad_glFinish = NULL; 362 | PFNGLFLUSHPROC glad_glFlush = NULL; 363 | PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; 364 | PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; 365 | PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; 366 | PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; 367 | PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; 368 | PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; 369 | PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; 370 | PFNGLFRONTFACEPROC glad_glFrontFace = NULL; 371 | PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; 372 | PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; 373 | PFNGLGENQUERIESPROC glad_glGenQueries = NULL; 374 | PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; 375 | PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; 376 | PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; 377 | PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; 378 | PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; 379 | PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; 380 | PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; 381 | PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; 382 | PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; 383 | PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; 384 | PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; 385 | PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; 386 | PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; 387 | PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; 388 | PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; 389 | PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; 390 | PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; 391 | PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; 392 | PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; 393 | PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; 394 | PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; 395 | PFNGLGETERRORPROC glad_glGetError = NULL; 396 | PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; 397 | PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; 398 | PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; 399 | PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; 400 | PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; 401 | PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; 402 | PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; 403 | PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; 404 | PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; 405 | PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; 406 | PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; 407 | PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; 408 | PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; 409 | PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; 410 | PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; 411 | PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; 412 | PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; 413 | PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; 414 | PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; 415 | PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; 416 | PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; 417 | PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; 418 | PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; 419 | PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; 420 | PFNGLGETSTRINGPROC glad_glGetString = NULL; 421 | PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; 422 | PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; 423 | PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; 424 | PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; 425 | PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; 426 | PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; 427 | PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; 428 | PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; 429 | PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; 430 | PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; 431 | PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; 432 | PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; 433 | PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; 434 | PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; 435 | PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; 436 | PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; 437 | PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; 438 | PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; 439 | PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; 440 | PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; 441 | PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; 442 | PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; 443 | PFNGLHINTPROC glad_glHint = NULL; 444 | PFNGLISBUFFERPROC glad_glIsBuffer = NULL; 445 | PFNGLISENABLEDPROC glad_glIsEnabled = NULL; 446 | PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; 447 | PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; 448 | PFNGLISPROGRAMPROC glad_glIsProgram = NULL; 449 | PFNGLISQUERYPROC glad_glIsQuery = NULL; 450 | PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; 451 | PFNGLISSAMPLERPROC glad_glIsSampler = NULL; 452 | PFNGLISSHADERPROC glad_glIsShader = NULL; 453 | PFNGLISSYNCPROC glad_glIsSync = NULL; 454 | PFNGLISTEXTUREPROC glad_glIsTexture = NULL; 455 | PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; 456 | PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; 457 | PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; 458 | PFNGLLOGICOPPROC glad_glLogicOp = NULL; 459 | PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; 460 | PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; 461 | PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; 462 | PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; 463 | PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; 464 | PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; 465 | PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; 466 | PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; 467 | PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; 468 | PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; 469 | PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; 470 | PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; 471 | PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; 472 | PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; 473 | PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; 474 | PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; 475 | PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; 476 | PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; 477 | PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; 478 | PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; 479 | PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; 480 | PFNGLPOINTSIZEPROC glad_glPointSize = NULL; 481 | PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; 482 | PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; 483 | PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; 484 | PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; 485 | PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; 486 | PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; 487 | PFNGLREADPIXELSPROC glad_glReadPixels = NULL; 488 | PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; 489 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; 490 | PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; 491 | PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; 492 | PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; 493 | PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; 494 | PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; 495 | PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; 496 | PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; 497 | PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; 498 | PFNGLSCISSORPROC glad_glScissor = NULL; 499 | PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; 500 | PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; 501 | PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; 502 | PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; 503 | PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; 504 | PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; 505 | PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; 506 | PFNGLSTENCILOPPROC glad_glStencilOp = NULL; 507 | PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; 508 | PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; 509 | PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; 510 | PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; 511 | PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; 512 | PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; 513 | PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; 514 | PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; 515 | PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; 516 | PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; 517 | PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; 518 | PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; 519 | PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; 520 | PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; 521 | PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; 522 | PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; 523 | PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; 524 | PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; 525 | PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; 526 | PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; 527 | PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; 528 | PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; 529 | PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; 530 | PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; 531 | PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; 532 | PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; 533 | PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; 534 | PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; 535 | PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; 536 | PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; 537 | PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; 538 | PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; 539 | PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; 540 | PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; 541 | PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; 542 | PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; 543 | PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; 544 | PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; 545 | PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; 546 | PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; 547 | PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; 548 | PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; 549 | PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; 550 | PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; 551 | PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; 552 | PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; 553 | PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; 554 | PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; 555 | PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; 556 | PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; 557 | PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; 558 | PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; 559 | PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; 560 | PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; 561 | PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; 562 | PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; 563 | PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; 564 | PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; 565 | PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; 566 | PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; 567 | PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; 568 | PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; 569 | PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; 570 | PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; 571 | PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; 572 | PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; 573 | PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; 574 | PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; 575 | PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; 576 | PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; 577 | PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; 578 | PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; 579 | PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; 580 | PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; 581 | PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; 582 | PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; 583 | PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; 584 | PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; 585 | PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; 586 | PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; 587 | PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; 588 | PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; 589 | PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; 590 | PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; 591 | PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; 592 | PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; 593 | PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; 594 | PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; 595 | PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; 596 | PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; 597 | PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; 598 | PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; 599 | PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; 600 | PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; 601 | PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; 602 | PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; 603 | PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; 604 | PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; 605 | PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; 606 | PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; 607 | PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; 608 | PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; 609 | PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; 610 | PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; 611 | PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; 612 | PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; 613 | PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; 614 | PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; 615 | PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; 616 | PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; 617 | PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; 618 | PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; 619 | PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; 620 | PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; 621 | PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; 622 | PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; 623 | PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; 624 | PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; 625 | PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; 626 | PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; 627 | PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; 628 | PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; 629 | PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; 630 | PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; 631 | PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; 632 | PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; 633 | PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; 634 | PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; 635 | PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; 636 | PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; 637 | PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; 638 | PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; 639 | PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; 640 | PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; 641 | PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; 642 | PFNGLVIEWPORTPROC glad_glViewport = NULL; 643 | PFNGLWAITSYNCPROC glad_glWaitSync = NULL; 644 | static void load_GL_VERSION_1_0(GLADloadproc load) { 645 | if(!GLAD_GL_VERSION_1_0) return; 646 | glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); 647 | glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace"); 648 | glad_glHint = (PFNGLHINTPROC)load("glHint"); 649 | glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth"); 650 | glad_glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize"); 651 | glad_glPolygonMode = (PFNGLPOLYGONMODEPROC)load("glPolygonMode"); 652 | glad_glScissor = (PFNGLSCISSORPROC)load("glScissor"); 653 | glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf"); 654 | glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv"); 655 | glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri"); 656 | glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv"); 657 | glad_glTexImage1D = (PFNGLTEXIMAGE1DPROC)load("glTexImage1D"); 658 | glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D"); 659 | glad_glDrawBuffer = (PFNGLDRAWBUFFERPROC)load("glDrawBuffer"); 660 | glad_glClear = (PFNGLCLEARPROC)load("glClear"); 661 | glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor"); 662 | glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil"); 663 | glad_glClearDepth = (PFNGLCLEARDEPTHPROC)load("glClearDepth"); 664 | glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask"); 665 | glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask"); 666 | glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask"); 667 | glad_glDisable = (PFNGLDISABLEPROC)load("glDisable"); 668 | glad_glEnable = (PFNGLENABLEPROC)load("glEnable"); 669 | glad_glFinish = (PFNGLFINISHPROC)load("glFinish"); 670 | glad_glFlush = (PFNGLFLUSHPROC)load("glFlush"); 671 | glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc"); 672 | glad_glLogicOp = (PFNGLLOGICOPPROC)load("glLogicOp"); 673 | glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc"); 674 | glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp"); 675 | glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc"); 676 | glad_glPixelStoref = (PFNGLPIXELSTOREFPROC)load("glPixelStoref"); 677 | glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei"); 678 | glad_glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer"); 679 | glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels"); 680 | glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv"); 681 | glad_glGetDoublev = (PFNGLGETDOUBLEVPROC)load("glGetDoublev"); 682 | glad_glGetError = (PFNGLGETERRORPROC)load("glGetError"); 683 | glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv"); 684 | glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv"); 685 | glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); 686 | glad_glGetTexImage = (PFNGLGETTEXIMAGEPROC)load("glGetTexImage"); 687 | glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv"); 688 | glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv"); 689 | glad_glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv"); 690 | glad_glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv"); 691 | glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled"); 692 | glad_glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange"); 693 | glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport"); 694 | } 695 | static void load_GL_VERSION_1_1(GLADloadproc load) { 696 | if(!GLAD_GL_VERSION_1_1) return; 697 | glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays"); 698 | glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements"); 699 | glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset"); 700 | glad_glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D"); 701 | glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D"); 702 | glad_glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)load("glCopyTexSubImage1D"); 703 | glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D"); 704 | glad_glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)load("glTexSubImage1D"); 705 | glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D"); 706 | glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture"); 707 | glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures"); 708 | glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures"); 709 | glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture"); 710 | } 711 | static void load_GL_VERSION_1_2(GLADloadproc load) { 712 | if(!GLAD_GL_VERSION_1_2) return; 713 | glad_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements"); 714 | glad_glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D"); 715 | glad_glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D"); 716 | glad_glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D"); 717 | } 718 | static void load_GL_VERSION_1_3(GLADloadproc load) { 719 | if(!GLAD_GL_VERSION_1_3) return; 720 | glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture"); 721 | glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage"); 722 | glad_glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D"); 723 | glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D"); 724 | glad_glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)load("glCompressedTexImage1D"); 725 | glad_glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D"); 726 | glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D"); 727 | glad_glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D"); 728 | glad_glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage"); 729 | } 730 | static void load_GL_VERSION_1_4(GLADloadproc load) { 731 | if(!GLAD_GL_VERSION_1_4) return; 732 | glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate"); 733 | glad_glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)load("glMultiDrawArrays"); 734 | glad_glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)load("glMultiDrawElements"); 735 | glad_glPointParameterf = (PFNGLPOINTPARAMETERFPROC)load("glPointParameterf"); 736 | glad_glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv"); 737 | glad_glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri"); 738 | glad_glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv"); 739 | glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor"); 740 | glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation"); 741 | } 742 | static void load_GL_VERSION_1_5(GLADloadproc load) { 743 | if(!GLAD_GL_VERSION_1_5) return; 744 | glad_glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries"); 745 | glad_glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries"); 746 | glad_glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery"); 747 | glad_glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery"); 748 | glad_glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery"); 749 | glad_glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv"); 750 | glad_glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)load("glGetQueryObjectiv"); 751 | glad_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv"); 752 | glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer"); 753 | glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers"); 754 | glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers"); 755 | glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer"); 756 | glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData"); 757 | glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData"); 758 | glad_glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)load("glGetBufferSubData"); 759 | glad_glMapBuffer = (PFNGLMAPBUFFERPROC)load("glMapBuffer"); 760 | glad_glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer"); 761 | glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv"); 762 | glad_glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv"); 763 | } 764 | static void load_GL_VERSION_2_0(GLADloadproc load) { 765 | if(!GLAD_GL_VERSION_2_0) return; 766 | glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate"); 767 | glad_glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers"); 768 | glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate"); 769 | glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate"); 770 | glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate"); 771 | glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader"); 772 | glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation"); 773 | glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader"); 774 | glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram"); 775 | glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader"); 776 | glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram"); 777 | glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader"); 778 | glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader"); 779 | glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray"); 780 | glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray"); 781 | glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib"); 782 | glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform"); 783 | glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders"); 784 | glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation"); 785 | glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv"); 786 | glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog"); 787 | glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv"); 788 | glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog"); 789 | glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource"); 790 | glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation"); 791 | glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv"); 792 | glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv"); 793 | glad_glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)load("glGetVertexAttribdv"); 794 | glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv"); 795 | glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv"); 796 | glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv"); 797 | glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram"); 798 | glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader"); 799 | glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram"); 800 | glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource"); 801 | glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram"); 802 | glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f"); 803 | glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f"); 804 | glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f"); 805 | glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f"); 806 | glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i"); 807 | glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i"); 808 | glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i"); 809 | glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i"); 810 | glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv"); 811 | glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv"); 812 | glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv"); 813 | glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv"); 814 | glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv"); 815 | glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv"); 816 | glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv"); 817 | glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv"); 818 | glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv"); 819 | glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv"); 820 | glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv"); 821 | glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram"); 822 | glad_glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)load("glVertexAttrib1d"); 823 | glad_glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)load("glVertexAttrib1dv"); 824 | glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f"); 825 | glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv"); 826 | glad_glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)load("glVertexAttrib1s"); 827 | glad_glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)load("glVertexAttrib1sv"); 828 | glad_glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)load("glVertexAttrib2d"); 829 | glad_glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)load("glVertexAttrib2dv"); 830 | glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f"); 831 | glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv"); 832 | glad_glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)load("glVertexAttrib2s"); 833 | glad_glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)load("glVertexAttrib2sv"); 834 | glad_glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)load("glVertexAttrib3d"); 835 | glad_glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)load("glVertexAttrib3dv"); 836 | glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f"); 837 | glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv"); 838 | glad_glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)load("glVertexAttrib3s"); 839 | glad_glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)load("glVertexAttrib3sv"); 840 | glad_glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)load("glVertexAttrib4Nbv"); 841 | glad_glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)load("glVertexAttrib4Niv"); 842 | glad_glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)load("glVertexAttrib4Nsv"); 843 | glad_glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)load("glVertexAttrib4Nub"); 844 | glad_glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)load("glVertexAttrib4Nubv"); 845 | glad_glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)load("glVertexAttrib4Nuiv"); 846 | glad_glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)load("glVertexAttrib4Nusv"); 847 | glad_glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)load("glVertexAttrib4bv"); 848 | glad_glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)load("glVertexAttrib4d"); 849 | glad_glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)load("glVertexAttrib4dv"); 850 | glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f"); 851 | glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv"); 852 | glad_glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)load("glVertexAttrib4iv"); 853 | glad_glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)load("glVertexAttrib4s"); 854 | glad_glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)load("glVertexAttrib4sv"); 855 | glad_glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)load("glVertexAttrib4ubv"); 856 | glad_glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)load("glVertexAttrib4uiv"); 857 | glad_glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)load("glVertexAttrib4usv"); 858 | glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer"); 859 | } 860 | static void load_GL_VERSION_2_1(GLADloadproc load) { 861 | if(!GLAD_GL_VERSION_2_1) return; 862 | glad_glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv"); 863 | glad_glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv"); 864 | glad_glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv"); 865 | glad_glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv"); 866 | glad_glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv"); 867 | glad_glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv"); 868 | } 869 | static void load_GL_VERSION_3_0(GLADloadproc load) { 870 | if(!GLAD_GL_VERSION_3_0) return; 871 | glad_glColorMaski = (PFNGLCOLORMASKIPROC)load("glColorMaski"); 872 | glad_glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v"); 873 | glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); 874 | glad_glEnablei = (PFNGLENABLEIPROC)load("glEnablei"); 875 | glad_glDisablei = (PFNGLDISABLEIPROC)load("glDisablei"); 876 | glad_glIsEnabledi = (PFNGLISENABLEDIPROC)load("glIsEnabledi"); 877 | glad_glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback"); 878 | glad_glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback"); 879 | glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); 880 | glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); 881 | glad_glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings"); 882 | glad_glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying"); 883 | glad_glClampColor = (PFNGLCLAMPCOLORPROC)load("glClampColor"); 884 | glad_glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)load("glBeginConditionalRender"); 885 | glad_glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)load("glEndConditionalRender"); 886 | glad_glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer"); 887 | glad_glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv"); 888 | glad_glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv"); 889 | glad_glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)load("glVertexAttribI1i"); 890 | glad_glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)load("glVertexAttribI2i"); 891 | glad_glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)load("glVertexAttribI3i"); 892 | glad_glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i"); 893 | glad_glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)load("glVertexAttribI1ui"); 894 | glad_glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)load("glVertexAttribI2ui"); 895 | glad_glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)load("glVertexAttribI3ui"); 896 | glad_glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui"); 897 | glad_glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)load("glVertexAttribI1iv"); 898 | glad_glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)load("glVertexAttribI2iv"); 899 | glad_glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)load("glVertexAttribI3iv"); 900 | glad_glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv"); 901 | glad_glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)load("glVertexAttribI1uiv"); 902 | glad_glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)load("glVertexAttribI2uiv"); 903 | glad_glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)load("glVertexAttribI3uiv"); 904 | glad_glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv"); 905 | glad_glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)load("glVertexAttribI4bv"); 906 | glad_glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)load("glVertexAttribI4sv"); 907 | glad_glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)load("glVertexAttribI4ubv"); 908 | glad_glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)load("glVertexAttribI4usv"); 909 | glad_glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv"); 910 | glad_glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)load("glBindFragDataLocation"); 911 | glad_glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation"); 912 | glad_glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui"); 913 | glad_glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui"); 914 | glad_glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui"); 915 | glad_glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui"); 916 | glad_glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv"); 917 | glad_glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv"); 918 | glad_glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv"); 919 | glad_glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv"); 920 | glad_glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)load("glTexParameterIiv"); 921 | glad_glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)load("glTexParameterIuiv"); 922 | glad_glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)load("glGetTexParameterIiv"); 923 | glad_glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)load("glGetTexParameterIuiv"); 924 | glad_glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv"); 925 | glad_glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv"); 926 | glad_glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv"); 927 | glad_glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi"); 928 | glad_glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi"); 929 | glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer"); 930 | glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer"); 931 | glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers"); 932 | glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers"); 933 | glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage"); 934 | glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv"); 935 | glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer"); 936 | glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer"); 937 | glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers"); 938 | glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers"); 939 | glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus"); 940 | glad_glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D"); 941 | glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D"); 942 | glad_glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D"); 943 | glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer"); 944 | glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv"); 945 | glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap"); 946 | glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer"); 947 | glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample"); 948 | glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer"); 949 | glad_glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange"); 950 | glad_glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange"); 951 | glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray"); 952 | glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays"); 953 | glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); 954 | glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); 955 | } 956 | static void load_GL_VERSION_3_1(GLADloadproc load) { 957 | if(!GLAD_GL_VERSION_3_1) return; 958 | glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); 959 | glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); 960 | glad_glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer"); 961 | glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex"); 962 | glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); 963 | glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); 964 | glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); 965 | glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName"); 966 | glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); 967 | glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); 968 | glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); 969 | glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); 970 | glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); 971 | glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); 972 | glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); 973 | } 974 | static void load_GL_VERSION_3_2(GLADloadproc load) { 975 | if(!GLAD_GL_VERSION_3_2) return; 976 | glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex"); 977 | glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex"); 978 | glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex"); 979 | glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex"); 980 | glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex"); 981 | glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); 982 | glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); 983 | glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); 984 | glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); 985 | glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); 986 | glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); 987 | glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); 988 | glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); 989 | glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); 990 | glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture"); 991 | glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample"); 992 | glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample"); 993 | glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); 994 | glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); 995 | } 996 | static void load_GL_VERSION_3_3(GLADloadproc load) { 997 | if(!GLAD_GL_VERSION_3_3) return; 998 | glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)load("glBindFragDataLocationIndexed"); 999 | glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)load("glGetFragDataIndex"); 1000 | glad_glGenSamplers = (PFNGLGENSAMPLERSPROC)load("glGenSamplers"); 1001 | glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)load("glDeleteSamplers"); 1002 | glad_glIsSampler = (PFNGLISSAMPLERPROC)load("glIsSampler"); 1003 | glad_glBindSampler = (PFNGLBINDSAMPLERPROC)load("glBindSampler"); 1004 | glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)load("glSamplerParameteri"); 1005 | glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)load("glSamplerParameteriv"); 1006 | glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)load("glSamplerParameterf"); 1007 | glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)load("glSamplerParameterfv"); 1008 | glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)load("glSamplerParameterIiv"); 1009 | glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)load("glSamplerParameterIuiv"); 1010 | glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)load("glGetSamplerParameteriv"); 1011 | glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)load("glGetSamplerParameterIiv"); 1012 | glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)load("glGetSamplerParameterfv"); 1013 | glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)load("glGetSamplerParameterIuiv"); 1014 | glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC)load("glQueryCounter"); 1015 | glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)load("glGetQueryObjecti64v"); 1016 | glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)load("glGetQueryObjectui64v"); 1017 | glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)load("glVertexAttribDivisor"); 1018 | glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)load("glVertexAttribP1ui"); 1019 | glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)load("glVertexAttribP1uiv"); 1020 | glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)load("glVertexAttribP2ui"); 1021 | glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)load("glVertexAttribP2uiv"); 1022 | glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)load("glVertexAttribP3ui"); 1023 | glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)load("glVertexAttribP3uiv"); 1024 | glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)load("glVertexAttribP4ui"); 1025 | glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)load("glVertexAttribP4uiv"); 1026 | glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC)load("glVertexP2ui"); 1027 | glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)load("glVertexP2uiv"); 1028 | glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC)load("glVertexP3ui"); 1029 | glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)load("glVertexP3uiv"); 1030 | glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC)load("glVertexP4ui"); 1031 | glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)load("glVertexP4uiv"); 1032 | glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)load("glTexCoordP1ui"); 1033 | glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)load("glTexCoordP1uiv"); 1034 | glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)load("glTexCoordP2ui"); 1035 | glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)load("glTexCoordP2uiv"); 1036 | glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)load("glTexCoordP3ui"); 1037 | glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)load("glTexCoordP3uiv"); 1038 | glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)load("glTexCoordP4ui"); 1039 | glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)load("glTexCoordP4uiv"); 1040 | glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)load("glMultiTexCoordP1ui"); 1041 | glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)load("glMultiTexCoordP1uiv"); 1042 | glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)load("glMultiTexCoordP2ui"); 1043 | glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)load("glMultiTexCoordP2uiv"); 1044 | glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)load("glMultiTexCoordP3ui"); 1045 | glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)load("glMultiTexCoordP3uiv"); 1046 | glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)load("glMultiTexCoordP4ui"); 1047 | glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)load("glMultiTexCoordP4uiv"); 1048 | glad_glNormalP3ui = (PFNGLNORMALP3UIPROC)load("glNormalP3ui"); 1049 | glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC)load("glNormalP3uiv"); 1050 | glad_glColorP3ui = (PFNGLCOLORP3UIPROC)load("glColorP3ui"); 1051 | glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC)load("glColorP3uiv"); 1052 | glad_glColorP4ui = (PFNGLCOLORP4UIPROC)load("glColorP4ui"); 1053 | glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC)load("glColorP4uiv"); 1054 | glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui"); 1055 | glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv"); 1056 | } 1057 | static int find_extensionsGL(void) { 1058 | if (!get_exts()) return 0; 1059 | (void)&has_ext; 1060 | free_exts(); 1061 | return 1; 1062 | } 1063 | 1064 | static void find_coreGL(void) { 1065 | 1066 | /* Thank you @elmindreda 1067 | * https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176 1068 | * https://github.com/glfw/glfw/blob/master/src/context.c#L36 1069 | */ 1070 | int i, major, minor; 1071 | 1072 | const char* version; 1073 | const char* prefixes[] = { 1074 | "OpenGL ES-CM ", 1075 | "OpenGL ES-CL ", 1076 | "OpenGL ES ", 1077 | NULL 1078 | }; 1079 | 1080 | version = (const char*) glGetString(GL_VERSION); 1081 | if (!version) return; 1082 | 1083 | for (i = 0; prefixes[i]; i++) { 1084 | const size_t length = strlen(prefixes[i]); 1085 | if (strncmp(version, prefixes[i], length) == 0) { 1086 | version += length; 1087 | break; 1088 | } 1089 | } 1090 | 1091 | /* PR #18 */ 1092 | #ifdef _MSC_VER 1093 | sscanf_s(version, "%d.%d", &major, &minor); 1094 | #else 1095 | sscanf(version, "%d.%d", &major, &minor); 1096 | #endif 1097 | 1098 | GLVersion.major = major; GLVersion.minor = minor; 1099 | max_loaded_major = major; max_loaded_minor = minor; 1100 | GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; 1101 | GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; 1102 | GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; 1103 | GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; 1104 | GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; 1105 | GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; 1106 | GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; 1107 | GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; 1108 | GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; 1109 | GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; 1110 | GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; 1111 | GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; 1112 | if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 3)) { 1113 | max_loaded_major = 3; 1114 | max_loaded_minor = 3; 1115 | } 1116 | } 1117 | 1118 | int gladLoadGLLoader(GLADloadproc load) { 1119 | GLVersion.major = 0; GLVersion.minor = 0; 1120 | glGetString = (PFNGLGETSTRINGPROC)load("glGetString"); 1121 | if(glGetString == NULL) return 0; 1122 | if(glGetString(GL_VERSION) == NULL) return 0; 1123 | find_coreGL(); 1124 | load_GL_VERSION_1_0(load); 1125 | load_GL_VERSION_1_1(load); 1126 | load_GL_VERSION_1_2(load); 1127 | load_GL_VERSION_1_3(load); 1128 | load_GL_VERSION_1_4(load); 1129 | load_GL_VERSION_1_5(load); 1130 | load_GL_VERSION_2_0(load); 1131 | load_GL_VERSION_2_1(load); 1132 | load_GL_VERSION_3_0(load); 1133 | load_GL_VERSION_3_1(load); 1134 | load_GL_VERSION_3_2(load); 1135 | load_GL_VERSION_3_3(load); 1136 | 1137 | if (!find_extensionsGL()) return 0; 1138 | return GLVersion.major != 0 || GLVersion.minor != 0; 1139 | } 1140 | 1141 | -------------------------------------------------------------------------------- /Libraries/include/stb/stb_image_write.h: -------------------------------------------------------------------------------- 1 | /* stb_image_write - v1.16 - public domain - http://nothings.org/stb 2 | writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 3 | no warranty implied; use at your own risk 4 | 5 | Before #including, 6 | 7 | #define STB_IMAGE_WRITE_IMPLEMENTATION 8 | 9 | in the file that you want to have the implementation. 10 | 11 | Will probably not work correctly with strict-aliasing optimizations. 12 | 13 | ABOUT: 14 | 15 | This header file is a library for writing images to C stdio or a callback. 16 | 17 | The PNG output is not optimal; it is 20-50% larger than the file 18 | written by a decent optimizing implementation; though providing a custom 19 | zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. 20 | This library is designed for source code compactness and simplicity, 21 | not optimal image file size or run-time performance. 22 | 23 | BUILDING: 24 | 25 | You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. 26 | You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace 27 | malloc,realloc,free. 28 | You can #define STBIW_MEMMOVE() to replace memmove() 29 | You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function 30 | for PNG compression (instead of the builtin one), it must have the following signature: 31 | unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); 32 | The returned data will be freed with STBIW_FREE() (free() by default), 33 | so it must be heap allocated with STBIW_MALLOC() (malloc() by default), 34 | 35 | UNICODE: 36 | 37 | If compiling for Windows and you wish to use Unicode filenames, compile 38 | with 39 | #define STBIW_WINDOWS_UTF8 40 | and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert 41 | Windows wchar_t filenames to utf8. 42 | 43 | USAGE: 44 | 45 | There are five functions, one for each image file format: 46 | 47 | int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 48 | int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); 49 | int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); 50 | int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); 51 | int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); 52 | 53 | void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically 54 | 55 | There are also five equivalent functions that use an arbitrary write function. You are 56 | expected to open/close your file-equivalent before and after calling these: 57 | 58 | int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); 59 | int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 60 | int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 61 | int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); 62 | int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); 63 | 64 | where the callback is: 65 | void stbi_write_func(void *context, void *data, int size); 66 | 67 | You can configure it with these global variables: 68 | int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE 69 | int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression 70 | int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode 71 | 72 | 73 | You can define STBI_WRITE_NO_STDIO to disable the file variant of these 74 | functions, so the library will not use stdio.h at all. However, this will 75 | also disable HDR writing, because it requires stdio for formatted output. 76 | 77 | Each function returns 0 on failure and non-0 on success. 78 | 79 | The functions create an image file defined by the parameters. The image 80 | is a rectangle of pixels stored from left-to-right, top-to-bottom. 81 | Each pixel contains 'comp' channels of data stored interleaved with 8-bits 82 | per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is 83 | monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. 84 | The *data pointer points to the first byte of the top-left-most pixel. 85 | For PNG, "stride_in_bytes" is the distance in bytes from the first byte of 86 | a row of pixels to the first byte of the next row of pixels. 87 | 88 | PNG creates output files with the same number of components as the input. 89 | The BMP format expands Y to RGB in the file format and does not 90 | output alpha. 91 | 92 | PNG supports writing rectangles of data even when the bytes storing rows of 93 | data are not consecutive in memory (e.g. sub-rectangles of a larger image), 94 | by supplying the stride between the beginning of adjacent rows. The other 95 | formats do not. (Thus you cannot write a native-format BMP through the BMP 96 | writer, both because it is in BGR order and because it may have padding 97 | at the end of the line.) 98 | 99 | PNG allows you to set the deflate compression level by setting the global 100 | variable 'stbi_write_png_compression_level' (it defaults to 8). 101 | 102 | HDR expects linear float data. Since the format is always 32-bit rgb(e) 103 | data, alpha (if provided) is discarded, and for monochrome data it is 104 | replicated across all three channels. 105 | 106 | TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed 107 | data, set the global variable 'stbi_write_tga_with_rle' to 0. 108 | 109 | JPEG does ignore alpha channels in input data; quality is between 1 and 100. 110 | Higher quality looks better but results in a bigger image. 111 | JPEG baseline (no JPEG progressive). 112 | 113 | CREDITS: 114 | 115 | 116 | Sean Barrett - PNG/BMP/TGA 117 | Baldur Karlsson - HDR 118 | Jean-Sebastien Guay - TGA monochrome 119 | Tim Kelsey - misc enhancements 120 | Alan Hickman - TGA RLE 121 | Emmanuel Julien - initial file IO callback implementation 122 | Jon Olick - original jo_jpeg.cpp code 123 | Daniel Gibson - integrate JPEG, allow external zlib 124 | Aarni Koskela - allow choosing PNG filter 125 | 126 | bugfixes: 127 | github:Chribba 128 | Guillaume Chereau 129 | github:jry2 130 | github:romigrou 131 | Sergio Gonzalez 132 | Jonas Karlsson 133 | Filip Wasil 134 | Thatcher Ulrich 135 | github:poppolopoppo 136 | Patrick Boettcher 137 | github:xeekworx 138 | Cap Petschulat 139 | Simon Rodriguez 140 | Ivan Tikhonov 141 | github:ignotion 142 | Adam Schackart 143 | Andrew Kensler 144 | 145 | LICENSE 146 | 147 | See end of file for license information. 148 | 149 | */ 150 | 151 | #ifndef INCLUDE_STB_IMAGE_WRITE_H 152 | #define INCLUDE_STB_IMAGE_WRITE_H 153 | 154 | #include 155 | 156 | // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline' 157 | #ifndef STBIWDEF 158 | #ifdef STB_IMAGE_WRITE_STATIC 159 | #define STBIWDEF static 160 | #else 161 | #ifdef __cplusplus 162 | #define STBIWDEF extern "C" 163 | #else 164 | #define STBIWDEF extern 165 | #endif 166 | #endif 167 | #endif 168 | 169 | #ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations 170 | STBIWDEF int stbi_write_tga_with_rle; 171 | STBIWDEF int stbi_write_png_compression_level; 172 | STBIWDEF int stbi_write_force_png_filter; 173 | #endif 174 | 175 | #ifndef STBI_WRITE_NO_STDIO 176 | STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); 177 | STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); 178 | STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); 179 | STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); 180 | STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); 181 | 182 | #ifdef STBIW_WINDOWS_UTF8 183 | STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); 184 | #endif 185 | #endif 186 | 187 | typedef void stbi_write_func(void *context, void *data, int size); 188 | 189 | STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); 190 | STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 191 | STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); 192 | STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); 193 | STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); 194 | 195 | STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); 196 | 197 | #endif//INCLUDE_STB_IMAGE_WRITE_H 198 | 199 | #ifdef STB_IMAGE_WRITE_IMPLEMENTATION 200 | 201 | #ifdef _WIN32 202 | #ifndef _CRT_SECURE_NO_WARNINGS 203 | #define _CRT_SECURE_NO_WARNINGS 204 | #endif 205 | #ifndef _CRT_NONSTDC_NO_DEPRECATE 206 | #define _CRT_NONSTDC_NO_DEPRECATE 207 | #endif 208 | #endif 209 | 210 | #ifndef STBI_WRITE_NO_STDIO 211 | #include 212 | #endif // STBI_WRITE_NO_STDIO 213 | 214 | #include 215 | #include 216 | #include 217 | #include 218 | 219 | #if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) 220 | // ok 221 | #elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) 222 | // ok 223 | #else 224 | #error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." 225 | #endif 226 | 227 | #ifndef STBIW_MALLOC 228 | #define STBIW_MALLOC(sz) malloc(sz) 229 | #define STBIW_REALLOC(p,newsz) realloc(p,newsz) 230 | #define STBIW_FREE(p) free(p) 231 | #endif 232 | 233 | #ifndef STBIW_REALLOC_SIZED 234 | #define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) 235 | #endif 236 | 237 | 238 | #ifndef STBIW_MEMMOVE 239 | #define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) 240 | #endif 241 | 242 | 243 | #ifndef STBIW_ASSERT 244 | #include 245 | #define STBIW_ASSERT(x) assert(x) 246 | #endif 247 | 248 | #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) 249 | 250 | #ifdef STB_IMAGE_WRITE_STATIC 251 | static int stbi_write_png_compression_level = 8; 252 | static int stbi_write_tga_with_rle = 1; 253 | static int stbi_write_force_png_filter = -1; 254 | #else 255 | int stbi_write_png_compression_level = 8; 256 | int stbi_write_tga_with_rle = 1; 257 | int stbi_write_force_png_filter = -1; 258 | #endif 259 | 260 | static int stbi__flip_vertically_on_write = 0; 261 | 262 | STBIWDEF void stbi_flip_vertically_on_write(int flag) 263 | { 264 | stbi__flip_vertically_on_write = flag; 265 | } 266 | 267 | typedef struct 268 | { 269 | stbi_write_func *func; 270 | void *context; 271 | unsigned char buffer[64]; 272 | int buf_used; 273 | } stbi__write_context; 274 | 275 | // initialize a callback-based context 276 | static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) 277 | { 278 | s->func = c; 279 | s->context = context; 280 | } 281 | 282 | #ifndef STBI_WRITE_NO_STDIO 283 | 284 | static void stbi__stdio_write(void *context, void *data, int size) 285 | { 286 | fwrite(data,1,size,(FILE*) context); 287 | } 288 | 289 | #if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) 290 | #ifdef __cplusplus 291 | #define STBIW_EXTERN extern "C" 292 | #else 293 | #define STBIW_EXTERN extern 294 | #endif 295 | STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); 296 | STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); 297 | 298 | STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) 299 | { 300 | return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); 301 | } 302 | #endif 303 | 304 | static FILE *stbiw__fopen(char const *filename, char const *mode) 305 | { 306 | FILE *f; 307 | #if defined(_WIN32) && defined(STBIW_WINDOWS_UTF8) 308 | wchar_t wMode[64]; 309 | wchar_t wFilename[1024]; 310 | if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)/sizeof(*wFilename))) 311 | return 0; 312 | 313 | if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)/sizeof(*wMode))) 314 | return 0; 315 | 316 | #if defined(_MSC_VER) && _MSC_VER >= 1400 317 | if (0 != _wfopen_s(&f, wFilename, wMode)) 318 | f = 0; 319 | #else 320 | f = _wfopen(wFilename, wMode); 321 | #endif 322 | 323 | #elif defined(_MSC_VER) && _MSC_VER >= 1400 324 | if (0 != fopen_s(&f, filename, mode)) 325 | f=0; 326 | #else 327 | f = fopen(filename, mode); 328 | #endif 329 | return f; 330 | } 331 | 332 | static int stbi__start_write_file(stbi__write_context *s, const char *filename) 333 | { 334 | FILE *f = stbiw__fopen(filename, "wb"); 335 | stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); 336 | return f != NULL; 337 | } 338 | 339 | static void stbi__end_write_file(stbi__write_context *s) 340 | { 341 | fclose((FILE *)s->context); 342 | } 343 | 344 | #endif // !STBI_WRITE_NO_STDIO 345 | 346 | typedef unsigned int stbiw_uint32; 347 | typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; 348 | 349 | static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) 350 | { 351 | while (*fmt) { 352 | switch (*fmt++) { 353 | case ' ': break; 354 | case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); 355 | s->func(s->context,&x,1); 356 | break; } 357 | case '2': { int x = va_arg(v,int); 358 | unsigned char b[2]; 359 | b[0] = STBIW_UCHAR(x); 360 | b[1] = STBIW_UCHAR(x>>8); 361 | s->func(s->context,b,2); 362 | break; } 363 | case '4': { stbiw_uint32 x = va_arg(v,int); 364 | unsigned char b[4]; 365 | b[0]=STBIW_UCHAR(x); 366 | b[1]=STBIW_UCHAR(x>>8); 367 | b[2]=STBIW_UCHAR(x>>16); 368 | b[3]=STBIW_UCHAR(x>>24); 369 | s->func(s->context,b,4); 370 | break; } 371 | default: 372 | STBIW_ASSERT(0); 373 | return; 374 | } 375 | } 376 | } 377 | 378 | static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) 379 | { 380 | va_list v; 381 | va_start(v, fmt); 382 | stbiw__writefv(s, fmt, v); 383 | va_end(v); 384 | } 385 | 386 | static void stbiw__write_flush(stbi__write_context *s) 387 | { 388 | if (s->buf_used) { 389 | s->func(s->context, &s->buffer, s->buf_used); 390 | s->buf_used = 0; 391 | } 392 | } 393 | 394 | static void stbiw__putc(stbi__write_context *s, unsigned char c) 395 | { 396 | s->func(s->context, &c, 1); 397 | } 398 | 399 | static void stbiw__write1(stbi__write_context *s, unsigned char a) 400 | { 401 | if ((size_t)s->buf_used + 1 > sizeof(s->buffer)) 402 | stbiw__write_flush(s); 403 | s->buffer[s->buf_used++] = a; 404 | } 405 | 406 | static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) 407 | { 408 | int n; 409 | if ((size_t)s->buf_used + 3 > sizeof(s->buffer)) 410 | stbiw__write_flush(s); 411 | n = s->buf_used; 412 | s->buf_used = n+3; 413 | s->buffer[n+0] = a; 414 | s->buffer[n+1] = b; 415 | s->buffer[n+2] = c; 416 | } 417 | 418 | static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) 419 | { 420 | unsigned char bg[3] = { 255, 0, 255}, px[3]; 421 | int k; 422 | 423 | if (write_alpha < 0) 424 | stbiw__write1(s, d[comp - 1]); 425 | 426 | switch (comp) { 427 | case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case 428 | case 1: 429 | if (expand_mono) 430 | stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp 431 | else 432 | stbiw__write1(s, d[0]); // monochrome TGA 433 | break; 434 | case 4: 435 | if (!write_alpha) { 436 | // composite against pink background 437 | for (k = 0; k < 3; ++k) 438 | px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; 439 | stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); 440 | break; 441 | } 442 | /* FALLTHROUGH */ 443 | case 3: 444 | stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); 445 | break; 446 | } 447 | if (write_alpha > 0) 448 | stbiw__write1(s, d[comp - 1]); 449 | } 450 | 451 | static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) 452 | { 453 | stbiw_uint32 zero = 0; 454 | int i,j, j_end; 455 | 456 | if (y <= 0) 457 | return; 458 | 459 | if (stbi__flip_vertically_on_write) 460 | vdir *= -1; 461 | 462 | if (vdir < 0) { 463 | j_end = -1; j = y-1; 464 | } else { 465 | j_end = y; j = 0; 466 | } 467 | 468 | for (; j != j_end; j += vdir) { 469 | for (i=0; i < x; ++i) { 470 | unsigned char *d = (unsigned char *) data + (j*x+i)*comp; 471 | stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); 472 | } 473 | stbiw__write_flush(s); 474 | s->func(s->context, &zero, scanline_pad); 475 | } 476 | } 477 | 478 | static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) 479 | { 480 | if (y < 0 || x < 0) { 481 | return 0; 482 | } else { 483 | va_list v; 484 | va_start(v, fmt); 485 | stbiw__writefv(s, fmt, v); 486 | va_end(v); 487 | stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); 488 | return 1; 489 | } 490 | } 491 | 492 | static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) 493 | { 494 | if (comp != 4) { 495 | // write RGB bitmap 496 | int pad = (-x*3) & 3; 497 | return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, 498 | "11 4 22 4" "4 44 22 444444", 499 | 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header 500 | 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header 501 | } else { 502 | // RGBA bitmaps need a v4 header 503 | // use BI_BITFIELDS mode with 32bpp and alpha mask 504 | // (straight BI_RGB with alpha mask doesn't work in most readers) 505 | return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *)data,1,0, 506 | "11 4 22 4" "4 44 22 444444 4444 4 444 444 444 444", 507 | 'B', 'M', 14+108+x*y*4, 0, 0, 14+108, // file header 508 | 108, x,y, 1,32, 3,0,0,0,0,0, 0xff0000,0xff00,0xff,0xff000000u, 0, 0,0,0, 0,0,0, 0,0,0, 0,0,0); // bitmap V4 header 509 | } 510 | } 511 | 512 | STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) 513 | { 514 | stbi__write_context s = { 0 }; 515 | stbi__start_write_callbacks(&s, func, context); 516 | return stbi_write_bmp_core(&s, x, y, comp, data); 517 | } 518 | 519 | #ifndef STBI_WRITE_NO_STDIO 520 | STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) 521 | { 522 | stbi__write_context s = { 0 }; 523 | if (stbi__start_write_file(&s,filename)) { 524 | int r = stbi_write_bmp_core(&s, x, y, comp, data); 525 | stbi__end_write_file(&s); 526 | return r; 527 | } else 528 | return 0; 529 | } 530 | #endif //!STBI_WRITE_NO_STDIO 531 | 532 | static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) 533 | { 534 | int has_alpha = (comp == 2 || comp == 4); 535 | int colorbytes = has_alpha ? comp-1 : comp; 536 | int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 537 | 538 | if (y < 0 || x < 0) 539 | return 0; 540 | 541 | if (!stbi_write_tga_with_rle) { 542 | return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, 543 | "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); 544 | } else { 545 | int i,j,k; 546 | int jend, jdir; 547 | 548 | stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); 549 | 550 | if (stbi__flip_vertically_on_write) { 551 | j = 0; 552 | jend = y; 553 | jdir = 1; 554 | } else { 555 | j = y-1; 556 | jend = -1; 557 | jdir = -1; 558 | } 559 | for (; j != jend; j += jdir) { 560 | unsigned char *row = (unsigned char *) data + j * x * comp; 561 | int len; 562 | 563 | for (i = 0; i < x; i += len) { 564 | unsigned char *begin = row + i * comp; 565 | int diff = 1; 566 | len = 1; 567 | 568 | if (i < x - 1) { 569 | ++len; 570 | diff = memcmp(begin, row + (i + 1) * comp, comp); 571 | if (diff) { 572 | const unsigned char *prev = begin; 573 | for (k = i + 2; k < x && len < 128; ++k) { 574 | if (memcmp(prev, row + k * comp, comp)) { 575 | prev += comp; 576 | ++len; 577 | } else { 578 | --len; 579 | break; 580 | } 581 | } 582 | } else { 583 | for (k = i + 2; k < x && len < 128; ++k) { 584 | if (!memcmp(begin, row + k * comp, comp)) { 585 | ++len; 586 | } else { 587 | break; 588 | } 589 | } 590 | } 591 | } 592 | 593 | if (diff) { 594 | unsigned char header = STBIW_UCHAR(len - 1); 595 | stbiw__write1(s, header); 596 | for (k = 0; k < len; ++k) { 597 | stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); 598 | } 599 | } else { 600 | unsigned char header = STBIW_UCHAR(len - 129); 601 | stbiw__write1(s, header); 602 | stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); 603 | } 604 | } 605 | } 606 | stbiw__write_flush(s); 607 | } 608 | return 1; 609 | } 610 | 611 | STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) 612 | { 613 | stbi__write_context s = { 0 }; 614 | stbi__start_write_callbacks(&s, func, context); 615 | return stbi_write_tga_core(&s, x, y, comp, (void *) data); 616 | } 617 | 618 | #ifndef STBI_WRITE_NO_STDIO 619 | STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) 620 | { 621 | stbi__write_context s = { 0 }; 622 | if (stbi__start_write_file(&s,filename)) { 623 | int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); 624 | stbi__end_write_file(&s); 625 | return r; 626 | } else 627 | return 0; 628 | } 629 | #endif 630 | 631 | // ************************************************************************************************* 632 | // Radiance RGBE HDR writer 633 | // by Baldur Karlsson 634 | 635 | #define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) 636 | 637 | #ifndef STBI_WRITE_NO_STDIO 638 | 639 | static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) 640 | { 641 | int exponent; 642 | float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); 643 | 644 | if (maxcomp < 1e-32f) { 645 | rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; 646 | } else { 647 | float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; 648 | 649 | rgbe[0] = (unsigned char)(linear[0] * normalize); 650 | rgbe[1] = (unsigned char)(linear[1] * normalize); 651 | rgbe[2] = (unsigned char)(linear[2] * normalize); 652 | rgbe[3] = (unsigned char)(exponent + 128); 653 | } 654 | } 655 | 656 | static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) 657 | { 658 | unsigned char lengthbyte = STBIW_UCHAR(length+128); 659 | STBIW_ASSERT(length+128 <= 255); 660 | s->func(s->context, &lengthbyte, 1); 661 | s->func(s->context, &databyte, 1); 662 | } 663 | 664 | static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) 665 | { 666 | unsigned char lengthbyte = STBIW_UCHAR(length); 667 | STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code 668 | s->func(s->context, &lengthbyte, 1); 669 | s->func(s->context, data, length); 670 | } 671 | 672 | static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) 673 | { 674 | unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; 675 | unsigned char rgbe[4]; 676 | float linear[3]; 677 | int x; 678 | 679 | scanlineheader[2] = (width&0xff00)>>8; 680 | scanlineheader[3] = (width&0x00ff); 681 | 682 | /* skip RLE for images too small or large */ 683 | if (width < 8 || width >= 32768) { 684 | for (x=0; x < width; x++) { 685 | switch (ncomp) { 686 | case 4: /* fallthrough */ 687 | case 3: linear[2] = scanline[x*ncomp + 2]; 688 | linear[1] = scanline[x*ncomp + 1]; 689 | linear[0] = scanline[x*ncomp + 0]; 690 | break; 691 | default: 692 | linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; 693 | break; 694 | } 695 | stbiw__linear_to_rgbe(rgbe, linear); 696 | s->func(s->context, rgbe, 4); 697 | } 698 | } else { 699 | int c,r; 700 | /* encode into scratch buffer */ 701 | for (x=0; x < width; x++) { 702 | switch(ncomp) { 703 | case 4: /* fallthrough */ 704 | case 3: linear[2] = scanline[x*ncomp + 2]; 705 | linear[1] = scanline[x*ncomp + 1]; 706 | linear[0] = scanline[x*ncomp + 0]; 707 | break; 708 | default: 709 | linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; 710 | break; 711 | } 712 | stbiw__linear_to_rgbe(rgbe, linear); 713 | scratch[x + width*0] = rgbe[0]; 714 | scratch[x + width*1] = rgbe[1]; 715 | scratch[x + width*2] = rgbe[2]; 716 | scratch[x + width*3] = rgbe[3]; 717 | } 718 | 719 | s->func(s->context, scanlineheader, 4); 720 | 721 | /* RLE each component separately */ 722 | for (c=0; c < 4; c++) { 723 | unsigned char *comp = &scratch[width*c]; 724 | 725 | x = 0; 726 | while (x < width) { 727 | // find first run 728 | r = x; 729 | while (r+2 < width) { 730 | if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) 731 | break; 732 | ++r; 733 | } 734 | if (r+2 >= width) 735 | r = width; 736 | // dump up to first run 737 | while (x < r) { 738 | int len = r-x; 739 | if (len > 128) len = 128; 740 | stbiw__write_dump_data(s, len, &comp[x]); 741 | x += len; 742 | } 743 | // if there's a run, output it 744 | if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd 745 | // find next byte after run 746 | while (r < width && comp[r] == comp[x]) 747 | ++r; 748 | // output run up to r 749 | while (x < r) { 750 | int len = r-x; 751 | if (len > 127) len = 127; 752 | stbiw__write_run_data(s, len, comp[x]); 753 | x += len; 754 | } 755 | } 756 | } 757 | } 758 | } 759 | } 760 | 761 | static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) 762 | { 763 | if (y <= 0 || x <= 0 || data == NULL) 764 | return 0; 765 | else { 766 | // Each component is stored separately. Allocate scratch space for full output scanline. 767 | unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); 768 | int i, len; 769 | char buffer[128]; 770 | char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; 771 | s->func(s->context, header, sizeof(header)-1); 772 | 773 | #ifdef __STDC_LIB_EXT1__ 774 | len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); 775 | #else 776 | len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); 777 | #endif 778 | s->func(s->context, buffer, len); 779 | 780 | for(i=0; i < y; i++) 781 | stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)); 782 | STBIW_FREE(scratch); 783 | return 1; 784 | } 785 | } 786 | 787 | STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) 788 | { 789 | stbi__write_context s = { 0 }; 790 | stbi__start_write_callbacks(&s, func, context); 791 | return stbi_write_hdr_core(&s, x, y, comp, (float *) data); 792 | } 793 | 794 | STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) 795 | { 796 | stbi__write_context s = { 0 }; 797 | if (stbi__start_write_file(&s,filename)) { 798 | int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); 799 | stbi__end_write_file(&s); 800 | return r; 801 | } else 802 | return 0; 803 | } 804 | #endif // STBI_WRITE_NO_STDIO 805 | 806 | 807 | ////////////////////////////////////////////////////////////////////////////// 808 | // 809 | // PNG writer 810 | // 811 | 812 | #ifndef STBIW_ZLIB_COMPRESS 813 | // stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() 814 | #define stbiw__sbraw(a) ((int *) (void *) (a) - 2) 815 | #define stbiw__sbm(a) stbiw__sbraw(a)[0] 816 | #define stbiw__sbn(a) stbiw__sbraw(a)[1] 817 | 818 | #define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) 819 | #define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) 820 | #define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) 821 | 822 | #define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) 823 | #define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) 824 | #define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) 825 | 826 | static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) 827 | { 828 | int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; 829 | void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); 830 | STBIW_ASSERT(p); 831 | if (p) { 832 | if (!*arr) ((int *) p)[1] = 0; 833 | *arr = (void *) ((int *) p + 2); 834 | stbiw__sbm(*arr) = m; 835 | } 836 | return *arr; 837 | } 838 | 839 | static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) 840 | { 841 | while (*bitcount >= 8) { 842 | stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); 843 | *bitbuffer >>= 8; 844 | *bitcount -= 8; 845 | } 846 | return data; 847 | } 848 | 849 | static int stbiw__zlib_bitrev(int code, int codebits) 850 | { 851 | int res=0; 852 | while (codebits--) { 853 | res = (res << 1) | (code & 1); 854 | code >>= 1; 855 | } 856 | return res; 857 | } 858 | 859 | static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) 860 | { 861 | int i; 862 | for (i=0; i < limit && i < 258; ++i) 863 | if (a[i] != b[i]) break; 864 | return i; 865 | } 866 | 867 | static unsigned int stbiw__zhash(unsigned char *data) 868 | { 869 | stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); 870 | hash ^= hash << 3; 871 | hash += hash >> 5; 872 | hash ^= hash << 4; 873 | hash += hash >> 17; 874 | hash ^= hash << 25; 875 | hash += hash >> 6; 876 | return hash; 877 | } 878 | 879 | #define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) 880 | #define stbiw__zlib_add(code,codebits) \ 881 | (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) 882 | #define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) 883 | // default huffman tables 884 | #define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) 885 | #define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) 886 | #define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) 887 | #define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) 888 | #define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) 889 | #define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) 890 | 891 | #define stbiw__ZHASH 16384 892 | 893 | #endif // STBIW_ZLIB_COMPRESS 894 | 895 | STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) 896 | { 897 | #ifdef STBIW_ZLIB_COMPRESS 898 | // user provided a zlib compress implementation, use that 899 | return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality); 900 | #else // use builtin 901 | static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; 902 | static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; 903 | static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; 904 | static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; 905 | unsigned int bitbuf=0; 906 | int i,j, bitcount=0; 907 | unsigned char *out = NULL; 908 | unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**)); 909 | if (hash_table == NULL) 910 | return NULL; 911 | if (quality < 5) quality = 5; 912 | 913 | stbiw__sbpush(out, 0x78); // DEFLATE 32K window 914 | stbiw__sbpush(out, 0x5e); // FLEVEL = 1 915 | stbiw__zlib_add(1,1); // BFINAL = 1 916 | stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman 917 | 918 | for (i=0; i < stbiw__ZHASH; ++i) 919 | hash_table[i] = NULL; 920 | 921 | i=0; 922 | while (i < data_len-3) { 923 | // hash next 3 bytes of data to be compressed 924 | int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; 925 | unsigned char *bestloc = 0; 926 | unsigned char **hlist = hash_table[h]; 927 | int n = stbiw__sbcount(hlist); 928 | for (j=0; j < n; ++j) { 929 | if (hlist[j]-data > i-32768) { // if entry lies within window 930 | int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); 931 | if (d >= best) { best=d; bestloc=hlist[j]; } 932 | } 933 | } 934 | // when hash table entry is too long, delete half the entries 935 | if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { 936 | STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); 937 | stbiw__sbn(hash_table[h]) = quality; 938 | } 939 | stbiw__sbpush(hash_table[h],data+i); 940 | 941 | if (bestloc) { 942 | // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal 943 | h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); 944 | hlist = hash_table[h]; 945 | n = stbiw__sbcount(hlist); 946 | for (j=0; j < n; ++j) { 947 | if (hlist[j]-data > i-32767) { 948 | int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); 949 | if (e > best) { // if next match is better, bail on current match 950 | bestloc = NULL; 951 | break; 952 | } 953 | } 954 | } 955 | } 956 | 957 | if (bestloc) { 958 | int d = (int) (data+i - bestloc); // distance back 959 | STBIW_ASSERT(d <= 32767 && best <= 258); 960 | for (j=0; best > lengthc[j+1]-1; ++j); 961 | stbiw__zlib_huff(j+257); 962 | if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); 963 | for (j=0; d > distc[j+1]-1; ++j); 964 | stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); 965 | if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); 966 | i += best; 967 | } else { 968 | stbiw__zlib_huffb(data[i]); 969 | ++i; 970 | } 971 | } 972 | // write out final bytes 973 | for (;i < data_len; ++i) 974 | stbiw__zlib_huffb(data[i]); 975 | stbiw__zlib_huff(256); // end of block 976 | // pad with 0 bits to byte boundary 977 | while (bitcount) 978 | stbiw__zlib_add(0,1); 979 | 980 | for (i=0; i < stbiw__ZHASH; ++i) 981 | (void) stbiw__sbfree(hash_table[i]); 982 | STBIW_FREE(hash_table); 983 | 984 | // store uncompressed instead if compression was worse 985 | if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) { 986 | stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1 987 | for (j = 0; j < data_len;) { 988 | int blocklen = data_len - j; 989 | if (blocklen > 32767) blocklen = 32767; 990 | stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression 991 | stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN 992 | stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8)); 993 | stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN 994 | stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8)); 995 | memcpy(out+stbiw__sbn(out), data+j, blocklen); 996 | stbiw__sbn(out) += blocklen; 997 | j += blocklen; 998 | } 999 | } 1000 | 1001 | { 1002 | // compute adler32 on input 1003 | unsigned int s1=1, s2=0; 1004 | int blocklen = (int) (data_len % 5552); 1005 | j=0; 1006 | while (j < data_len) { 1007 | for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; } 1008 | s1 %= 65521; s2 %= 65521; 1009 | j += blocklen; 1010 | blocklen = 5552; 1011 | } 1012 | stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); 1013 | stbiw__sbpush(out, STBIW_UCHAR(s2)); 1014 | stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); 1015 | stbiw__sbpush(out, STBIW_UCHAR(s1)); 1016 | } 1017 | *out_len = stbiw__sbn(out); 1018 | // make returned pointer freeable 1019 | STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); 1020 | return (unsigned char *) stbiw__sbraw(out); 1021 | #endif // STBIW_ZLIB_COMPRESS 1022 | } 1023 | 1024 | static unsigned int stbiw__crc32(unsigned char *buffer, int len) 1025 | { 1026 | #ifdef STBIW_CRC32 1027 | return STBIW_CRC32(buffer, len); 1028 | #else 1029 | static unsigned int crc_table[256] = 1030 | { 1031 | 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 1032 | 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 1033 | 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 1034 | 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 1035 | 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 1036 | 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 1037 | 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 1038 | 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 1039 | 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 1040 | 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 1041 | 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 1042 | 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 1043 | 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 1044 | 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 1045 | 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 1046 | 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 1047 | 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 1048 | 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 1049 | 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 1050 | 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 1051 | 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 1052 | 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 1053 | 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 1054 | 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 1055 | 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 1056 | 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 1057 | 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 1058 | 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 1059 | 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 1060 | 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 1061 | 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 1062 | 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 1063 | }; 1064 | 1065 | unsigned int crc = ~0u; 1066 | int i; 1067 | for (i=0; i < len; ++i) 1068 | crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; 1069 | return ~crc; 1070 | #endif 1071 | } 1072 | 1073 | #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) 1074 | #define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); 1075 | #define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) 1076 | 1077 | static void stbiw__wpcrc(unsigned char **data, int len) 1078 | { 1079 | unsigned int crc = stbiw__crc32(*data - len - 4, len+4); 1080 | stbiw__wp32(*data, crc); 1081 | } 1082 | 1083 | static unsigned char stbiw__paeth(int a, int b, int c) 1084 | { 1085 | int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); 1086 | if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); 1087 | if (pb <= pc) return STBIW_UCHAR(b); 1088 | return STBIW_UCHAR(c); 1089 | } 1090 | 1091 | // @OPTIMIZE: provide an option that always forces left-predict or paeth predict 1092 | static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer) 1093 | { 1094 | static int mapping[] = { 0,1,2,3,4 }; 1095 | static int firstmap[] = { 0,1,0,5,6 }; 1096 | int *mymap = (y != 0) ? mapping : firstmap; 1097 | int i; 1098 | int type = mymap[filter_type]; 1099 | unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); 1100 | int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes; 1101 | 1102 | if (type==0) { 1103 | memcpy(line_buffer, z, width*n); 1104 | return; 1105 | } 1106 | 1107 | // first loop isn't optimized since it's just one pixel 1108 | for (i = 0; i < n; ++i) { 1109 | switch (type) { 1110 | case 1: line_buffer[i] = z[i]; break; 1111 | case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; 1112 | case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break; 1113 | case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break; 1114 | case 5: line_buffer[i] = z[i]; break; 1115 | case 6: line_buffer[i] = z[i]; break; 1116 | } 1117 | } 1118 | switch (type) { 1119 | case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break; 1120 | case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break; 1121 | case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break; 1122 | case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break; 1123 | case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break; 1124 | case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; 1125 | } 1126 | } 1127 | 1128 | STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) 1129 | { 1130 | int force_filter = stbi_write_force_png_filter; 1131 | int ctype[5] = { -1, 0, 4, 2, 6 }; 1132 | unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; 1133 | unsigned char *out,*o, *filt, *zlib; 1134 | signed char *line_buffer; 1135 | int j,zlen; 1136 | 1137 | if (stride_bytes == 0) 1138 | stride_bytes = x * n; 1139 | 1140 | if (force_filter >= 5) { 1141 | force_filter = -1; 1142 | } 1143 | 1144 | filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; 1145 | line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } 1146 | for (j=0; j < y; ++j) { 1147 | int filter_type; 1148 | if (force_filter > -1) { 1149 | filter_type = force_filter; 1150 | stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer); 1151 | } else { // Estimate the best filter by running through all of them: 1152 | int best_filter = 0, best_filter_val = 0x7fffffff, est, i; 1153 | for (filter_type = 0; filter_type < 5; filter_type++) { 1154 | stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer); 1155 | 1156 | // Estimate the entropy of the line using this filter; the less, the better. 1157 | est = 0; 1158 | for (i = 0; i < x*n; ++i) { 1159 | est += abs((signed char) line_buffer[i]); 1160 | } 1161 | if (est < best_filter_val) { 1162 | best_filter_val = est; 1163 | best_filter = filter_type; 1164 | } 1165 | } 1166 | if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it 1167 | stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer); 1168 | filter_type = best_filter; 1169 | } 1170 | } 1171 | // when we get here, filter_type contains the filter type, and line_buffer contains the data 1172 | filt[j*(x*n+1)] = (unsigned char) filter_type; 1173 | STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); 1174 | } 1175 | STBIW_FREE(line_buffer); 1176 | zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level); 1177 | STBIW_FREE(filt); 1178 | if (!zlib) return 0; 1179 | 1180 | // each tag requires 12 bytes of overhead 1181 | out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); 1182 | if (!out) return 0; 1183 | *out_len = 8 + 12+13 + 12+zlen + 12; 1184 | 1185 | o=out; 1186 | STBIW_MEMMOVE(o,sig,8); o+= 8; 1187 | stbiw__wp32(o, 13); // header length 1188 | stbiw__wptag(o, "IHDR"); 1189 | stbiw__wp32(o, x); 1190 | stbiw__wp32(o, y); 1191 | *o++ = 8; 1192 | *o++ = STBIW_UCHAR(ctype[n]); 1193 | *o++ = 0; 1194 | *o++ = 0; 1195 | *o++ = 0; 1196 | stbiw__wpcrc(&o,13); 1197 | 1198 | stbiw__wp32(o, zlen); 1199 | stbiw__wptag(o, "IDAT"); 1200 | STBIW_MEMMOVE(o, zlib, zlen); 1201 | o += zlen; 1202 | STBIW_FREE(zlib); 1203 | stbiw__wpcrc(&o, zlen); 1204 | 1205 | stbiw__wp32(o,0); 1206 | stbiw__wptag(o, "IEND"); 1207 | stbiw__wpcrc(&o,0); 1208 | 1209 | STBIW_ASSERT(o == out + *out_len); 1210 | 1211 | return out; 1212 | } 1213 | 1214 | #ifndef STBI_WRITE_NO_STDIO 1215 | STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) 1216 | { 1217 | FILE *f; 1218 | int len; 1219 | unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); 1220 | if (png == NULL) return 0; 1221 | 1222 | f = stbiw__fopen(filename, "wb"); 1223 | if (!f) { STBIW_FREE(png); return 0; } 1224 | fwrite(png, 1, len, f); 1225 | fclose(f); 1226 | STBIW_FREE(png); 1227 | return 1; 1228 | } 1229 | #endif 1230 | 1231 | STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) 1232 | { 1233 | int len; 1234 | unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); 1235 | if (png == NULL) return 0; 1236 | func(context, png, len); 1237 | STBIW_FREE(png); 1238 | return 1; 1239 | } 1240 | 1241 | 1242 | /* *************************************************************************** 1243 | * 1244 | * JPEG writer 1245 | * 1246 | * This is based on Jon Olick's jo_jpeg.cpp: 1247 | * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html 1248 | */ 1249 | 1250 | static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, 1251 | 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; 1252 | 1253 | static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { 1254 | int bitBuf = *bitBufP, bitCnt = *bitCntP; 1255 | bitCnt += bs[1]; 1256 | bitBuf |= bs[0] << (24 - bitCnt); 1257 | while(bitCnt >= 8) { 1258 | unsigned char c = (bitBuf >> 16) & 255; 1259 | stbiw__putc(s, c); 1260 | if(c == 255) { 1261 | stbiw__putc(s, 0); 1262 | } 1263 | bitBuf <<= 8; 1264 | bitCnt -= 8; 1265 | } 1266 | *bitBufP = bitBuf; 1267 | *bitCntP = bitCnt; 1268 | } 1269 | 1270 | static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { 1271 | float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; 1272 | float z1, z2, z3, z4, z5, z11, z13; 1273 | 1274 | float tmp0 = d0 + d7; 1275 | float tmp7 = d0 - d7; 1276 | float tmp1 = d1 + d6; 1277 | float tmp6 = d1 - d6; 1278 | float tmp2 = d2 + d5; 1279 | float tmp5 = d2 - d5; 1280 | float tmp3 = d3 + d4; 1281 | float tmp4 = d3 - d4; 1282 | 1283 | // Even part 1284 | float tmp10 = tmp0 + tmp3; // phase 2 1285 | float tmp13 = tmp0 - tmp3; 1286 | float tmp11 = tmp1 + tmp2; 1287 | float tmp12 = tmp1 - tmp2; 1288 | 1289 | d0 = tmp10 + tmp11; // phase 3 1290 | d4 = tmp10 - tmp11; 1291 | 1292 | z1 = (tmp12 + tmp13) * 0.707106781f; // c4 1293 | d2 = tmp13 + z1; // phase 5 1294 | d6 = tmp13 - z1; 1295 | 1296 | // Odd part 1297 | tmp10 = tmp4 + tmp5; // phase 2 1298 | tmp11 = tmp5 + tmp6; 1299 | tmp12 = tmp6 + tmp7; 1300 | 1301 | // The rotator is modified from fig 4-8 to avoid extra negations. 1302 | z5 = (tmp10 - tmp12) * 0.382683433f; // c6 1303 | z2 = tmp10 * 0.541196100f + z5; // c2-c6 1304 | z4 = tmp12 * 1.306562965f + z5; // c2+c6 1305 | z3 = tmp11 * 0.707106781f; // c4 1306 | 1307 | z11 = tmp7 + z3; // phase 5 1308 | z13 = tmp7 - z3; 1309 | 1310 | *d5p = z13 + z2; // phase 6 1311 | *d3p = z13 - z2; 1312 | *d1p = z11 + z4; 1313 | *d7p = z11 - z4; 1314 | 1315 | *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; 1316 | } 1317 | 1318 | static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { 1319 | int tmp1 = val < 0 ? -val : val; 1320 | val = val < 0 ? val-1 : val; 1321 | bits[1] = 1; 1322 | while(tmp1 >>= 1) { 1323 | ++bits[1]; 1324 | } 1325 | bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { 1368 | } 1369 | // end0pos = first element in reverse order !=0 1370 | if(end0pos == 0) { 1371 | stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); 1372 | return DU[0]; 1373 | } 1374 | for(i = 1; i <= end0pos; ++i) { 1375 | int startpos = i; 1376 | int nrzeroes; 1377 | unsigned short bits[2]; 1378 | for (; DU[i]==0 && i<=end0pos; ++i) { 1379 | } 1380 | nrzeroes = i-startpos; 1381 | if ( nrzeroes >= 16 ) { 1382 | int lng = nrzeroes>>4; 1383 | int nrmarker; 1384 | for (nrmarker=1; nrmarker <= lng; ++nrmarker) 1385 | stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); 1386 | nrzeroes &= 15; 1387 | } 1388 | stbiw__jpg_calcBits(DU[i], bits); 1389 | stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); 1390 | stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); 1391 | } 1392 | if(end0pos != 63) { 1393 | stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); 1394 | } 1395 | return DU[0]; 1396 | } 1397 | 1398 | static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { 1399 | // Constants that don't pollute global namespace 1400 | static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; 1401 | static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; 1402 | static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; 1403 | static const unsigned char std_ac_luminance_values[] = { 1404 | 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, 1405 | 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, 1406 | 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, 1407 | 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, 1408 | 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, 1409 | 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, 1410 | 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa 1411 | }; 1412 | static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; 1413 | static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; 1414 | static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; 1415 | static const unsigned char std_ac_chrominance_values[] = { 1416 | 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, 1417 | 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, 1418 | 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, 1419 | 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, 1420 | 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, 1421 | 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, 1422 | 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa 1423 | }; 1424 | // Huffman tables 1425 | static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; 1426 | static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; 1427 | static const unsigned short YAC_HT[256][2] = { 1428 | {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1429 | {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1430 | {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1431 | {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1432 | {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1433 | {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1434 | {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1435 | {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1436 | {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1437 | {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1438 | {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1439 | {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1440 | {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1441 | {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1442 | {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, 1443 | {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} 1444 | }; 1445 | static const unsigned short UVAC_HT[256][2] = { 1446 | {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1447 | {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1448 | {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1449 | {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1450 | {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1451 | {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1452 | {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1453 | {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1454 | {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1455 | {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1456 | {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1457 | {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1458 | {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1459 | {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, 1460 | {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, 1461 | {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} 1462 | }; 1463 | static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, 1464 | 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; 1465 | static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, 1466 | 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; 1467 | static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, 1468 | 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; 1469 | 1470 | int row, col, i, k, subsample; 1471 | float fdtbl_Y[64], fdtbl_UV[64]; 1472 | unsigned char YTable[64], UVTable[64]; 1473 | 1474 | if(!data || !width || !height || comp > 4 || comp < 1) { 1475 | return 0; 1476 | } 1477 | 1478 | quality = quality ? quality : 90; 1479 | subsample = quality <= 90 ? 1 : 0; 1480 | quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; 1481 | quality = quality < 50 ? 5000 / quality : 200 - quality * 2; 1482 | 1483 | for(i = 0; i < 64; ++i) { 1484 | int uvti, yti = (YQT[i]*quality+50)/100; 1485 | YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); 1486 | uvti = (UVQT[i]*quality+50)/100; 1487 | UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); 1488 | } 1489 | 1490 | for(row = 0, k = 0; row < 8; ++row) { 1491 | for(col = 0; col < 8; ++col, ++k) { 1492 | fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); 1493 | fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); 1494 | } 1495 | } 1496 | 1497 | // Write Headers 1498 | { 1499 | static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; 1500 | static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; 1501 | const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width), 1502 | 3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; 1503 | s->func(s->context, (void*)head0, sizeof(head0)); 1504 | s->func(s->context, (void*)YTable, sizeof(YTable)); 1505 | stbiw__putc(s, 1); 1506 | s->func(s->context, UVTable, sizeof(UVTable)); 1507 | s->func(s->context, (void*)head1, sizeof(head1)); 1508 | s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); 1509 | s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); 1510 | stbiw__putc(s, 0x10); // HTYACinfo 1511 | s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); 1512 | s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); 1513 | stbiw__putc(s, 1); // HTUDCinfo 1514 | s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); 1515 | s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); 1516 | stbiw__putc(s, 0x11); // HTUACinfo 1517 | s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); 1518 | s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); 1519 | s->func(s->context, (void*)head2, sizeof(head2)); 1520 | } 1521 | 1522 | // Encode 8x8 macroblocks 1523 | { 1524 | static const unsigned short fillBits[] = {0x7F, 7}; 1525 | int DCY=0, DCU=0, DCV=0; 1526 | int bitBuf=0, bitCnt=0; 1527 | // comp == 2 is grey+alpha (alpha is ignored) 1528 | int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; 1529 | const unsigned char *dataR = (const unsigned char *)data; 1530 | const unsigned char *dataG = dataR + ofsG; 1531 | const unsigned char *dataB = dataR + ofsB; 1532 | int x, y, pos; 1533 | if(subsample) { 1534 | for(y = 0; y < height; y += 16) { 1535 | for(x = 0; x < width; x += 16) { 1536 | float Y[256], U[256], V[256]; 1537 | for(row = y, pos = 0; row < y+16; ++row) { 1538 | // row >= height => use last input row 1539 | int clamped_row = (row < height) ? row : height - 1; 1540 | int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; 1541 | for(col = x; col < x+16; ++col, ++pos) { 1542 | // if col >= width => use pixel from last input column 1543 | int p = base_p + ((col < width) ? col : (width-1))*comp; 1544 | float r = dataR[p], g = dataG[p], b = dataB[p]; 1545 | Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; 1546 | U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; 1547 | V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; 1548 | } 1549 | } 1550 | DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); 1551 | DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); 1552 | DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); 1553 | DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); 1554 | 1555 | // subsample U,V 1556 | { 1557 | float subU[64], subV[64]; 1558 | int yy, xx; 1559 | for(yy = 0, pos = 0; yy < 8; ++yy) { 1560 | for(xx = 0; xx < 8; ++xx, ++pos) { 1561 | int j = yy*32+xx*2; 1562 | subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f; 1563 | subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f; 1564 | } 1565 | } 1566 | DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); 1567 | DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); 1568 | } 1569 | } 1570 | } 1571 | } else { 1572 | for(y = 0; y < height; y += 8) { 1573 | for(x = 0; x < width; x += 8) { 1574 | float Y[64], U[64], V[64]; 1575 | for(row = y, pos = 0; row < y+8; ++row) { 1576 | // row >= height => use last input row 1577 | int clamped_row = (row < height) ? row : height - 1; 1578 | int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; 1579 | for(col = x; col < x+8; ++col, ++pos) { 1580 | // if col >= width => use pixel from last input column 1581 | int p = base_p + ((col < width) ? col : (width-1))*comp; 1582 | float r = dataR[p], g = dataG[p], b = dataB[p]; 1583 | Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; 1584 | U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; 1585 | V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; 1586 | } 1587 | } 1588 | 1589 | DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT); 1590 | DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); 1591 | DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); 1592 | } 1593 | } 1594 | } 1595 | 1596 | // Do the bit alignment of the EOI marker 1597 | stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); 1598 | } 1599 | 1600 | // EOI 1601 | stbiw__putc(s, 0xFF); 1602 | stbiw__putc(s, 0xD9); 1603 | 1604 | return 1; 1605 | } 1606 | 1607 | STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) 1608 | { 1609 | stbi__write_context s = { 0 }; 1610 | stbi__start_write_callbacks(&s, func, context); 1611 | return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); 1612 | } 1613 | 1614 | 1615 | #ifndef STBI_WRITE_NO_STDIO 1616 | STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) 1617 | { 1618 | stbi__write_context s = { 0 }; 1619 | if (stbi__start_write_file(&s,filename)) { 1620 | int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); 1621 | stbi__end_write_file(&s); 1622 | return r; 1623 | } else 1624 | return 0; 1625 | } 1626 | #endif 1627 | 1628 | #endif // STB_IMAGE_WRITE_IMPLEMENTATION 1629 | 1630 | /* Revision history 1631 | 1.16 (2021-07-11) 1632 | make Deflate code emit uncompressed blocks when it would otherwise expand 1633 | support writing BMPs with alpha channel 1634 | 1.15 (2020-07-13) unknown 1635 | 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels 1636 | 1.13 1637 | 1.12 1638 | 1.11 (2019-08-11) 1639 | 1640 | 1.10 (2019-02-07) 1641 | support utf8 filenames in Windows; fix warnings and platform ifdefs 1642 | 1.09 (2018-02-11) 1643 | fix typo in zlib quality API, improve STB_I_W_STATIC in C++ 1644 | 1.08 (2018-01-29) 1645 | add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter 1646 | 1.07 (2017-07-24) 1647 | doc fix 1648 | 1.06 (2017-07-23) 1649 | writing JPEG (using Jon Olick's code) 1650 | 1.05 ??? 1651 | 1.04 (2017-03-03) 1652 | monochrome BMP expansion 1653 | 1.03 ??? 1654 | 1.02 (2016-04-02) 1655 | avoid allocating large structures on the stack 1656 | 1.01 (2016-01-16) 1657 | STBIW_REALLOC_SIZED: support allocators with no realloc support 1658 | avoid race-condition in crc initialization 1659 | minor compile issues 1660 | 1.00 (2015-09-14) 1661 | installable file IO function 1662 | 0.99 (2015-09-13) 1663 | warning fixes; TGA rle support 1664 | 0.98 (2015-04-08) 1665 | added STBIW_MALLOC, STBIW_ASSERT etc 1666 | 0.97 (2015-01-18) 1667 | fixed HDR asserts, rewrote HDR rle logic 1668 | 0.96 (2015-01-17) 1669 | add HDR output 1670 | fix monochrome BMP 1671 | 0.95 (2014-08-17) 1672 | add monochrome TGA output 1673 | 0.94 (2014-05-31) 1674 | rename private functions to avoid conflicts with stb_image.h 1675 | 0.93 (2014-05-27) 1676 | warning fixes 1677 | 0.92 (2010-08-01) 1678 | casts to unsigned char to fix warnings 1679 | 0.91 (2010-07-17) 1680 | first public release 1681 | 0.90 first internal release 1682 | */ 1683 | 1684 | /* 1685 | ------------------------------------------------------------------------------ 1686 | This software is available under 2 licenses -- choose whichever you prefer. 1687 | ------------------------------------------------------------------------------ 1688 | ALTERNATIVE A - MIT License 1689 | Copyright (c) 2017 Sean Barrett 1690 | Permission is hereby granted, free of charge, to any person obtaining a copy of 1691 | this software and associated documentation files (the "Software"), to deal in 1692 | the Software without restriction, including without limitation the rights to 1693 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 1694 | of the Software, and to permit persons to whom the Software is furnished to do 1695 | so, subject to the following conditions: 1696 | The above copyright notice and this permission notice shall be included in all 1697 | copies or substantial portions of the Software. 1698 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1699 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1700 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1701 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1702 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1703 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1704 | SOFTWARE. 1705 | ------------------------------------------------------------------------------ 1706 | ALTERNATIVE B - Public Domain (www.unlicense.org) 1707 | This is free and unencumbered software released into the public domain. 1708 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 1709 | software, either in source code form or as a compiled binary, for any purpose, 1710 | commercial or non-commercial, and by any means. 1711 | In jurisdictions that recognize copyright laws, the author or authors of this 1712 | software dedicate any and all copyright interest in the software to the public 1713 | domain. We make this dedication for the benefit of the public at large and to 1714 | the detriment of our heirs and successors. We intend this dedication to be an 1715 | overt act of relinquishment in perpetuity of all present and future rights to 1716 | this software under copyright law. 1717 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1718 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1719 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1720 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 1721 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 1722 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 1723 | ------------------------------------------------------------------------------ 1724 | */ 1725 | --------------------------------------------------------------------------------