From dd5efb7175c48ede58ca900bc389ebe6821d2f34 Mon Sep 17 00:00:00 2001 From: korenkonder Date: Tue, 5 Dec 2023 19:03:23 +0300 Subject: [PATCH] First commit --- .gitignore | 8 + DivaGL.sln | 40 + extern/lib/detours.lib | Bin 0 -> 724684 bytes extern/lib/detours.pdb | Bin 0 -> 184320 bytes extern/lib/libdeflatestatic.lib | Bin 0 -> 289892 bytes extern/lib/libdeflatestatic.pdb | Bin 0 -> 94208 bytes extern/lib/syelog.lib | Bin 0 -> 51286 bytes extern/src/Helpers.h | 169 + extern/src/SigScan.h | 111 + extern/src/detours.h | 1233 +++++ extern/src/libdeflate.h | 411 ++ src/DivaGL/DivaGL.rc | 46 + src/DivaGL/DivaGL.vcxproj | 339 ++ src/DivaGL/DivaGL.vcxproj.user | 30 + src/DivaGL/Glitter/glitter.cpp | 146 + src/DivaGL/Glitter/glitter.hpp | 322 ++ src/DivaGL/Glitter/particle.cpp | 33 + src/DivaGL/Glitter/particle_manager.cpp | 23 + src/DivaGL/Glitter/render_group.cpp | 103 + src/DivaGL/Glitter/render_scene.cpp | 1042 ++++ src/DivaGL/Glitter/scene.cpp | 14 + src/DivaGL/auth_3d.cpp | 750 +++ src/DivaGL/auth_3d.hpp | 12 + src/DivaGL/camera.cpp | 92 + src/DivaGL/camera.hpp | 58 + src/DivaGL/color.cpp | 6 + src/DivaGL/color.hpp | 77 + src/DivaGL/dllmain.cpp | 133 + src/DivaGL/gl.hpp | 6371 +++++++++++++++++++++++ src/DivaGL/gl_array_buffer.hpp | 144 + src/DivaGL/gl_element_array_buffer.hpp | 144 + src/DivaGL/gl_shader_storage_buffer.hpp | 144 + src/DivaGL/gl_state.cpp | 489 ++ src/DivaGL/gl_state.hpp | 127 + src/DivaGL/gl_uniform_buffer.hpp | 144 + src/DivaGL/hook.cpp | 117 + src/DivaGL/hook.hpp | 10 + src/DivaGL/inject.cpp | 126 + src/DivaGL/inject.hpp | 15 + src/DivaGL/light_param/fog.cpp | 95 + src/DivaGL/light_param/fog.hpp | 38 + src/DivaGL/light_param/light.cpp | 497 ++ src/DivaGL/light_param/light.hpp | 105 + src/DivaGL/mdl/disp_manager.cpp | 2343 +++++++++ src/DivaGL/mdl/disp_manager.hpp | 449 ++ src/DivaGL/mdl/draw_object.cpp | 1145 ++++ src/DivaGL/mdl/draw_object.hpp | 32 + src/DivaGL/object.cpp | 116 + src/DivaGL/object.hpp | 529 ++ src/DivaGL/print.cpp | 22 + src/DivaGL/print.hpp | 11 + src/DivaGL/render.cpp | 1763 +++++++ src/DivaGL/render.hpp | 204 + src/DivaGL/render_context.cpp | 516 ++ src/DivaGL/render_context.hpp | 331 ++ src/DivaGL/render_manager.cpp | 1781 +++++++ src/DivaGL/render_manager.hpp | 154 + src/DivaGL/render_texture.cpp | 43 + src/DivaGL/render_texture.hpp | 49 + src/DivaGL/renderer/dof.cpp | 273 + src/DivaGL/renderer/dof.hpp | 82 + src/DivaGL/renderer/fbo.cpp | 62 + src/DivaGL/renderer/fbo.hpp | 29 + src/DivaGL/renderer/transparency.cpp | 46 + src/DivaGL/renderer/transparency.hpp | 29 + src/DivaGL/resolution_mode.cpp | 177 + src/DivaGL/resolution_mode.hpp | 55 + src/DivaGL/rob/rob.cpp | 136 + src/DivaGL/rob/rob.hpp | 25 + src/DivaGL/shader_glsl.cpp | 993 ++++ src/DivaGL/shader_glsl.hpp | 114 + src/DivaGL/shader_glsl_ft.cpp | 3387 ++++++++++++ src/DivaGL/shader_glsl_ft.hpp | 87 + src/DivaGL/shader_table.cpp | 237 + src/DivaGL/shader_table.hpp | 218 + src/DivaGL/shadow.cpp | 12 + src/DivaGL/shadow.hpp | 63 + src/DivaGL/shared.cpp | 6 + src/DivaGL/shared.hpp | 19 + src/DivaGL/sprite.cpp | 1133 ++++ src/DivaGL/sprite.hpp | 201 + src/DivaGL/stage.cpp | 206 + src/DivaGL/stage.hpp | 10 + src/DivaGL/stage_param.cpp | 8 + src/DivaGL/stage_param.hpp | 172 + src/DivaGL/texture.cpp | 106 + src/DivaGL/texture.hpp | 95 + src/DivaGL/types.hpp | 72 + src/DivaGL/uniform.cpp | 10 + src/DivaGL/uniform.hpp | 91 + src/DivaGL/wrap.cpp | 2580 +++++++++ src/DivaGL/wrap.hpp | 3432 ++++++++++++ thirdparty.txt | 52 + 93 files changed, 37470 insertions(+) create mode 100644 .gitignore create mode 100644 DivaGL.sln create mode 100644 extern/lib/detours.lib create mode 100644 extern/lib/detours.pdb create mode 100644 extern/lib/libdeflatestatic.lib create mode 100644 extern/lib/libdeflatestatic.pdb create mode 100644 extern/lib/syelog.lib create mode 100644 extern/src/Helpers.h create mode 100644 extern/src/SigScan.h create mode 100644 extern/src/detours.h create mode 100644 extern/src/libdeflate.h create mode 100644 src/DivaGL/DivaGL.rc create mode 100644 src/DivaGL/DivaGL.vcxproj create mode 100644 src/DivaGL/DivaGL.vcxproj.user create mode 100644 src/DivaGL/Glitter/glitter.cpp create mode 100644 src/DivaGL/Glitter/glitter.hpp create mode 100644 src/DivaGL/Glitter/particle.cpp create mode 100644 src/DivaGL/Glitter/particle_manager.cpp create mode 100644 src/DivaGL/Glitter/render_group.cpp create mode 100644 src/DivaGL/Glitter/render_scene.cpp create mode 100644 src/DivaGL/Glitter/scene.cpp create mode 100644 src/DivaGL/auth_3d.cpp create mode 100644 src/DivaGL/auth_3d.hpp create mode 100644 src/DivaGL/camera.cpp create mode 100644 src/DivaGL/camera.hpp create mode 100644 src/DivaGL/color.cpp create mode 100644 src/DivaGL/color.hpp create mode 100644 src/DivaGL/dllmain.cpp create mode 100644 src/DivaGL/gl.hpp create mode 100644 src/DivaGL/gl_array_buffer.hpp create mode 100644 src/DivaGL/gl_element_array_buffer.hpp create mode 100644 src/DivaGL/gl_shader_storage_buffer.hpp create mode 100644 src/DivaGL/gl_state.cpp create mode 100644 src/DivaGL/gl_state.hpp create mode 100644 src/DivaGL/gl_uniform_buffer.hpp create mode 100644 src/DivaGL/hook.cpp create mode 100644 src/DivaGL/hook.hpp create mode 100644 src/DivaGL/inject.cpp create mode 100644 src/DivaGL/inject.hpp create mode 100644 src/DivaGL/light_param/fog.cpp create mode 100644 src/DivaGL/light_param/fog.hpp create mode 100644 src/DivaGL/light_param/light.cpp create mode 100644 src/DivaGL/light_param/light.hpp create mode 100644 src/DivaGL/mdl/disp_manager.cpp create mode 100644 src/DivaGL/mdl/disp_manager.hpp create mode 100644 src/DivaGL/mdl/draw_object.cpp create mode 100644 src/DivaGL/mdl/draw_object.hpp create mode 100644 src/DivaGL/object.cpp create mode 100644 src/DivaGL/object.hpp create mode 100644 src/DivaGL/print.cpp create mode 100644 src/DivaGL/print.hpp create mode 100644 src/DivaGL/render.cpp create mode 100644 src/DivaGL/render.hpp create mode 100644 src/DivaGL/render_context.cpp create mode 100644 src/DivaGL/render_context.hpp create mode 100644 src/DivaGL/render_manager.cpp create mode 100644 src/DivaGL/render_manager.hpp create mode 100644 src/DivaGL/render_texture.cpp create mode 100644 src/DivaGL/render_texture.hpp create mode 100644 src/DivaGL/renderer/dof.cpp create mode 100644 src/DivaGL/renderer/dof.hpp create mode 100644 src/DivaGL/renderer/fbo.cpp create mode 100644 src/DivaGL/renderer/fbo.hpp create mode 100644 src/DivaGL/renderer/transparency.cpp create mode 100644 src/DivaGL/renderer/transparency.hpp create mode 100644 src/DivaGL/resolution_mode.cpp create mode 100644 src/DivaGL/resolution_mode.hpp create mode 100644 src/DivaGL/rob/rob.cpp create mode 100644 src/DivaGL/rob/rob.hpp create mode 100644 src/DivaGL/shader_glsl.cpp create mode 100644 src/DivaGL/shader_glsl.hpp create mode 100644 src/DivaGL/shader_glsl_ft.cpp create mode 100644 src/DivaGL/shader_glsl_ft.hpp create mode 100644 src/DivaGL/shader_table.cpp create mode 100644 src/DivaGL/shader_table.hpp create mode 100644 src/DivaGL/shadow.cpp create mode 100644 src/DivaGL/shadow.hpp create mode 100644 src/DivaGL/shared.cpp create mode 100644 src/DivaGL/shared.hpp create mode 100644 src/DivaGL/sprite.cpp create mode 100644 src/DivaGL/sprite.hpp create mode 100644 src/DivaGL/stage.cpp create mode 100644 src/DivaGL/stage.hpp create mode 100644 src/DivaGL/stage_param.cpp create mode 100644 src/DivaGL/stage_param.hpp create mode 100644 src/DivaGL/texture.cpp create mode 100644 src/DivaGL/texture.hpp create mode 100644 src/DivaGL/types.hpp create mode 100644 src/DivaGL/uniform.cpp create mode 100644 src/DivaGL/uniform.hpp create mode 100644 src/DivaGL/wrap.cpp create mode 100644 src/DivaGL/wrap.hpp create mode 100644 thirdparty.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3517e98 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.vs +bin +lib +obj +src/KKdLib +*.aps +*.cs +!extern/lib diff --git a/DivaGL.sln b/DivaGL.sln new file mode 100644 index 0000000..3425cc9 --- /dev/null +++ b/DivaGL.sln @@ -0,0 +1,40 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30320.27 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DivaGL", "src\DivaGL\DivaGL.vcxproj", "{4D949362-9095-4113-9423-7E0492618F16}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KKdLib", "src\KKdLib\KKdLib.vcxproj", "{4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + DebugDLL|x64 = DebugDLL|x64 + Release|x64 = Release|x64 + ReleaseDLL|x64 = ReleaseDLL|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4D949362-9095-4113-9423-7E0492618F16}.Debug|x64.ActiveCfg = Debug|x64 + {4D949362-9095-4113-9423-7E0492618F16}.Debug|x64.Build.0 = Debug|x64 + {4D949362-9095-4113-9423-7E0492618F16}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {4D949362-9095-4113-9423-7E0492618F16}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {4D949362-9095-4113-9423-7E0492618F16}.Release|x64.ActiveCfg = Release|x64 + {4D949362-9095-4113-9423-7E0492618F16}.Release|x64.Build.0 = Release|x64 + {4D949362-9095-4113-9423-7E0492618F16}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {4D949362-9095-4113-9423-7E0492618F16}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.Debug|x64.ActiveCfg = DebugOpt|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.Debug|x64.Build.0 = DebugOpt|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.DebugDLL|x64.ActiveCfg = DebugOpt|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.DebugDLL|x64.Build.0 = DebugOpt|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.Release|x64.ActiveCfg = Release|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.Release|x64.Build.0 = Release|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.ReleaseDLL|x64.ActiveCfg = Release|x64 + {4C9636B9-E5B6-41E5-9AFC-5B33CC9633DE}.ReleaseDLL|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {90795F07-C3EF-4F00-A79A-0647DBB7117E} + EndGlobalSection +EndGlobal diff --git a/extern/lib/detours.lib b/extern/lib/detours.lib new file mode 100644 index 0000000000000000000000000000000000000000..27fbf1fed2069f81a0919efa1c3ddada2f30620a GIT binary patch literal 724684 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�B<{^V^k7ou$562>u$F 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
_}L5r6=wBQe70^8HvHuQ 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 wu}#g()BJ{vsJfEr3CvE3Px# literal 0 HcmV?d00001 diff --git a/extern/lib/detours.pdb b/extern/lib/detours.pdb new file mode 100644 index 0000000000000000000000000000000000000000..095f79fd5deca5859b12a08453ee7c46c2ad5f47 GIT binary patch literal 184320 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
  • eZ@H8tnTC&}o7s_z%zJlyjv1 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 literal 0 HcmV?d00001 diff --git a/extern/lib/libdeflatestatic.lib b/extern/lib/libdeflatestatic.lib new file mode 100644 index 0000000000000000000000000000000000000000..2c457d1d77fe01c630179976426039c1b3fd3aa2 GIT binary patch literal 289892 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 R?e;ctteB$tSr3IslBeF+rFMY3mY_Hy! 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�?aY{qQ+gG!9@f-@16fMNEV%Cbn5bguP94 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 BTTK7} literal 0 HcmV?d00001 diff --git a/extern/lib/syelog.lib b/extern/lib/syelog.lib new file mode 100644 index 0000000000000000000000000000000000000000..e8d1d6889dd3843524852c79ff092f87d22cbe3a GIT binary patch literal 51286 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 literal 0 HcmV?d00001 diff --git a/extern/src/Helpers.h b/extern/src/Helpers.h new file mode 100644 index 0000000..94d1192 --- /dev/null +++ b/extern/src/Helpers.h @@ -0,0 +1,169 @@ +#pragma once + +#include "detours.h" + +#define _CONCAT2(x, y) x##y +#define CONCAT2(x, y) _CONCAT(x, y) +#define INSERT_PADDING(length) \ + uint8_t CONCAT2(pad, __LINE__)[length] + +#define ASSERT_OFFSETOF(type, field, offset) \ + static_assert(offsetof(type, field) == offset, "offsetof assertion failed") + +#define ASSERT_SIZEOF(type, size) \ + static_assert(sizeof(type) == size, "sizeof assertion failed") + +#ifdef BASE_ADDRESS +const HMODULE MODULE_HANDLE = GetModuleHandle(nullptr); + +#define ASLR(address) \ + ((size_t)MODULE_HANDLE + (size_t)address - (size_t)BASE_ADDRESS) +#endif + +#define FUNCTION_PTR(returnType, callingConvention, function, location, ...) \ + returnType (callingConvention *function)(__VA_ARGS__) = (returnType(callingConvention*)(__VA_ARGS__))(location) + +#define FUNCTION_PTR_H(returnType, callingConvention, function, ...) \ + extern returnType (callingConvention *function) (__VA_ARGS__) + +#define PROC_ADDRESS(libraryName, procName) \ + GetProcAddress(LoadLibrary(TEXT(libraryName)), procName) + +#define HOOK(returnType, callingConvention, functionName, location, ...) \ + typedef returnType callingConvention _##functionName(__VA_ARGS__); \ + _##functionName* original##functionName = (_##functionName*)(location); \ + returnType callingConvention implOf##functionName(__VA_ARGS__) + +#define INSTALL_HOOK(functionName) \ + { \ + DetourTransactionBegin(); \ + DetourUpdateThread(GetCurrentThread()); \ + DetourAttach((void**)&original##functionName, implOf##functionName); \ + DetourTransactionCommit(); \ + } + +#define VTABLE_HOOK(returnType, callingConvention, className, functionName, ...) \ + typedef returnType callingConvention className##functionName(className* This, __VA_ARGS__); \ + className##functionName* original##className##functionName; \ + returnType callingConvention implOf##className##functionName(className* This, __VA_ARGS__) + +#define INSTALL_VTABLE_HOOK(className, object, functionName, functionIndex) \ + { \ + void** addr = &(*(void***)object)[functionIndex]; \ + if (*addr != implOf##className##functionName) \ + { \ + original##className##functionName = (className##functionName*)*addr; \ + DWORD oldProtect; \ + VirtualProtect(addr, sizeof(void*), PAGE_EXECUTE_READWRITE, &oldProtect); \ + *addr = implOf##className##functionName; \ + VirtualProtect(addr, sizeof(void*), oldProtect, &oldProtect); \ + } \ + } + +#define READ_MEMORY(location, type) \ + *(type *)location + +#define WRITE_MEMORY(location, type, ...) \ + { \ + const type data[] = { __VA_ARGS__ }; \ + DWORD oldProtect; \ + VirtualProtect((void*)(location), sizeof(data), PAGE_EXECUTE_READWRITE, &oldProtect); \ + memcpy((void*)(location), data, sizeof(data)); \ + VirtualProtect((void*)(location), sizeof(data), oldProtect, &oldProtect); \ + } + +#define WRITE_MEMORY_STRING(location, data, length) \ + { \ + DWORD oldProtect; \ + VirtualProtect ((void *)(location), length, PAGE_EXECUTE_READWRITE, &oldProtect); \ + memcpy ((void *)(location), data, length); \ + VirtualProtect ((void *)(location), length, oldProtect, &oldProtect); \ + } + +#define WRITE_JUMP(location, function) \ + { \ + WRITE_MEMORY(location, uint8_t, 0xE9); \ + WRITE_MEMORY(location + 1, uint32_t, (uint32_t)(function - location - 5)); \ + } + +#define WRITE_CALL(location, function) \ + { \ + WRITE_MEMORY(location, uint8_t, 0xE8); \ + WRITE_MEMORY(location + 1, uint32_t, (uint32_t)(function - location - 5)); \ + } + +#define WRITE_NOP(location, count) \ + { \ + DWORD oldProtect; \ + VirtualProtect((void*)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \ + for (size_t i = 0; i < (size_t)(count); i++) \ + *((uint8_t*)(location) + i) = 0x90; \ + VirtualProtect((void*)(location), (size_t)(count), oldProtect, &oldProtect); \ + } + +#define WRITE_NOP_1(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x90); \ + } + +#define WRITE_NOP_2(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x66, 0x90); \ + } + +#define WRITE_NOP_3(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x0F, 0x1F, 0x00); \ + } + +#define WRITE_NOP_4(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x0F, 0x1F, 0x40, 0x00); \ + } + +#define WRITE_NOP_5(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x0F, 0x1F, 0x44, 0x00, 0x00); \ + } + +#define WRITE_NOP_6(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00); \ + } + +#define WRITE_NOP_7(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00); \ + } + +#define WRITE_NOP_8(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00); \ + } + +#define WRITE_NOP_9(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00); \ + } + +#define WRITE_NOP_10(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00); \ + } + +#define WRITE_NOP_11(location) \ + { \ + WRITE_MEMORY(location, uint8_t, 0x66, 0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00); \ + } + +#define WRITE_NULL(location, count) \ + { \ + DWORD oldProtect; \ + VirtualProtect((void*)(location), (size_t)(count), PAGE_EXECUTE_READWRITE, &oldProtect); \ + for (size_t i = 0; i < (size_t)(count); i++) \ + *((uint8_t*)(location) + i) = 0x00; \ + VirtualProtect((void*)(location), (size_t)(count), oldProtect, &oldProtect); \ + } + +#define COUNTOFARR(arr) \ + sizeof(arr) / sizeof(arr[0]) diff --git a/extern/src/SigScan.h b/extern/src/SigScan.h new file mode 100644 index 0000000..f5ed89d --- /dev/null +++ b/extern/src/SigScan.h @@ -0,0 +1,111 @@ +#pragma once + +#include + +FORCEINLINE const MODULEINFO& getModuleInfo() { + static MODULEINFO moduleInfo; + + if (moduleInfo.SizeOfImage) + return moduleInfo; + + ZeroMemory(&moduleInfo, sizeof(MODULEINFO)); + GetModuleInformation(GetCurrentProcess(), GetModuleHandle(nullptr), &moduleInfo, sizeof(MODULEINFO)); + + return moduleInfo; +} + +// Signature scan in specified memory region +FORCEINLINE void* sigScan(const char* signature, const char* mask, size_t sigSize, void* memory, const size_t memorySize) { + if (sigSize == 0) + sigSize = strlen(mask); + + for (size_t i = 0; i < memorySize; i++) { + char* currMemory = (char*)memory + i; + + size_t j; + for (j = 0; j < sigSize; j++) { + if (mask[j] != '?' && signature[j] != currMemory[j]) + break; + } + + if (j == sigSize) + return currMemory; + } + + return nullptr; +} + +// Signature scan in current process +FORCEINLINE void* sigScan(const char* signature, const char* mask, void* hint) { + const MODULEINFO& info = getModuleInfo(); + const size_t sigSize = strlen(mask); + + // Ensure hint address is within the process memory region so there are no crashes. + if ((hint >= info.lpBaseOfDll) && ((char*)hint + sigSize <= (char*)info.lpBaseOfDll + info.SizeOfImage)) { + void* result = sigScan(signature, mask, sigSize, hint, sigSize); + + if (result) + return result; + } + + return sigScan(signature, mask, sigSize, info.lpBaseOfDll, info.SizeOfImage); +} + +// Signature scan string in specified memory region +FORCEINLINE void* sigScanString(const char* signature, void* memory, const size_t memorySize) { + const size_t sigSize = strlen(signature); + + for (size_t i = 0; i < memorySize; i++) { + char* currMemory = (char*)memory + i; + + if (!memcmp(signature, currMemory, sigSize)) + return currMemory; + } + + return nullptr; +} + +// Signature scan string in current process +FORCEINLINE void* sigScanString(const char* signature) { + const MODULEINFO& info = getModuleInfo(); + return sigScanString(signature, info.lpBaseOfDll, info.SizeOfImage); +} + +// Automatically scanned signature +#define SIG_SCAN(x, y, ...) \ + FORCEINLINE void* x(); \ + inline bool x##Valid = true; \ + inline void* x##Addr = x(); \ + FORCEINLINE void* x() { \ + constexpr const char* x##Data[] = { __VA_ARGS__ }; \ + constexpr size_t x##Size = _countof(x##Data); \ + if (!x##Addr) { \ + if constexpr (x##Size == 2) { \ + x##Addr = sigScan(x##Data[0], x##Data[1], (void*)(y)); \ + if (x##Addr) \ + return x##Addr; \ + } \ + else \ + for (int i = 0; i < x##Size; i += 2) { \ + x##Addr = sigScan(x##Data[i], x##Data[i + 1], (void*)(y)); \ + if (x##Addr) \ + return x##Addr; \ + } \ + x##Valid = false; \ + } \ + return x##Addr; \ + } + +#define SIG_SCAN_STRING(x, y) \ + FORCEINLINE void* x(); \ + inline bool x##Valid = true; \ + inline void* x##Addr = x(); \ + FORCEINLINE void* x() { \ + if (!x##Addr) { \ + x##Addr = sigScanString(y); \ + if (x##Addr) \ + return x##Addr; \ + x##Valid = false; \ + } \ + return x##Addr; \ + } diff --git a/extern/src/detours.h b/extern/src/detours.h new file mode 100644 index 0000000..f3738af --- /dev/null +++ b/extern/src/detours.h @@ -0,0 +1,1233 @@ +///////////////////////////////////////////////////////////////////////////// +// +// Core Detours Functionality (detours.h of detours.lib) +// +// Microsoft Research Detours Package, Version 4.0.1 +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#pragma once +#ifndef _DETOURS_H_ +#define _DETOURS_H_ + +#define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH + +////////////////////////////////////////////////////////////////////////////// +// + +#ifdef DETOURS_INTERNAL + +#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 +#define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 + +#pragma warning(disable:4068) // unknown pragma (suppress) + +#if _MSC_VER >= 1900 +#pragma warning(push) +#pragma warning(disable:4091) // empty typedef +#endif + +// Suppress declspec(dllimport) for the sake of Detours +// users that provide kernel32 functionality themselves. +// This is ok in the mainstream case, it will just cost +// an extra instruction calling some functions, which +// LTCG optimizes away. +// +#define _KERNEL32_ 1 +#define _USER32_ 1 + +#include +#if (_MSC_VER < 1310) +#else +#pragma warning(push) +#if _MSC_VER > 1400 +#pragma warning(disable:6102 6103) // /analyze warnings +#endif +#include +#include +#pragma warning(pop) +#endif +#include + +// Allow Detours to cleanly compile with the MingW toolchain. +// +#ifdef __GNUC__ +#define __try +#define __except(x) if (0) +#include +#include +#endif + +// From winerror.h, as this error isn't found in some SDKs: +// +// MessageId: ERROR_DYNAMIC_CODE_BLOCKED +// +// MessageText: +// +// The operation was blocked as the process prohibits dynamic code generation. +// +#define ERROR_DYNAMIC_CODE_BLOCKED 1655L + +#endif // DETOURS_INTERNAL + +////////////////////////////////////////////////////////////////////////////// +// + +#undef DETOURS_X64 +#undef DETOURS_X86 +#undef DETOURS_IA64 +#undef DETOURS_ARM +#undef DETOURS_ARM64 +#undef DETOURS_BITS +#undef DETOURS_32BIT +#undef DETOURS_64BIT + +#if defined(_X86_) +#define DETOURS_X86 +#define DETOURS_OPTION_BITS 64 + +#elif defined(_AMD64_) +#define DETOURS_X64 +#define DETOURS_OPTION_BITS 32 + +#elif defined(_IA64_) +#define DETOURS_IA64 +#define DETOURS_OPTION_BITS 32 + +#elif defined(_ARM_) +#define DETOURS_ARM + +#elif defined(_ARM64_) +#define DETOURS_ARM64 + +#else +#error Unknown architecture (x86, amd64, ia64, arm, arm64) +#endif + +#ifdef _WIN64 +#undef DETOURS_32BIT +#define DETOURS_64BIT 1 +#define DETOURS_BITS 64 +// If all 64bit kernels can run one and only one 32bit architecture. +//#define DETOURS_OPTION_BITS 32 +#else +#define DETOURS_32BIT 1 +#undef DETOURS_64BIT +#define DETOURS_BITS 32 +// If all 64bit kernels can run one and only one 32bit architecture. +//#define DETOURS_OPTION_BITS 32 +#endif + +/////////////////////////////////////////////////////////////// Helper Macros. +// +#define DETOURS_STRINGIFY_(x) #x +#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) + +#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) + +////////////////////////////////////////////////////////////////////////////// +// + +#if (_MSC_VER < 1299) && !defined(__MINGW32__) +typedef LONG LONG_PTR; +typedef ULONG ULONG_PTR; +#endif + +///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. +// +// These definitions are include so that Detours will build even if the +// compiler doesn't have full SAL 2.0 support. +// +#ifndef DETOURS_DONT_REMOVE_SAL_20 + +#ifdef DETOURS_TEST_REMOVE_SAL_20 +#undef _Analysis_assume_ +#undef _Benign_race_begin_ +#undef _Benign_race_end_ +#undef _Field_range_ +#undef _Field_size_ +#undef _In_ +#undef _In_bytecount_ +#undef _In_count_ +#undef __in_ecount +#undef _In_opt_ +#undef _In_opt_bytecount_ +#undef _In_opt_count_ +#undef _In_opt_z_ +#undef _In_range_ +#undef _In_reads_ +#undef _In_reads_bytes_ +#undef _In_reads_opt_ +#undef _In_reads_opt_bytes_ +#undef _In_reads_or_z_ +#undef _In_z_ +#undef _Inout_ +#undef _Inout_opt_ +#undef _Inout_z_count_ +#undef _Out_ +#undef _Out_opt_ +#undef _Out_writes_ +#undef _Outptr_result_maybenull_ +#undef _Readable_bytes_ +#undef _Success_ +#undef _Writable_bytes_ +#undef _Pre_notnull_ +#endif + +#if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) +#define _Outptr_result_maybenull_ _Deref_out_opt_z_ +#endif + +#if defined(_In_count_) && !defined(_In_reads_) +#define _In_reads_(x) _In_count_(x) +#endif + +#if defined(_In_opt_count_) && !defined(_In_reads_opt_) +#define _In_reads_opt_(x) _In_opt_count_(x) +#endif + +#if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) +#define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) +#endif + +#if defined(_In_bytecount_) && !defined(_In_reads_bytes_) +#define _In_reads_bytes_(x) _In_bytecount_(x) +#endif + +#ifndef _In_ +#define _In_ +#endif + +#ifndef _In_bytecount_ +#define _In_bytecount_(x) +#endif + +#ifndef _In_count_ +#define _In_count_(x) +#endif + +#ifndef __in_ecount +#define __in_ecount(x) +#endif + +#ifndef _In_opt_ +#define _In_opt_ +#endif + +#ifndef _In_opt_bytecount_ +#define _In_opt_bytecount_(x) +#endif + +#ifndef _In_opt_count_ +#define _In_opt_count_(x) +#endif + +#ifndef _In_opt_z_ +#define _In_opt_z_ +#endif + +#ifndef _In_range_ +#define _In_range_(x,y) +#endif + +#ifndef _In_reads_ +#define _In_reads_(x) +#endif + +#ifndef _In_reads_bytes_ +#define _In_reads_bytes_(x) +#endif + +#ifndef _In_reads_opt_ +#define _In_reads_opt_(x) +#endif + +#ifndef _In_reads_opt_bytes_ +#define _In_reads_opt_bytes_(x) +#endif + +#ifndef _In_reads_or_z_ +#define _In_reads_or_z_ +#endif + +#ifndef _In_z_ +#define _In_z_ +#endif + +#ifndef _Inout_ +#define _Inout_ +#endif + +#ifndef _Inout_opt_ +#define _Inout_opt_ +#endif + +#ifndef _Inout_z_count_ +#define _Inout_z_count_(x) +#endif + +#ifndef _Out_ +#define _Out_ +#endif + +#ifndef _Out_opt_ +#define _Out_opt_ +#endif + +#ifndef _Out_writes_ +#define _Out_writes_(x) +#endif + +#ifndef _Outptr_result_maybenull_ +#define _Outptr_result_maybenull_ +#endif + +#ifndef _Writable_bytes_ +#define _Writable_bytes_(x) +#endif + +#ifndef _Readable_bytes_ +#define _Readable_bytes_(x) +#endif + +#ifndef _Success_ +#define _Success_(x) +#endif + +#ifndef _Pre_notnull_ +#define _Pre_notnull_ +#endif + +#ifdef DETOURS_INTERNAL + +#pragma warning(disable:4615) // unknown warning type (suppress with older compilers) + +#ifndef _Benign_race_begin_ +#define _Benign_race_begin_ +#endif + +#ifndef _Benign_race_end_ +#define _Benign_race_end_ +#endif + +#ifndef _Field_size_ +#define _Field_size_(x) +#endif + +#ifndef _Field_range_ +#define _Field_range_(x,y) +#endif + +#ifndef _Analysis_assume_ +#define _Analysis_assume_(x) +#endif + +#endif // DETOURS_INTERNAL +#endif // DETOURS_DONT_REMOVE_SAL_20 + +////////////////////////////////////////////////////////////////////////////// +// +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct _GUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[ 8 ]; +} GUID; + +#ifdef INITGUID +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name +#endif // INITGUID +#endif // !GUID_DEFINED + +#if defined(__cplusplus) +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#define REFGUID const GUID & +#endif // !_REFGUID_DEFINED +#else // !__cplusplus +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#define REFGUID const GUID * const +#endif // !_REFGUID_DEFINED +#endif // !__cplusplus + +#ifndef ARRAYSIZE +#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) +#endif + +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/////////////////////////////////////////////////// Instruction Target Macros. +// +#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) +#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) +#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" + +extern const GUID DETOUR_EXE_RESTORE_GUID; +extern const GUID DETOUR_EXE_HELPER_GUID; + +#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! +typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; + +#ifndef DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS +#define DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 32 +#endif // !DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS + +/////////////////////////////////////////////////////////// Binary Structures. +// +#pragma pack(push, 8) +typedef struct _DETOUR_SECTION_HEADER +{ + DWORD cbHeaderSize; + DWORD nSignature; + DWORD nDataOffset; + DWORD cbDataSize; + + DWORD nOriginalImportVirtualAddress; + DWORD nOriginalImportSize; + DWORD nOriginalBoundImportVirtualAddress; + DWORD nOriginalBoundImportSize; + + DWORD nOriginalIatVirtualAddress; + DWORD nOriginalIatSize; + DWORD nOriginalSizeOfImage; + DWORD cbPrePE; + + DWORD nOriginalClrFlags; + DWORD reserved1; + DWORD reserved2; + DWORD reserved3; + + // Followed by cbPrePE bytes of data. +} DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; + +typedef struct _DETOUR_SECTION_RECORD +{ + DWORD cbBytes; + DWORD nReserved; + GUID guid; +} DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; + +typedef struct _DETOUR_CLR_HEADER +{ + // Header versioning + ULONG cb; + USHORT MajorRuntimeVersion; + USHORT MinorRuntimeVersion; + + // Symbol table and startup information + IMAGE_DATA_DIRECTORY MetaData; + ULONG Flags; + + // Followed by the rest of the IMAGE_COR20_HEADER +} DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; + +typedef struct _DETOUR_EXE_RESTORE +{ + DWORD cb; + DWORD cbidh; + DWORD cbinh; + DWORD cbclr; + + PBYTE pidh; + PBYTE pinh; + PBYTE pclr; + + IMAGE_DOS_HEADER idh; + union { + IMAGE_NT_HEADERS inh; // all environments have this +#ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this + IMAGE_NT_HEADERS32 inh32; +#endif +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this + IMAGE_NT_HEADERS64 inh64; +#endif +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this + BYTE raw[sizeof(IMAGE_NT_HEADERS64) + + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; +#else + BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; +#endif + }; + DETOUR_CLR_HEADER clr; + +} DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; + +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC +C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); +#endif + +// The size can change, but assert for clarity due to the muddying #ifdefs. +#ifdef _WIN64 +C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); +#else +C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); +#endif + +typedef struct _DETOUR_EXE_HELPER +{ + DWORD cb; + DWORD pid; + DWORD nDlls; + CHAR rDlls[4]; +} DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; + +#pragma pack(pop) + +#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ +{ \ + sizeof(DETOUR_SECTION_HEADER),\ + DETOUR_SECTION_HEADER_SIGNATURE,\ + sizeof(DETOUR_SECTION_HEADER),\ + (cbSectionSize),\ + \ + 0,\ + 0,\ + 0,\ + 0,\ + \ + 0,\ + 0,\ + 0,\ + 0,\ +} + +///////////////////////////////////////////////////////////// Binary Typedefs. +// +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( + _In_opt_ PVOID pContext, + _In_opt_ LPCSTR pszFile, + _Outptr_result_maybenull_ LPCSTR *ppszOutFile); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( + _In_opt_ PVOID pContext, + _In_ LPCSTR pszOrigFile, + _In_ LPCSTR pszFile, + _Outptr_result_maybenull_ LPCSTR *ppszOutFile); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( + _In_opt_ PVOID pContext, + _In_ ULONG nOrigOrdinal, + _In_ ULONG nOrdinal, + _Out_ ULONG *pnOutOrdinal, + _In_opt_ LPCSTR pszOrigSymbol, + _In_opt_ LPCSTR pszSymbol, + _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( + _In_opt_ PVOID pContext); + +typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, + _In_ ULONG nOrdinal, + _In_opt_ LPCSTR pszName, + _In_opt_ PVOID pCode); + +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, + _In_opt_ HMODULE hModule, + _In_opt_ LPCSTR pszFile); + +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, + _In_ DWORD nOrdinal, + _In_opt_ LPCSTR pszFunc, + _In_opt_ PVOID pvFunc); + +// Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, + _In_ DWORD nOrdinal, + _In_opt_ LPCSTR pszFunc, + _In_opt_ PVOID* ppvFunc); + +typedef VOID * PDETOUR_BINARY; +typedef VOID * PDETOUR_LOADED_BINARY; + +//////////////////////////////////////////////////////////// Transaction APIs. +// +LONG WINAPI DetourTransactionBegin(VOID); +LONG WINAPI DetourTransactionAbort(VOID); +LONG WINAPI DetourTransactionCommit(VOID); +LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); + +LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); + +LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour); + +LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour, + _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, + _Out_opt_ PVOID *ppRealTarget, + _Out_opt_ PVOID *ppRealDetour); + +LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour); + +BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); +BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); +PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); +PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); + +////////////////////////////////////////////////////////////// Code Functions. +// +PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, + _In_ LPCSTR pszFunction); +PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, + _Out_opt_ PVOID *ppGlobals); +PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, + _Inout_opt_ PVOID *ppDstPool, + _In_ PVOID pSrc, + _Out_opt_ PVOID *ppTarget, + _Out_opt_ LONG *plExtra); +BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, + _In_ BOOL fLimitReferencesToModule); +PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, + _Out_ PDWORD pcbAllocatedSize); +BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode, + _In_ PBYTE pbAddress); + +///////////////////////////////////////////////////// Loaded Binary Functions. +// +HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); +HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); +PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); +ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); +BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); +BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, + _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); + +BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, + _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, + _In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); + +BOOL WINAPI DetourFreePayload(_In_ PVOID pvData); +///////////////////////////////////////////////// Persistent Binary Functions. +// + +PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, + _Out_opt_ GUID *pGuid, + _Out_ DWORD *pcbData, + _Inout_ DWORD *pnIterator); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, + _In_ REFGUID rguid, + _Out_ DWORD *pcbData); + +PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, + _In_ REFGUID rguid, + _In_reads_opt_(cbData) PVOID pData, + _In_ DWORD cbData); +BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); +BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); +BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); +BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, + _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, + _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, + _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); +BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); +BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); + +/////////////////////////////////////////////////// Create Process & Load Dll. +// +_Success_(return != NULL) +PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( + _In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation); + +typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation); + +BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDll DetourCreateProcessWithDllW +#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW +#else +#define DetourCreateProcessWithDll DetourCreateProcessWithDllA +#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA +#endif // !UNICODE + +BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW +#else +#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA +#endif // !UNICODE + +BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW +#else +#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA +#endif // !UNICODE + +BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, + _In_ LPCSTR lpDllName, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, + _In_ LPCSTR lpDllName, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourProcessViaHelper DetourProcessViaHelperW +#else +#define DetourProcessViaHelper DetourProcessViaHelperA +#endif // !UNICODE + +BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW +#else +#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA +#endif // !UNICODE + +BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ DWORD nDlls); + +BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, + _In_ HMODULE hImage, + _In_ BOOL bIs32Bit, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ DWORD nDlls); + +BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _In_reads_bytes_(cbData) LPCVOID pvData, + _In_ DWORD cbData); +_Success_(return != NULL) +PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _In_reads_bytes_(cbData) LPCVOID pvData, + _In_ DWORD cbData); + +BOOL WINAPI DetourRestoreAfterWith(VOID); +BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, + _In_ DWORD cbData); +BOOL WINAPI DetourIsHelperProcess(VOID); +VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, + _In_ HINSTANCE, + _In_ LPSTR, + _In_ INT); + +// +////////////////////////////////////////////////////////////////////////////// +#ifdef __cplusplus +} +#endif // __cplusplus + +/////////////////////////////////////////////////// Type-safe overloads for C++ +// +#if __cplusplus >= 201103L || _MSVC_LANG >= 201103L +#include + +template +struct DetoursIsFunctionPointer : std::false_type {}; + +template +struct DetoursIsFunctionPointer : std::is_function::type> {}; + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourAttach(_Inout_ T *ppPointer, + _In_ T pDetour) noexcept +{ + return DetourAttach( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour)); +} + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourAttachEx(_Inout_ T *ppPointer, + _In_ T pDetour, + _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, + _Out_opt_ T *ppRealTarget, + _Out_opt_ T *ppRealDetour) noexcept +{ + return DetourAttachEx( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour), + ppRealTrampoline, + reinterpret_cast(ppRealTarget), + reinterpret_cast(ppRealDetour)); +} + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourDetach(_Inout_ T *ppPointer, + _In_ T pDetour) noexcept +{ + return DetourDetach( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour)); +} + +#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L +// +////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////// Detours Internal Definitions. +// +#ifdef __cplusplus +#ifdef DETOURS_INTERNAL + +#define NOTHROW +// #define NOTHROW (nothrow) + +////////////////////////////////////////////////////////////////////////////// +// +#if (_MSC_VER < 1299) && !defined(__GNUC__) +#include +typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; +typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; +typedef IMAGEHLP_SYMBOL SYMBOL_INFO; +typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; + +static inline +LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) +{ + return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); +} +#else +#pragma warning(push) +#pragma warning(disable:4091) // empty typedef +#include +#pragma warning(pop) +#endif + +#ifdef IMAGEAPI // defined by DBGHELP.H +typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); + +typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, + _In_opt_ LPCSTR UserSearchPath, + _In_ BOOL fInvadeProcess); +typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); +typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); +typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, + _In_opt_ HANDLE hFile, + _In_opt_ LPSTR ImageName, + _In_opt_ LPSTR ModuleName, + _In_ DWORD64 BaseOfDll, + _In_ DWORD SizeOfDll); +typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, + _In_ DWORD64 qwAddr, + _Out_ PIMAGEHLP_MODULE64 ModuleInfo); +typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, + _In_ LPSTR Name, + _Out_ PSYMBOL_INFO Symbol); + +typedef struct _DETOUR_SYM_INFO +{ + HANDLE hProcess; + HMODULE hDbgHelp; + PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; + PF_SymInitialize pfSymInitialize; + PF_SymSetOptions pfSymSetOptions; + PF_SymGetOptions pfSymGetOptions; + PF_SymLoadModule64 pfSymLoadModule64; + PF_SymGetModuleInfo64 pfSymGetModuleInfo64; + PF_SymFromName pfSymFromName; +} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; + +PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); + +#endif // IMAGEAPI + +#if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) +#error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) +#endif +#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 + +#ifdef _DEBUG + +int Detour_AssertExprWithFunctionName(int reportType, const char* filename, int linenumber, const char* FunctionName, const char* msg); + +#define DETOUR_ASSERT_EXPR_WITH_FUNCTION(expr, msg) \ + (void) ((expr) || \ + (1 != Detour_AssertExprWithFunctionName(_CRT_ASSERT, __FILE__, __LINE__,__FUNCTION__, msg)) || \ + (_CrtDbgBreak(), 0)) + +#define DETOUR_ASSERT(expr) DETOUR_ASSERT_EXPR_WITH_FUNCTION((expr), #expr) + +#else// _DEBUG +#define DETOUR_ASSERT(expr) +#endif// _DEBUG + +#ifndef DETOUR_TRACE +#if DETOUR_DEBUG +#define DETOUR_TRACE(x) printf x +#define DETOUR_BREAK() __debugbreak() +#include +#include +#else +#define DETOUR_TRACE(x) +#define DETOUR_BREAK() +#endif +#endif + +#if 1 || defined(DETOURS_IA64) + +// +// IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. +// + +#define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) + +#define DETOUR_IA64_TEMPLATE_OFFSET (0) +#define DETOUR_IA64_TEMPLATE_SIZE (5) + +#define DETOUR_IA64_INSTRUCTION_SIZE (41) +#define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) +#define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) +#define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) + +C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); + +__declspec(align(16)) struct DETOUR_IA64_BUNDLE +{ + public: + union + { + BYTE data[16]; + UINT64 wide[2]; + }; + + enum { + A_UNIT = 1u, + I_UNIT = 2u, + M_UNIT = 3u, + B_UNIT = 4u, + F_UNIT = 5u, + L_UNIT = 6u, + X_UNIT = 7u, + }; + struct DETOUR_IA64_METADATA + { + ULONG nTemplate : 8; // Instruction template. + ULONG nUnit0 : 4; // Unit for slot 0 + ULONG nUnit1 : 4; // Unit for slot 1 + ULONG nUnit2 : 4; // Unit for slot 2 + }; + + protected: + static const DETOUR_IA64_METADATA s_rceCopyTable[33]; + + UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; + + bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, + _In_ BYTE slot, + _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; + + // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 + // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. + + // 00 + // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. + // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] + // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] + // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] + // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] + // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] + // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] + // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] + BYTE GetTemplate() const; + // Get 4 bit opcodes. + BYTE GetInst0() const; + BYTE GetInst1() const; + BYTE GetInst2() const; + BYTE GetUnit(BYTE slot) const; + BYTE GetUnit0() const; + BYTE GetUnit1() const; + BYTE GetUnit2() const; + // Get 37 bit data. + UINT64 GetData0() const; + UINT64 GetData1() const; + UINT64 GetData2() const; + + // Get/set the full 41 bit instructions. + UINT64 GetInstruction(BYTE slot) const; + UINT64 GetInstruction0() const; + UINT64 GetInstruction1() const; + UINT64 GetInstruction2() const; + void SetInstruction(BYTE slot, UINT64 instruction); + void SetInstruction0(UINT64 instruction); + void SetInstruction1(UINT64 instruction); + void SetInstruction2(UINT64 instruction); + + // Get/set bitfields. + static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); + static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); + + // Get specific read-only fields. + static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode + static UINT64 GetX(UINT64 instruction); // 1bit opcode extension + static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension + static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension + + // Get/set specific fields. + static UINT64 GetImm7a(UINT64 instruction); + static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); + static UINT64 GetImm13c(UINT64 instruction); + static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); + static UINT64 GetSignBit(UINT64 instruction); + static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); + static UINT64 GetImm20a(UINT64 instruction); + static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); + static UINT64 GetImm20b(UINT64 instruction); + static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); + + static UINT64 SignExtend(UINT64 Value, UINT64 Offset); + + BOOL IsMovlGp() const; + + VOID SetInst(BYTE Slot, BYTE nInst); + VOID SetInst0(BYTE nInst); + VOID SetInst1(BYTE nInst); + VOID SetInst2(BYTE nInst); + VOID SetData(BYTE Slot, UINT64 nData); + VOID SetData0(UINT64 nData); + VOID SetData1(UINT64 nData); + VOID SetData2(UINT64 nData); + BOOL SetNop(BYTE Slot); + BOOL SetNop0(); + BOOL SetNop1(); + BOOL SetNop2(); + + public: + BOOL IsBrl() const; + VOID SetBrl(); + VOID SetBrl(UINT64 target); + UINT64 GetBrlTarget() const; + VOID SetBrlTarget(UINT64 target); + VOID SetBrlImm(UINT64 imm); + UINT64 GetBrlImm() const; + + UINT64 GetMovlGp() const; + VOID SetMovlGp(UINT64 gp); + + VOID SetStop(); + + UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; +}; +#endif // DETOURS_IA64 + +#ifdef DETOURS_ARM + +#define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) +#define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) + +#endif // DETOURS_ARM + +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define DETOUR_OFFLINE_LIBRARY(x) \ +PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ + _Inout_opt_ PVOID *ppDstPool, \ + _In_ PVOID pSrc, \ + _Out_opt_ PVOID *ppTarget, \ + _Out_opt_ LONG *plExtra); \ + \ +BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ + _In_ BOOL fLimitReferencesToModule); \ + +DETOUR_OFFLINE_LIBRARY(X86) +DETOUR_OFFLINE_LIBRARY(X64) +DETOUR_OFFLINE_LIBRARY(ARM) +DETOUR_OFFLINE_LIBRARY(ARM64) +DETOUR_OFFLINE_LIBRARY(IA64) + +#undef DETOUR_OFFLINE_LIBRARY + +////////////////////////////////////////////////////////////////////////////// +// +// Helpers for manipulating page protection. +// + +_Success_(return != FALSE) +BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, + _In_ PVOID pAddress, + _In_ SIZE_T nSize, + _In_ DWORD dwNewProtect, + _Out_ PDWORD pdwOldProtect); + +_Success_(return != FALSE) +BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, + _In_ SIZE_T nSize, + _In_ DWORD dwNewProtect, + _Out_ PDWORD pdwOldProtect); + +// Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID +BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); +#ifdef __cplusplus +} +#endif // __cplusplus + +////////////////////////////////////////////////////////////////////////////// + +#define MM_ALLOCATION_GRANULARITY 0x10000 + +////////////////////////////////////////////////////////////////////////////// + +#endif // DETOURS_INTERNAL +#endif // __cplusplus + +#endif // _DETOURS_H_ +// +//////////////////////////////////////////////////////////////// End of File. diff --git a/extern/src/libdeflate.h b/extern/src/libdeflate.h new file mode 100644 index 0000000..0a274f0 --- /dev/null +++ b/extern/src/libdeflate.h @@ -0,0 +1,411 @@ +/* + * libdeflate.h - public header for libdeflate + */ + +#ifndef LIBDEFLATE_H +#define LIBDEFLATE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBDEFLATE_VERSION_MAJOR 1 +#define LIBDEFLATE_VERSION_MINOR 19 +#define LIBDEFLATE_VERSION_STRING "1.19" + +/* + * Users of libdeflate.dll on Windows can define LIBDEFLATE_DLL to cause + * __declspec(dllimport) to be used. This should be done when it's easy to do. + * Otherwise it's fine to skip it, since it is a very minor performance + * optimization that is irrelevant for most use cases of libdeflate. + */ +#ifndef LIBDEFLATEAPI +# if defined(LIBDEFLATE_DLL) && (defined(_WIN32) || defined(__CYGWIN__)) +# define LIBDEFLATEAPI __declspec(dllimport) +# else +# define LIBDEFLATEAPI +# endif +#endif + +/* ========================================================================== */ +/* Compression */ +/* ========================================================================== */ + +struct libdeflate_compressor; +struct libdeflate_options; + +/* + * libdeflate_alloc_compressor() allocates a new compressor that supports + * DEFLATE, zlib, and gzip compression. 'compression_level' is the compression + * level on a zlib-like scale but with a higher maximum value (1 = fastest, 6 = + * medium/default, 9 = slow, 12 = slowest). Level 0 is also supported and means + * "no compression", specifically "create a valid stream, but only emit + * uncompressed blocks" (this will expand the data slightly). + * + * The return value is a pointer to the new compressor, or NULL if out of memory + * or if the compression level is invalid (i.e. outside the range [0, 12]). + * + * Note: for compression, the sliding window size is defined at compilation time + * to 32768, the largest size permissible in the DEFLATE format. It cannot be + * changed at runtime. + * + * A single compressor is not safe to use by multiple threads concurrently. + * However, different threads may use different compressors concurrently. + */ +LIBDEFLATEAPI struct libdeflate_compressor * +libdeflate_alloc_compressor(int compression_level); + +/* + * Like libdeflate_alloc_compressor(), but adds the 'options' argument. + */ +LIBDEFLATEAPI struct libdeflate_compressor * +libdeflate_alloc_compressor_ex(int compression_level, + const struct libdeflate_options *options); + +/* + * libdeflate_deflate_compress() performs raw DEFLATE compression on a buffer of + * data. It attempts to compress 'in_nbytes' bytes of data located at 'in' and + * write the result to 'out', which has space for 'out_nbytes_avail' bytes. The + * return value is the compressed size in bytes, or 0 if the data could not be + * compressed to 'out_nbytes_avail' bytes or fewer. + * + * If compression is successful, then the output data is guaranteed to be a + * valid DEFLATE stream that decompresses to the input data. No other + * guarantees are made about the output data. Notably, different versions of + * libdeflate can produce different compressed data for the same uncompressed + * data, even at the same compression level. Do ***NOT*** do things like + * writing tests that compare compressed data to a golden output, as this can + * break when libdeflate is updated. (This property isn't specific to + * libdeflate; the same is true for zlib and other compression libraries too.) + */ +LIBDEFLATEAPI size_t +libdeflate_deflate_compress(struct libdeflate_compressor *compressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail); + +/* + * libdeflate_deflate_compress_bound() returns a worst-case upper bound on the + * number of bytes of compressed data that may be produced by compressing any + * buffer of length less than or equal to 'in_nbytes' using + * libdeflate_deflate_compress() with the specified compressor. This bound will + * necessarily be a number greater than or equal to 'in_nbytes'. It may be an + * overestimate of the true upper bound. The return value is guaranteed to be + * the same for all invocations with the same compressor and same 'in_nbytes'. + * + * As a special case, 'compressor' may be NULL. This causes the bound to be + * taken across *any* libdeflate_compressor that could ever be allocated with + * this build of the library, with any options. + * + * Note that this function is not necessary in many applications. With + * block-based compression, it is usually preferable to separately store the + * uncompressed size of each block and to store any blocks that did not compress + * to less than their original size uncompressed. In that scenario, there is no + * need to know the worst-case compressed size, since the maximum number of + * bytes of compressed data that may be used would always be one less than the + * input length. You can just pass a buffer of that size to + * libdeflate_deflate_compress() and store the data uncompressed if + * libdeflate_deflate_compress() returns 0, indicating that the compressed data + * did not fit into the provided output buffer. + */ +LIBDEFLATEAPI size_t +libdeflate_deflate_compress_bound(struct libdeflate_compressor *compressor, + size_t in_nbytes); + +/* + * Like libdeflate_deflate_compress(), but uses the zlib wrapper format instead + * of raw DEFLATE. + */ +LIBDEFLATEAPI size_t +libdeflate_zlib_compress(struct libdeflate_compressor *compressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail); + +/* + * Like libdeflate_deflate_compress_bound(), but assumes the data will be + * compressed with libdeflate_zlib_compress() rather than with + * libdeflate_deflate_compress(). + */ +LIBDEFLATEAPI size_t +libdeflate_zlib_compress_bound(struct libdeflate_compressor *compressor, + size_t in_nbytes); + +/* + * Like libdeflate_deflate_compress(), but uses the gzip wrapper format instead + * of raw DEFLATE. + */ +LIBDEFLATEAPI size_t +libdeflate_gzip_compress(struct libdeflate_compressor *compressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail); + +/* + * Like libdeflate_deflate_compress_bound(), but assumes the data will be + * compressed with libdeflate_gzip_compress() rather than with + * libdeflate_deflate_compress(). + */ +LIBDEFLATEAPI size_t +libdeflate_gzip_compress_bound(struct libdeflate_compressor *compressor, + size_t in_nbytes); + +/* + * libdeflate_free_compressor() frees a compressor that was allocated with + * libdeflate_alloc_compressor(). If a NULL pointer is passed in, no action is + * taken. + */ +LIBDEFLATEAPI void +libdeflate_free_compressor(struct libdeflate_compressor *compressor); + +/* ========================================================================== */ +/* Decompression */ +/* ========================================================================== */ + +struct libdeflate_decompressor; +struct libdeflate_options; + +/* + * libdeflate_alloc_decompressor() allocates a new decompressor that can be used + * for DEFLATE, zlib, and gzip decompression. The return value is a pointer to + * the new decompressor, or NULL if out of memory. + * + * This function takes no parameters, and the returned decompressor is valid for + * decompressing data that was compressed at any compression level and with any + * sliding window size. + * + * A single decompressor is not safe to use by multiple threads concurrently. + * However, different threads may use different decompressors concurrently. + */ +LIBDEFLATEAPI struct libdeflate_decompressor * +libdeflate_alloc_decompressor(void); + +/* + * Like libdeflate_alloc_decompressor(), but adds the 'options' argument. + */ +LIBDEFLATEAPI struct libdeflate_decompressor * +libdeflate_alloc_decompressor_ex(const struct libdeflate_options *options); + +/* + * Result of a call to libdeflate_deflate_decompress(), + * libdeflate_zlib_decompress(), or libdeflate_gzip_decompress(). + */ +enum libdeflate_result { + /* Decompression was successful. */ + LIBDEFLATE_SUCCESS = 0, + + /* Decompression failed because the compressed data was invalid, + * corrupt, or otherwise unsupported. */ + LIBDEFLATE_BAD_DATA = 1, + + /* A NULL 'actual_out_nbytes_ret' was provided, but the data would have + * decompressed to fewer than 'out_nbytes_avail' bytes. */ + LIBDEFLATE_SHORT_OUTPUT = 2, + + /* The data would have decompressed to more than 'out_nbytes_avail' + * bytes. */ + LIBDEFLATE_INSUFFICIENT_SPACE = 3, +}; + +/* + * libdeflate_deflate_decompress() decompresses a DEFLATE stream from the buffer + * 'in' with compressed size up to 'in_nbytes' bytes. The uncompressed data is + * written to 'out', a buffer with size 'out_nbytes_avail' bytes. If + * decompression succeeds, then 0 (LIBDEFLATE_SUCCESS) is returned. Otherwise, + * a nonzero result code such as LIBDEFLATE_BAD_DATA is returned, and the + * contents of the output buffer are undefined. + * + * Decompression stops at the end of the DEFLATE stream (as indicated by the + * BFINAL flag), even if it is actually shorter than 'in_nbytes' bytes. + * + * libdeflate_deflate_decompress() can be used in cases where the actual + * uncompressed size is known (recommended) or unknown (not recommended): + * + * - If the actual uncompressed size is known, then pass the actual + * uncompressed size as 'out_nbytes_avail' and pass NULL for + * 'actual_out_nbytes_ret'. This makes libdeflate_deflate_decompress() fail + * with LIBDEFLATE_SHORT_OUTPUT if the data decompressed to fewer than the + * specified number of bytes. + * + * - If the actual uncompressed size is unknown, then provide a non-NULL + * 'actual_out_nbytes_ret' and provide a buffer with some size + * 'out_nbytes_avail' that you think is large enough to hold all the + * uncompressed data. In this case, if the data decompresses to less than + * or equal to 'out_nbytes_avail' bytes, then + * libdeflate_deflate_decompress() will write the actual uncompressed size + * to *actual_out_nbytes_ret and return 0 (LIBDEFLATE_SUCCESS). Otherwise, + * it will return LIBDEFLATE_INSUFFICIENT_SPACE if the provided buffer was + * not large enough but no other problems were encountered, or another + * nonzero result code if decompression failed for another reason. + */ +LIBDEFLATEAPI enum libdeflate_result +libdeflate_deflate_decompress(struct libdeflate_decompressor *decompressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail, + size_t *actual_out_nbytes_ret); + +/* + * Like libdeflate_deflate_decompress(), but adds the 'actual_in_nbytes_ret' + * argument. If decompression succeeds and 'actual_in_nbytes_ret' is not NULL, + * then the actual compressed size of the DEFLATE stream (aligned to the next + * byte boundary) is written to *actual_in_nbytes_ret. + */ +LIBDEFLATEAPI enum libdeflate_result +libdeflate_deflate_decompress_ex(struct libdeflate_decompressor *decompressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail, + size_t *actual_in_nbytes_ret, + size_t *actual_out_nbytes_ret); + +/* + * Like libdeflate_deflate_decompress(), but assumes the zlib wrapper format + * instead of raw DEFLATE. + * + * Decompression will stop at the end of the zlib stream, even if it is shorter + * than 'in_nbytes'. If you need to know exactly where the zlib stream ended, + * use libdeflate_zlib_decompress_ex(). + */ +LIBDEFLATEAPI enum libdeflate_result +libdeflate_zlib_decompress(struct libdeflate_decompressor *decompressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail, + size_t *actual_out_nbytes_ret); + +/* + * Like libdeflate_zlib_decompress(), but adds the 'actual_in_nbytes_ret' + * argument. If 'actual_in_nbytes_ret' is not NULL and the decompression + * succeeds (indicating that the first zlib-compressed stream in the input + * buffer was decompressed), then the actual number of input bytes consumed is + * written to *actual_in_nbytes_ret. + */ +LIBDEFLATEAPI enum libdeflate_result +libdeflate_zlib_decompress_ex(struct libdeflate_decompressor *decompressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail, + size_t *actual_in_nbytes_ret, + size_t *actual_out_nbytes_ret); + +/* + * Like libdeflate_deflate_decompress(), but assumes the gzip wrapper format + * instead of raw DEFLATE. + * + * If multiple gzip-compressed members are concatenated, then only the first + * will be decompressed. Use libdeflate_gzip_decompress_ex() if you need + * multi-member support. + */ +LIBDEFLATEAPI enum libdeflate_result +libdeflate_gzip_decompress(struct libdeflate_decompressor *decompressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail, + size_t *actual_out_nbytes_ret); + +/* + * Like libdeflate_gzip_decompress(), but adds the 'actual_in_nbytes_ret' + * argument. If 'actual_in_nbytes_ret' is not NULL and the decompression + * succeeds (indicating that the first gzip-compressed member in the input + * buffer was decompressed), then the actual number of input bytes consumed is + * written to *actual_in_nbytes_ret. + */ +LIBDEFLATEAPI enum libdeflate_result +libdeflate_gzip_decompress_ex(struct libdeflate_decompressor *decompressor, + const void *in, size_t in_nbytes, + void *out, size_t out_nbytes_avail, + size_t *actual_in_nbytes_ret, + size_t *actual_out_nbytes_ret); + +/* + * libdeflate_free_decompressor() frees a decompressor that was allocated with + * libdeflate_alloc_decompressor(). If a NULL pointer is passed in, no action + * is taken. + */ +LIBDEFLATEAPI void +libdeflate_free_decompressor(struct libdeflate_decompressor *decompressor); + +/* ========================================================================== */ +/* Checksums */ +/* ========================================================================== */ + +/* + * libdeflate_adler32() updates a running Adler-32 checksum with 'len' bytes of + * data and returns the updated checksum. When starting a new checksum, the + * required initial value for 'adler' is 1. This value is also returned when + * 'buffer' is specified as NULL. + */ +LIBDEFLATEAPI uint32_t +libdeflate_adler32(uint32_t adler, const void *buffer, size_t len); + + +/* + * libdeflate_crc32() updates a running CRC-32 checksum with 'len' bytes of data + * and returns the updated checksum. When starting a new checksum, the required + * initial value for 'crc' is 0. This value is also returned when 'buffer' is + * specified as NULL. + */ +LIBDEFLATEAPI uint32_t +libdeflate_crc32(uint32_t crc, const void *buffer, size_t len); + +/* ========================================================================== */ +/* Custom memory allocator */ +/* ========================================================================== */ + +/* + * Install a custom memory allocator which libdeflate will use for all memory + * allocations by default. 'malloc_func' is a function that must behave like + * malloc(), and 'free_func' is a function that must behave like free(). + * + * The per-(de)compressor custom memory allocator that can be specified in + * 'struct libdeflate_options' takes priority over this. + * + * This doesn't affect the free() function that will be used to free + * (de)compressors that were already in existence when this is called. + */ +LIBDEFLATEAPI void +libdeflate_set_memory_allocator(void *(*malloc_func)(size_t), + void (*free_func)(void *)); + +/* + * Advanced options. This is the options structure that + * libdeflate_alloc_compressor_ex() and libdeflate_alloc_decompressor_ex() + * require. Most users won't need this and should just use the non-"_ex" + * functions instead. If you do need this, it should be initialized like this: + * + * struct libdeflate_options options; + * + * memset(&options, 0, sizeof(options)); + * options.sizeof_options = sizeof(options); + * // Then set the fields that you need to override the defaults for. + */ +struct libdeflate_options { + + /* + * This field must be set to the struct size. This field exists for + * extensibility, so that fields can be appended to this struct in + * future versions of libdeflate while still supporting old binaries. + */ + size_t sizeof_options; + + /* + * An optional custom memory allocator to use for this (de)compressor. + * 'malloc_func' must be a function that behaves like malloc(), and + * 'free_func' must be a function that behaves like free(). + * + * This is useful in cases where a process might have multiple users of + * libdeflate who want to use different memory allocators. For example, + * a library might want to use libdeflate with a custom memory allocator + * without interfering with user code that might use libdeflate too. + * + * This takes priority over the "global" memory allocator (which by + * default is malloc() and free(), but can be changed by + * libdeflate_set_memory_allocator()). Moreover, libdeflate will never + * call the "global" memory allocator if a per-(de)compressor custom + * allocator is always given. + */ + void *(*malloc_func)(size_t); + void (*free_func)(void *); +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LIBDEFLATE_H */ diff --git a/src/DivaGL/DivaGL.rc b/src/DivaGL/DivaGL.rc new file mode 100644 index 0000000..caea5e7 --- /dev/null +++ b/src/DivaGL/DivaGL.rc @@ -0,0 +1,46 @@ +#define IDR_VERSION2 101 + +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif + +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,2,0 + PRODUCTVERSION 0,2,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000904b0" + BEGIN + VALUE "FileDescription", "DivaGL plugin for PDAFT 7.10" + VALUE "FileVersion", "0.2.0.0" + VALUE "InternalName", "DivaGL" + VALUE "LegalCopyright", "korenkonder (C) 2020-2023" + VALUE "OriginalFilename", "DivaGL.dll" + VALUE "ProductName", "DivaGL" + VALUE "ProductVersion", "0.2.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x9, 1200 + END +END diff --git a/src/DivaGL/DivaGL.vcxproj b/src/DivaGL/DivaGL.vcxproj new file mode 100644 index 0000000..3d2dce5 --- /dev/null +++ b/src/DivaGL/DivaGL.vcxproj @@ -0,0 +1,339 @@ + + + + + DebugDLL + x64 + + + Debug + x64 + + + ReleaseDLL + x64 + + + Release + x64 + + + + 16.0 + {4D949362-9095-4113-9423-7E0492618F16} + Win32Proj + 10.0 + + + + DynamicLibrary + false + v142 + Unicode + + + DynamicLibrary + false + v142 + Unicode + + + DynamicLibrary + false + v142 + Unicode + + + DynamicLibrary + false + v142 + Unicode + + + + + + + + + + + + + + + + + false + DivaGL + $(SolutionDir)bin\ + $(SolutionDir)obj\debug\DivaGL\ + .dva + + + false + dinput8 + $(SolutionDir)bin\ + $(SolutionDir)obj\debug\DivaGL\ + .dll + + + false + DivaGL + $(SolutionDir)bin\ + $(SolutionDir)obj\release\DivaGL\ + .dva + + + false + dinput8 + $(SolutionDir)bin\ + $(SolutionDir)obj\release\DivaGL\ + .dll + + + + NotUsing + Level3 + Disabled + WIN32;DEBUG;%(PreprocessorDefinitions) + $(SolutionDir)extern\src + true + ProgramDatabase + false + OnlyExplicitInline + FastCall + true + CompileAsCpp + $(IntDir)/%(RelativeDir) + MultiThreaded + 26812 + false + + + MachineX64 + DebugFull + Windows + $(SolutionDir)extern\lib;$(SolutionDir)lib\debugopt\ + opengl32.lib;detours.lib;syelog.lib;libdeflatestatic.lib;KKdLib.lib;%(AdditionalDependencies) + /ignore:4098 /ignore:4099 /ignore:4286 %(AdditionalOptions) + false + + + copy /Y "$(SolutionDir)bin\$(TargetName).dva" "N:\DUMP\plugins\$(TargetName).dva" +copy /Y "$(SolutionDir)bin\$(TargetName).pdb" "N:\DUMP\plugins\$(TargetName).pdb" +del "$(SolutionDir)bin\$(TargetName).exp" +del "$(SolutionDir)bin\$(TargetName).lib" + + + + + NotUsing + Level3 + Disabled + WIN32;DINPUT8_DLL;DEBUG;%(PreprocessorDefinitions) + $(SolutionDir)extern\src + true + ProgramDatabase + false + OnlyExplicitInline + FastCall + true + CompileAsCpp + $(IntDir)/%(RelativeDir) + MultiThreaded + 26812 + false + + + MachineX64 + DebugFull + Windows + $(SolutionDir)extern\lib;$(SolutionDir)lib\debugopt\ + opengl32.lib;detours.lib;syelog.lib;libdeflatestatic.lib;KKdLib.lib;%(AdditionalDependencies) + /ignore:4098 /ignore:4099 /ignore:4286 %(AdditionalOptions) + false + + + copy /Y "$(SolutionDir)bin\$(TargetName).dll" "N:\DUMP\$(TargetName).dll" +copy /Y "$(SolutionDir)bin\$(TargetName).pdb" "N:\DUMP\$(TargetName).pdb" +del "$(SolutionDir)bin\$(TargetName).exp" +del "$(SolutionDir)bin\$(TargetName).lib" + + + + + NotUsing + Level3 + MaxSpeed + WIN32;%(PreprocessorDefinitions) + $(SolutionDir)extern\src + true + false + ProgramDatabase + OnlyExplicitInline + true + FastCall + CompileAsCpp + + + $(IntDir)/%(RelativeDir) + Size + + + false + MultiThreaded + 26812 + + + MachineX64 + true + Windows + $(SolutionDir)extern\lib;$(SolutionDir)lib\release\ + opengl32.lib;detours.lib;syelog.lib;libdeflatestatic.lib;KKdLib.lib;%(AdditionalDependencies) + true + /ignore:4098 /ignore:4099 /ignore:4286 %(AdditionalOptions) + true + false + + + copy /Y "$(SolutionDir)bin\$(TargetName).dva" "N:\DUMP\plugins\$(TargetName).dva" +copy /Y "$(SolutionDir)bin\$(TargetName).pdb" "N:\DUMP\plugins\$(TargetName).pdb" +del "$(SolutionDir)bin\$(TargetName).exp" +del "$(SolutionDir)bin\$(TargetName).lib" + + + + + NotUsing + Level3 + MaxSpeed + WIN32;DINPUT8_DLL;%(PreprocessorDefinitions) + $(SolutionDir)extern\src + true + false + ProgramDatabase + OnlyExplicitInline + true + FastCall + CompileAsCpp + + + $(IntDir)/%(RelativeDir) + Size + + + false + MultiThreaded + 26812 + + + MachineX64 + true + Windows + $(SolutionDir)extern\lib;$(SolutionDir)lib\release\ + opengl32.lib;detours.lib;syelog.lib;libdeflatestatic.lib;KKdLib.lib;%(AdditionalDependencies) + true + /ignore:4098 /ignore:4099 /ignore:4286 %(AdditionalOptions) + true + false + + + copy /Y "$(SolutionDir)bin\$(TargetName).dll" "N:\DUMP\$(TargetName).dll" +copy /Y "$(SolutionDir)bin\$(TargetName).pdb" "N:\DUMP\$(TargetName).pdb" +del "$(SolutionDir)bin\$(TargetName).exp" +del "$(SolutionDir)bin\$(TargetName).lib" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {4c9636b9-e5b6-41e5-9afc-5b33cc9633de} + + + + \ No newline at end of file diff --git a/src/DivaGL/DivaGL.vcxproj.user b/src/DivaGL/DivaGL.vcxproj.user new file mode 100644 index 0000000..c23e4d1 --- /dev/null +++ b/src/DivaGL/DivaGL.vcxproj.user @@ -0,0 +1,30 @@ + + + + N:\DUMP\diva.exe + N:\DUMP + WindowsLocalDebugger + --launch -w + + + N:\DUMP\diva.exe + N:\DUMP + WindowsLocalDebugger + --launch -w + + + N:\DUMP\diva.exe + --launch -w + N:\DUMP + WindowsLocalDebugger + + + N:\DUMP\diva.exe + --launch -w + N:\DUMP + WindowsLocalDebugger + + + true + + \ No newline at end of file diff --git a/src/DivaGL/Glitter/glitter.cpp b/src/DivaGL/Glitter/glitter.cpp new file mode 100644 index 0000000..8914149 --- /dev/null +++ b/src/DivaGL/Glitter/glitter.cpp @@ -0,0 +1,146 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "glitter.hpp" +#include "../inject.hpp" +#include "../gl_state.hpp" +#include "../wrap.hpp" + +namespace Glitter { + void axis_angle_from_vectors(vec3* axis, float_t* angle, const vec3* vec1, const vec3* vec2) { + *axis = vec3::cross(*vec1, *vec2); + *angle = vec3::length(*axis); + if (*angle >= 0.000001f) + *angle = asinf(min_def(*angle, 1.0f)); + else { + *angle = 0.0f; + axis->x = vec1->z; + axis->y = 0.0f; + axis->z = vec1->x; + if (vec3::length(*axis) < 0.000001f) { + axis->x = -vec1->y; + axis->y = vec1->x; + axis->z = 0.0f; + } + } + + if (vec3::dot(*vec1, *vec2) < 0.0f) + *angle = (float_t)M_PI - *angle; + } + + void CreateBuffer(int32_t max_count, bool is_quad, GLuint& vao, GLuint& vbo, GLuint& ebo) { + glGenVertexArrays(1, &vao); + gl_state_bind_vertex_array(vao, true); + + glGenBuffers(1, &vbo); + gl_state_bind_array_buffer(vbo, true); + + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(sizeof(Buffer) * max_count), 0, GL_DYNAMIC_DRAW); + + if (is_quad) { + size_t count = (size_t)max_count / 4 * 5; + int32_t* ebo_data = (int32_t*)_operator_new(sizeof(int32_t) * (count - 1)); + for (size_t i = 0, j = 0, k = count / 5 - 1; i < count; i += 5, j += 4, k--) { + ebo_data[i + 0] = (uint32_t)(j + 0); + ebo_data[i + 1] = (uint32_t)(j + 1); + ebo_data[i + 2] = (uint32_t)(j + 3); + ebo_data[i + 3] = (uint32_t)(j + 2); + if (k) + ebo_data[i + 4] = 0xFFFFFFFF; + } + + glGenBuffers(1, &ebo); + gl_state_bind_element_array_buffer(ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int32_t) * (count - 1), ebo_data, GL_STATIC_DRAW); + _operator_delete(ebo_data); + } + else + ebo = 0; + + static const GLsizei buffer_size = sizeof(Buffer); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(Buffer, position)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(Buffer, uv)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(Buffer, color)); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + if (is_quad) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + void DeleteBuffer(GLuint& vao, GLuint& vbo, GLuint& ebo) { + if (ebo) { + glDeleteBuffers(1, &ebo); + ebo = 0; + } + + if (vbo) { + glDeleteBuffers(1, &vbo); + vbo = 0; + } + + if (vao) { + glDeleteVertexArrays(1, &vao); + vao = 0; + } + } + + // Particle + const char* _000000014039BC78_patch_data + = "\x48\x89\xE9\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x80\xFF\xD0\xEB\x3D"; + const char* _00000001403AEA7E_patch_data + = "\x48\x89\xD9\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x80\xFF\xD0\xEB\x0B"; + + // RenderGroup + const char* _00000001403A5CA7_patch_data + = "\x48\x8B\xCE\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x80\xFF\xD0\xE9\x95\x00\x00\x00"; + const char* _00000001403A8552_patch_data + = "\x48\x89\xD9\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x80\xFF\xD0\xEB\x07"; + + void Patch() { + uint8_t buf[0x100]; + + // Particle + inject_uint32_t((void*)0x000000014039A396, + 0x1B0 + sizeof(GLuint) * 2 + sizeof(DrawListData*)); + + memcpy(buf, _000000014039BC78_patch_data, 0x11); + *(uint64_t*)&buf[0x05] = (uint64_t)Particle::CreateBuffer; + inject_data((void*)0x000000014039BC78, buf, 0x11); + + memcpy(buf, _00000001403AEA7E_patch_data, 0x11); + *(uint64_t*)&buf[0x05] = (uint64_t)Particle::DeleteBuffer; + inject_data((void*)0x00000001403AEA7E, buf, 0x11); + + // RenderGroup + inject_uint32_t((void*)0x00000001403A9740, sizeof(RenderGroup)); + + memcpy(buf, _00000001403A5CA7_patch_data, 0x14); + *(uint64_t*)&buf[0x05] = (uint64_t)RenderGroup::CreateBuffer; + inject_data((void*)0x00000001403A5CA7, buf, 0x14); + + memcpy(buf, _00000001403A8552_patch_data, 0x11); + *(uint64_t*)&buf[0x05] = (uint64_t)RenderGroup::DeleteBuffer; + inject_data((void*)0x00000001403A8552, buf, 0x11); + + // RenderScene + buf[0x00] = 0x48; + buf[0x01] = 0xB8; + *(uint64_t*)&buf[0x02] = (uint64_t)RenderScene::Disp; + buf[0x0A] = 0xFF; + buf[0x0B] = 0xE0; + inject_data((void*)0x00000001403AA140, buf, 0x0C); + + // GltParticleManager + inject_uint64_t((void*)(0x00000001409EB880 + 0x20), (uint64_t)GltParticleManager::Disp); + } +} diff --git a/src/DivaGL/Glitter/glitter.hpp b/src/DivaGL/Glitter/glitter.hpp new file mode 100644 index 0000000..f1616be --- /dev/null +++ b/src/DivaGL/Glitter/glitter.hpp @@ -0,0 +1,322 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/mat.hpp" +#include "../../KKdLib/vec.hpp" +#include "../gl.hpp" +#include "../types.hpp" +#include "../texture.hpp" + +namespace Glitter { + enum Direction { + DIRECTION_BILLBOARD = 0, + DIRECTION_EMITTER_DIRECTION = 1, + DIRECTION_PREV_POSITION = 2, + DIRECTION_EMIT_POSITION = 3, + DIRECTION_Y_AXIS = 4, + DIRECTION_X_AXIS = 5, + DIRECTION_Z_AXIS = 6, + DIRECTION_BILLBOARD_Y_AXIS = 7, + DIRECTION_PREV_POSITION_DUP = 8, + DIRECTION_EMITTER_ROTATION = 9, + DIRECTION_EFFECT_ROTATION = 10, + DIRECTION_PARTICLE_ROTATION = 11, + }; + + enum DispType { + DISP_OPAQUE = 0, + DISP_NORMAL = 1, + DISP_ALPHA = 2, + }; + + enum FogType { + FOG_NONE = 0, + FOG_DEPTH = 1, + FOG_HEIGHT = 2, + }; + + enum ParticleBlend { + PARTICLE_BLEND_ZERO = 0, + PARTICLE_BLEND_TYPICAL = 1, + PARTICLE_BLEND_ADD = 2, + PARTICLE_BLEND_SUBTRACT = 3, + PARTICLE_BLEND_MULTIPLY = 4, + PARTICLE_BLEND_PUNCH_THROUGH = 5, + }; + + enum ParticleFlag { + PARTICLE_NONE = 0x00000, + PARTICLE_LOOP = 0x00001, + PARTICLE_EMITTER_LOCAL = 0x00004, + PARTICLE_SCALE_Y_BY_X = 0x00010, + PARTICLE_REBOUND_PLANE = 0x00020, + PARTICLE_ROTATE_BY_EMITTER = 0x00040, + PARTICLE_SCALE = 0x00080, + PARTICLE_TEXTURE_MASK = 0x00100, + PARTICLE_DEPTH_TEST = 0x00200, + PARTICLE_ROTATE_LOCUS = 0x00800, + PARTICLE_LOCAL = 0x10000, + PARTICLE_EMISSION = 0x20000, + }; + + enum ParticleManagerFlag { + PARTICLE_MANAGER_PAUSE = 0x01, + PARTICLE_MANAGER_NOT_DISP = 0x02, + PARTICLE_MANAGER_RESET_SCENE_COUNTER = 0x04, + PARTICLE_MANAGER_READ_FILES = 0x08, + }; + + enum ParticleType { + PARTICLE_QUAD = 0, + PARTICLE_LINE = 1, + PARTICLE_LOCUS = 2, + }; + + enum Pivot { + PIVOT_TOP_LEFT = 0, + PIVOT_TOP_CENTER = 1, + PIVOT_TOP_RIGHT = 2, + PIVOT_MIDDLE_LEFT = 3, + PIVOT_MIDDLE_CENTER = 4, + PIVOT_MIDDLE_RIGHT = 5, + PIVOT_BOTTOM_LEFT = 6, + PIVOT_BOTTOM_CENTER = 7, + PIVOT_BOTTOM_RIGHT = 8, + }; + + enum SceneFlag { + SCENE_NONE = 0x00, + SCENE_FLAG_1 = 0x01, + SCENE_NOT_DISP = 0x02, + SCENE_FLAG_3 = 0x04, + }; + + struct Animation; + struct Buffer; + struct Camera; + struct Curve; + struct Effect; + struct Emitter; + struct EmitterInst; + struct ItemBase; + struct Node; + struct Particle; + struct ParticleInst; + struct Random; + struct RenderElement; + struct RenderGroup; + struct RenderScene; + + struct BatchShaderData; + struct Scene; + struct GltParticleManager; + +#define GPM Glitter::GltParticleManager* glt_particle_manager +#define GPM_VAL (glt_particle_manager) + + struct Buffer { + vec3 position; + vec2 uv[2]; + vec4 color; + }; + + struct LocusHistory { + struct Data { + vec3 translation; + vec4 color; + float_t scale; + }; + + struct Sub { + prj::vector vec; + int32_t count; + }; + + void* __vftable; + Sub sub; + }; + + struct Particle { + static void CreateBuffer(size_t data); + static void DeleteBuffer(size_t data); + }; + + struct RenderElement { + bool alive; + uint8_t uv_counter; + int32_t random; + float_t frame; + float_t life_time; + float_t rebound_time; + float_t frame_step_uv; + float_t speed; + float_t deceleration; + vec2 uv; + vec4 color; + vec3 base_translation; + vec3 translation; + vec3 translation_prev; + vec3 direction; + vec3 acceleration; + vec2 scale_particle; + vec3 scale; + vec3 rotation; + vec3 rotation_add; + float_t rot_z_cos; + float_t rot_z_sin; + float_t scale_all; + vec2 uv_scroll; + mat4 mat; + LocusHistory* locus_history; + }; + + struct EffectGroup { + void* __vftable; + std::vector effects; // Glitter::Effect + int32_t load_count; + texture** textures; + void* scene; // Glitter::Scene + float_t emission; + bool not_loaded; + bool scene_init; + bool buffer_init; + }; + + typedef prj::vector> DrawListData; + + struct RenderGroup { + void* __vftable; + ParticleFlag flags; + ParticleType type; + Direction draw_type; + ParticleBlend blend_mode; + ParticleBlend mask_blend_mode; + int32_t dword1C; + Pivot pivot; + int32_t split_u; + int32_t split_v; + vec2 split_uv; + float_t z_offset; + int32_t count; + int32_t ctrl; + int32_t texture; + int32_t mask_texture; + prj::string name; + float_t frame; + mat4 mat; + mat4 mat_rot; + bool has_mask; + int32_t dwordF0; + int32_t dwordF4; + RenderElement* elements; + Buffer* buffer; + int32_t max_count; + int32_t dword10C; + void* particle_inst; // Glitter::ParticleInst + DispType disp_type; + FogType fog_type; + GLuint vbo; + float_t emission; + bool use_own_buffer; + GLuint vao; + GLuint ebo; + size_t disp; + mat4 mat_draw; + DrawListData* draw_list; + + static mat4 RotateToEmitPosition(RenderGroup* rend_group, + RenderElement* rend_elem, vec3* vec); + static mat4 RotateToPrevPosition(RenderGroup* rend_group, + RenderElement* rend_elem, vec3* vec); + + static void CreateBuffer(RenderGroup* rend_group); + static void DeleteBuffer(RenderGroup* rend_group); + }; + + struct RenderScene { + prj::vector render_groups; + int32_t disp_quad; + int32_t disp_locus; + int32_t disp_line; + int32_t ctrl_quad; + int32_t ctrl_locus; + int32_t ctrl_line; + + static void CalcDisp(RenderScene* rend_sc); + static void CalcDisp(RenderScene* rend_sc, RenderGroup* rend_group); + static void CalcDispLine(RenderGroup* rend_group); + static void CalcDispLocus(RenderGroup* rend_group); + static void CalcDispQuad(RenderGroup* rend_group); + static void CalcDispQuadDirectionRotation( + RenderGroup* rend_group, mat4* model_mat, mat4* dir_mat); + static void CalcDispQuadNormal( + RenderGroup* rend_group, mat4* model_mat, mat4* dir_mat); + static void Disp(RenderScene* rend_sc, RenderGroup* rend_group); + + static void CalcDispLocusSetPivot(Pivot pivot, + float_t w, float_t& v00, float_t& v01); + static void CalcDispQuadSetPivot(Pivot pivot, + float_t w, float_t h, float_t& v00, float_t& v01, float_t& v10, float_t& v11); + }; + + struct SceneEffect { + void* ptr; // Glitter::EffectInst + bool draw; + }; + + struct Scene { + void* __vftable; + prj::vector effects; + uint32_t load_counter; + uint64_t hash; + SceneFlag flags; + float_t emission; + EffectGroup* effect_group; + RenderScene render_scene; + + static void CalcDisp(Scene* sc); + }; + + struct GltParticleManager { + void* __vftable; + uint8_t app_task_data[0x60]; + prj::map effect_groups; + void* field_78; + uint64_t field_80; + prj::vector scenes; + prj::vector file_readers; + void* sys_frame_rate; + ParticleManagerFlag flags; + int32_t scene_load_counter; + int32_t available_buffers_init; + int32_t available_buffers; + float_t field_D0; + float_t field_D4; + float_t emission; + float_t delta_frame; + prj::map resources; + uint32_t texture_counter; + int32_t field_F4; + int32_t field_F8; + int32_t random; + int32_t counter; + int32_t field_104; + + static void Disp(GPM); + }; + + extern GPM; + + extern void axis_angle_from_vectors(vec3* axis, float_t* angle, const vec3* vec0, const vec3* vec1); + + extern void CreateBuffer(int32_t max_count, bool is_quad, GLuint& vao, GLuint& vbo, GLuint& ebo); + extern void DeleteBuffer(GLuint& vao, GLuint& vbo, GLuint& ebo); + + extern void Patch(); + + extern void (FASTCALL* GltParticleManager__DispScenes)(GPM, DispType disp_type); +} diff --git a/src/DivaGL/Glitter/particle.cpp b/src/DivaGL/Glitter/particle.cpp new file mode 100644 index 0000000..7f93421 --- /dev/null +++ b/src/DivaGL/Glitter/particle.cpp @@ -0,0 +1,33 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "glitter.hpp" + +namespace Glitter { + void Particle::CreateBuffer(size_t data) { + ParticleType type = (ParticleType) * (int32_t*)(data + 0x40 + 0x00 + 0x08); + GLuint& vbo = ((GLuint*)(data + 0x40 + 0x160))[0]; + int32_t max_count = *(int32_t*)(data + 0x40 + 0x164); + GLuint& vao = ((GLuint*)(data + 0x40 + 0x170))[0]; + GLuint& ebo = ((GLuint*)(data + 0x40 + 0x170))[1]; + Glitter::CreateBuffer(max_count, type == PARTICLE_QUAD, vao, vbo, ebo); + + DrawListData*& draw_list = *(DrawListData**)(data + 0x40 + 0x170 + sizeof(GLuint) * 2); + draw_list = new DrawListData; + } + + void Particle::DeleteBuffer(size_t data) { + DrawListData*& draw_list = *(DrawListData**)(data + 0x40 + 0x170 + sizeof(GLuint) * 2); + if (draw_list) { + delete draw_list; + draw_list = 0; + } + + GLuint& vbo = ((GLuint*)(data + 0x40 + 0x160))[0]; + GLuint& vao = ((GLuint*)(data + 0x40 + 0x170))[0]; + GLuint& ebo = ((GLuint*)(data + 0x40 + 0x170))[1]; + Glitter::DeleteBuffer(vao, vbo, ebo); + } +} diff --git a/src/DivaGL/Glitter/particle_manager.cpp b/src/DivaGL/Glitter/particle_manager.cpp new file mode 100644 index 0000000..994d730 --- /dev/null +++ b/src/DivaGL/Glitter/particle_manager.cpp @@ -0,0 +1,23 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "glitter.hpp" +#include "../gl_state.hpp" + +namespace Glitter { + GPM = (GltParticleManager*)0x000000141199BB0; + + void GltParticleManager::Disp(GPM) { + if (glt_particle_manager->flags & PARTICLE_MANAGER_NOT_DISP) + return; + + for (Scene*& i : glt_particle_manager->scenes) + if (i) + Scene::CalcDisp(i); + } + + void (FASTCALL* GltParticleManager__DispScenes)(GPM, DispType disp_type) + = (void (FASTCALL*)(GPM, DispType disp_type))0x00000001403A1020; +} diff --git a/src/DivaGL/Glitter/render_group.cpp b/src/DivaGL/Glitter/render_group.cpp new file mode 100644 index 0000000..77ae9d0 --- /dev/null +++ b/src/DivaGL/Glitter/render_group.cpp @@ -0,0 +1,103 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "glitter.hpp" +#include "../gl_state.hpp" + +namespace Glitter { + mat4 RenderGroup::RotateToEmitPosition(RenderGroup* rend_group, + RenderElement* rend_elem, vec3* vec) { + vec3 vec2; + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) + vec2 = rend_elem->translation; + else { + mat4_get_translation(&rend_group->mat, &vec2); + vec2 -= rend_elem->translation; + } + vec2 = vec3::normalize(vec2); + + mat4 mat; + if (fabsf(vec2.y) >= 0.000001f) { + mat = mat4_identity; + vec3 vec1 = *vec; + + vec3 axis; + float_t angle; + axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); + mat4_mul_rotation(&mat, &axis, angle, &mat); + } + else + mat4_rotate_z((float_t)M_PI, &mat); + return mat; + } + + mat4 RenderGroup::RotateToPrevPosition(RenderGroup* rend_group, + RenderElement* rend_elem, vec3* vec) { + vec3 vec2 = rend_elem->translation - rend_elem->translation_prev; + + if (vec3::length_squared(vec2) < 0.000001f) + vec2 = rend_elem->translation; + vec2 = vec3::normalize(vec2); + + mat4 mat; + mat4_rotate_z((float_t)M_PI, &mat); + if (fabsf(vec2.y) >= 0.000001f) { + vec3 vec1 = *vec; + + vec3 axis; + float_t angle; + axis_angle_from_vectors(&axis, &angle, &vec1, &vec2); + mat4_mul_rotation(&mat, &axis, angle, &mat); + } + return mat; + } + + void RenderGroup::CreateBuffer(RenderGroup* rend_group) { + if (rend_group->use_own_buffer) { + if (rend_group->max_count > 0) { + rend_group->buffer = (Buffer*)_operator_new(sizeof(Buffer) * rend_group->max_count); + if (!rend_group->buffer) + rend_group->max_count = 0; + + ParticleType type = rend_group->type; + GLuint& vbo = rend_group->vbo; + int32_t max_count = rend_group->max_count; + GLuint& vao = rend_group->vao; + GLuint& ebo = rend_group->ebo; + Glitter::CreateBuffer(max_count, type == PARTICLE_QUAD, vao, vbo, ebo); + rend_group->draw_list = new DrawListData; + } + } + else { + size_t particle = *(size_t*)((size_t)rend_group->particle_inst + 0x98 + 0x178); + rend_group->vao = ((GLuint*)(particle + 0x40 + 0x170))[0]; + rend_group->ebo = ((GLuint*)(particle + 0x40 + 0x170))[1]; + rend_group->draw_list = *(DrawListData**)(particle + + 0x40 + 0x170 + sizeof(GLuint) * 2); + } + } + + void RenderGroup::DeleteBuffer(RenderGroup* rend_group) { + if (rend_group->use_own_buffer) { + DrawListData* draw_list = rend_group->draw_list; + if (draw_list) { + draw_list->clear(); + draw_list->shrink_to_fit(); + _operator_delete(draw_list); + rend_group->draw_list = 0; + } + + GLuint& vbo = rend_group->vbo; + GLuint& vao = rend_group->vao; + GLuint& ebo = rend_group->ebo; + Glitter::DeleteBuffer(vao, vbo, ebo); + } + else { + rend_group->vbo = 0; + rend_group->ebo = 0; + rend_group->draw_list = 0; + } + } +} diff --git a/src/DivaGL/Glitter/render_scene.cpp b/src/DivaGL/Glitter/render_scene.cpp new file mode 100644 index 0000000..30f0423 --- /dev/null +++ b/src/DivaGL/Glitter/render_scene.cpp @@ -0,0 +1,1042 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "glitter.hpp" +#include "../gl_state.hpp" +#include "../render_context.hpp" +#include "../shader_glsl_ft.hpp" +#include "../wrap.hpp" + +namespace Glitter { + void RenderScene::CalcDisp(RenderScene* rend_sc) { + rend_sc->disp_quad = 0; + rend_sc->disp_line = 0; + rend_sc->disp_locus = 0; + + bool (FASTCALL * RenderGroup_CannotDisp)(RenderGroup * rend_group) + = (bool(FASTCALL*)(RenderGroup * rend_group))0x00000001403A7120; + + for (RenderGroup*& i : rend_sc->render_groups) { + if (!i) + continue; + + RenderGroup* rend_group = i; + if (RenderGroup_CannotDisp(rend_group)) + continue; + + CalcDisp(rend_sc, rend_group); + } + } + + void RenderScene::CalcDisp(RenderScene* rend_sc, RenderGroup* rend_group) { + rend_group->disp = 0; + switch (rend_group->type) { + case PARTICLE_QUAD: + if (!rend_group->vao) + return; + + CalcDispQuad(rend_group); + rend_sc->disp_quad += (uint32_t)rend_group->disp; + break; + case PARTICLE_LINE: + if (!rend_group->vao) + return; + + CalcDispLine(rend_group); + rend_sc->disp_line += (uint32_t)rend_group->disp; + break; + case PARTICLE_LOCUS: + if (!rend_group->vao) + return; + + CalcDispLocus(rend_group); + rend_sc->disp_locus += (uint32_t)rend_group->disp; + break; + } + } + + void RenderScene::CalcDispLine(RenderGroup* rend_group) { + if (!rend_group->elements || !rend_group->vbo || rend_group->ctrl < 1) + return; + + size_t count = 0; + RenderElement* elem = rend_group->elements; + for (size_t i = rend_group->ctrl; i > 0; i--, elem++) { + if (!elem->alive) + continue; + + if (elem->locus_history) { + size_t length = elem->locus_history->sub.vec.size(); + if (length > 1) + count += length; + } + } + + if (!count || count > rend_group->max_count) + return; + + bool has_scale = false; + vec3 scale = 0.0f; + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { + mat4 mat; + mat4_transpose(&rend_group->mat, &mat); + mat4_get_scale(&mat, &scale); + scale -= 1.0f; + if (!(has_scale |= fabsf(scale.x) > 0.000001f ? true : false)) + scale.x = 0.0f; + if (!(has_scale |= fabsf(scale.y) > 0.000001f ? true : false)) + scale.y = 0.0f; + if (!(has_scale |= fabsf(scale.z) > 0.000001f ? true : false)) + scale.z = 0.0f; + mat4_normalize_rotation(&mat, &mat); + mat4_transpose(&mat, &rend_group->mat_draw); + } + else + rend_group->mat_draw = mat4_identity; + + Buffer* buf; + if (GL_VERSION_4_5) + buf = (Buffer*)glMapNamedBuffer(rend_group->vbo, GL_WRITE_ONLY); + else { + gl_state_bind_array_buffer(rend_group->vbo); + buf = (Buffer*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (!buf) { + if (!GL_VERSION_4_5) + gl_state_bind_array_buffer(0); + return; + } + + elem = rend_group->elements; + size_t disp = 0; + rend_group->draw_list->clear(); + for (size_t i = rend_group->ctrl, index = 0; i > 0; elem++) { + if (!elem->alive) + continue; + + i--; + LocusHistory* hist = elem->locus_history; + if (elem->color.w < 0.01f || !hist || hist->sub.vec.size() < 2) + continue; + + size_t j = 0; + if (has_scale) + for (LocusHistory::Data& hist_data : hist->sub.vec) { + vec3& pos = hist_data.translation; + buf->position = pos + (pos - elem->base_translation) * scale; + buf->uv[0] = 0.0f; + buf->uv[1] = 0.0f; + buf->color = hist_data.color; + j++; + buf++; + } + else + for (LocusHistory::Data& hist_data : hist->sub.vec) { + buf->position = hist_data.translation; + buf->uv[0] = 0.0f; + buf->uv[1] = 0.0f; + buf->color = hist_data.color; + j++; + buf++; + } + + if (j > 0) { + disp += j; + rend_group->draw_list->push_back({ (GLint)index, (GLsizei)j }); + index += j; + } + } + rend_group->disp = disp; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(rend_group->vbo); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + } + + void RenderScene::CalcDispLocus(RenderGroup* rend_group) { + if (!rend_group->elements || !rend_group->vbo || rend_group->ctrl < 1) + return; + + size_t count = 0; + RenderElement* elem = rend_group->elements; + for (size_t i = rend_group->ctrl; i > 0; i--, elem++) { + if (!elem->alive) + continue; + + if (elem->locus_history) { + LocusHistory* hist = elem->locus_history; + size_t length = elem->locus_history->sub.vec.size(); + if (length > 1) + count += 2 * length; + } + } + + if (!count || count > rend_group->max_count) + return; + + mat4 cam_view; + mat4 cam_inv_view; + mat4_transpose(&camera_data->view_matrix, &cam_view); + mat4_transpose(&camera_data->inv_view_matrix, &cam_inv_view); + + vec3 x_vec = { 1.0f, 0.0f, 0.0f }; + if (rend_group->flags & PARTICLE_LOCAL) { + mat4 mat; + mat4_transpose(&rend_group->mat, &mat); + mat4_mul(&cam_inv_view, &mat, &mat); + mat4_mul(&cam_view, &mat, &mat); + mat4_mul(&mat, &cam_inv_view, &mat); + mat4_transpose(&mat, &rend_group->mat_draw); + } + else + rend_group->mat_draw = mat4_identity; + + bool has_scale = false; + vec3 scale = 0.0f; + mat3 model_mat; + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { + mat4 mat; + mat4_transpose(&rend_group->mat, &mat); + mat4_get_scale(&mat, &scale); + if (rend_group->flags & PARTICLE_SCALE) + x_vec.x = scale.x; + scale -= 1.0f; + if (!(has_scale |= fabsf(scale.x) > 0.000001f ? true : false)) + scale.x = 0.0f; + if (!(has_scale |= fabsf(scale.y) > 0.000001f ? true : false)) + scale.y = 0.0f; + if (!(has_scale |= fabsf(scale.z) > 0.000001f ? true : false)) + scale.z = 0.0f; + + mat4 mat_rot; + mat4_transpose(&rend_group->mat_rot, &mat_rot); + mat4_transform_vector(&mat_rot, &scale, &scale); + + mat4_to_mat3(&mat, &model_mat); + mat3_normalize_rotation(&model_mat, &model_mat); + } + else + model_mat = mat3_identity; + + mat3 cam_inv_view_mat3; + mat4_to_mat3(&cam_inv_view, &cam_inv_view_mat3); + mat3_invert(&cam_inv_view_mat3, &cam_inv_view_mat3); + mat3_transform_vector(&cam_inv_view_mat3, &x_vec, &x_vec); + + Buffer* buf; + if (GL_VERSION_4_5) + buf = (Buffer*)glMapNamedBuffer(rend_group->vbo, GL_WRITE_ONLY); + else { + gl_state_bind_array_buffer(rend_group->vbo); + buf = (Buffer*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (!buf) { + if (!GL_VERSION_4_5) + gl_state_bind_array_buffer(0); + return; + } + + elem = rend_group->elements; + vec2 split_uv = rend_group->split_uv; + Pivot pivot = rend_group->pivot; + size_t disp = 0; + rend_group->draw_list->clear(); + for (size_t i = rend_group->ctrl, index = 0; i > 0; elem++) { + if (!elem->alive) + continue; + + i--; + LocusHistory* hist = elem->locus_history; + if (elem->color.w < 0.01f || !hist || hist->sub.vec.size() < 2) + continue; + + float_t uv_u = elem->uv.x + elem->uv_scroll.x; + float_t uv_u_2nd = elem->uv.x + elem->uv_scroll.x + split_uv.x; + float_t uv_v_2nd = elem->uv.y + elem->uv_scroll.y + split_uv.y; + float_t uv_v_scale = split_uv.y / (float_t)(hist->sub.vec.size() - 1); + + uv_v_2nd = 1.0f - uv_v_2nd; + + size_t len = elem->locus_history->sub.vec.size(); + size_t j = 0; + if (has_scale) + for (LocusHistory::Data& hist_data : hist->sub.vec) { + vec3 pos = hist_data.translation; + vec3 pos_diff = (pos - elem->base_translation) * scale; + mat3_transform_vector(&model_mat, &pos_diff, &pos_diff); + pos += pos_diff; + + float_t v00; + float_t v01; + CalcDispLocusSetPivot(pivot, + hist_data.scale * elem->scale.x * elem->scale_all, + v00, v01); + + buf[0].position = pos + x_vec * v00; + buf[0].uv[0].x = uv_u; + buf[0].uv[0].y = uv_v_2nd + (float_t)j * uv_v_scale; + buf[0].uv[1] = buf[0].uv[0]; + buf[0].color = hist_data.color; + + buf[1].position = pos + x_vec * v01; + buf[1].uv[0].x = uv_u_2nd; + buf[1].uv[0].y = uv_v_2nd + (float_t)j * uv_v_scale; + buf[1].uv[1] = buf[1].uv[0]; + buf[1].color = hist_data.color; + j++; + buf += 2; + } + else + for (LocusHistory::Data& hist_data : hist->sub.vec) { + vec3 pos = hist_data.translation; + + float_t v00; + float_t v01; + CalcDispLocusSetPivot(pivot, + hist_data.scale * elem->scale.x * elem->scale_all, + v00, v01); + + buf[0].position = pos + x_vec * v00; + buf[0].uv[0].x = uv_u; + buf[0].uv[0].y = uv_v_2nd + (float_t)j * uv_v_scale; + buf[0].uv[1] = buf[0].uv[0]; + buf[0].color = hist_data.color; + + buf[1].position = pos + x_vec * v01; + buf[1].uv[0].x = uv_u_2nd; + buf[1].uv[0].y = uv_v_2nd + (float_t)j * uv_v_scale; + buf[1].uv[1] = buf[1].uv[0]; + buf[1].color = hist_data.color; + j++; + buf += 2; + } + + if (j > 0) { + disp += j; + rend_group->draw_list->push_back({ (GLint)index, (GLsizei)(j * 2) }); + index += j * 2; + } + } + rend_group->disp = disp; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(rend_group->vbo); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + } + + void RenderScene::CalcDispQuad(RenderGroup* rend_group) { + if (!rend_group->elements || !rend_group->vbo || rend_group->ctrl < 1) + return; + + mat4 cam_view; + mat4 cam_inv_view; + mat4_transpose(&camera_data->view_matrix, &cam_view); + mat4_transpose(&camera_data->inv_view_matrix, &cam_inv_view); + + mat4 model_mat; + mat4 view_mat; + mat4 inv_view_mat; + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { + mat4_transpose(&rend_group->mat, &model_mat); + mat4_normalize_rotation(&model_mat, &view_mat); + mat4_mul(&view_mat, &cam_view, &view_mat); + mat4_invert(&view_mat, &inv_view_mat); + } + else { + model_mat = mat4_identity; + view_mat = cam_view; + inv_view_mat = cam_inv_view; + } + + if (rend_group->flags & PARTICLE_LOCAL) { + mat4 mat; + mat4_transpose(&rend_group->mat, &mat); + mat4_mul(&inv_view_mat, &mat, &inv_view_mat); + mat4_mul(&view_mat, &inv_view_mat, &view_mat); + mat4_invert(&view_mat, &inv_view_mat); + } + + mat4_mul(&view_mat, &cam_inv_view, &rend_group->mat_draw); + mat4_transpose(&rend_group->mat_draw, &rend_group->mat_draw); + + mat4 dir_mat; + switch (rend_group->draw_type) { + case DIRECTION_BILLBOARD: + mat4_clear_trans(&model_mat, &dir_mat); + mat4_mul(&dir_mat, &inv_view_mat, &dir_mat); + mat4_clear_trans(&dir_mat, &dir_mat); + break; + case DIRECTION_EMITTER_DIRECTION: + mat4_transpose(&rend_group->mat_rot, &dir_mat); + mat4_clear_trans(&dir_mat, &dir_mat); + break; + case DIRECTION_PREV_POSITION: + case DIRECTION_EMIT_POSITION: + case DIRECTION_PREV_POSITION_DUP: + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { + mat4_transpose(&rend_group->mat_rot, &dir_mat); + mat4_clear_trans(&dir_mat, &dir_mat); + } + else + dir_mat = mat4_identity; + break; + case DIRECTION_Y_AXIS: + mat4_rotate_y((float_t)-M_PI_2, &dir_mat); + break; + case DIRECTION_X_AXIS: + mat4_rotate_x((float_t)-M_PI_2, &dir_mat); + break; + case DIRECTION_Z_AXIS: + mat4_rotate_z((float_t)-M_PI_2, &dir_mat); + break; + case DIRECTION_BILLBOARD_Y_AXIS: + mat4_rotate_y(camera_data->rotation.y, &dir_mat); + break; + default: + dir_mat = mat4_identity; + break; + } + + switch (rend_group->draw_type) { + case DIRECTION_PREV_POSITION: + case DIRECTION_EMIT_POSITION: + case DIRECTION_PREV_POSITION_DUP: + CalcDispQuadDirectionRotation(rend_group, &model_mat, &dir_mat); + break; + default: + CalcDispQuadNormal(rend_group, &model_mat, &dir_mat); + break; + } + } + + void RenderScene::CalcDispQuadDirectionRotation( + RenderGroup* rend_group, mat4* model_mat, mat4* dir_mat) { + mat4 inv_model_mat; + mat4_invert(model_mat, &inv_model_mat); + mat4_clear_trans(&inv_model_mat, &inv_model_mat); + + vec3 x_vec_base = { 1.0f, 0.0f, 0.0f }; + vec3 y_vec_base = { 0.0f, 1.0f, 0.0f }; + + mat4_transform_vector(&inv_model_mat, &x_vec_base, &x_vec_base); + mat4_transform_vector(&inv_model_mat, &y_vec_base, &y_vec_base); + + vec3 up_vec; + mat4(*rotate_func)(RenderGroup*, RenderElement*, vec3*); + if (rend_group->draw_type == DIRECTION_EMIT_POSITION) { + up_vec = { 0.0f, 0.0f, 1.0f }; + rotate_func = RenderGroup::RotateToEmitPosition; + } + else { + up_vec = { 0.0f, 1.0f, 0.0f }; + rotate_func = RenderGroup::RotateToPrevPosition; + } + + vec3 scale; + mat4_get_scale(model_mat, &scale); + + Buffer* buf; + if (GL_VERSION_4_5) + buf = (Buffer*)glMapNamedBuffer(rend_group->vbo, GL_WRITE_ONLY); + else { + gl_state_bind_array_buffer(rend_group->vbo); + buf = (Buffer*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (!buf) { + if (!GL_VERSION_4_5) + gl_state_bind_array_buffer(0); + return; + } + + bool use_scale = rend_group->flags & PARTICLE_SCALE ? true : false; + RenderElement* elem = rend_group->elements; + vec2 split_uv = rend_group->split_uv; + Pivot pivot = rend_group->pivot; + size_t disp = 0; + for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { + j_max = min_def(i, j_max); + for (size_t j = j_max; j > 0; elem++) { + if (!elem->alive) + continue; + j--; + + if (elem->color.w < 0.01f) + continue; + + vec2 scale_particle = *(vec2*)&elem->scale * elem->scale_particle * elem->scale_all; + if (fabsf(scale_particle.x) < 0.000001f || fabsf(scale_particle.y) < 0.000001f) + continue; + + vec3 pos = elem->translation; + + float_t v00; + float_t v01; + float_t v10; + float_t v11; + CalcDispQuadSetPivot(pivot, + scale_particle.x, scale_particle.y, + v00, v01, v10, v11); + + vec2 pos_add[4]; + vec2 uv_add[4]; + pos_add[0].x = v00; + pos_add[0].y = v11; + uv_add[0].x = 0.0f; + uv_add[0].y = 0.0f; + pos_add[1].x = v00; + pos_add[1].y = v10; + uv_add[1].x = 0.0f; + uv_add[1].y = split_uv.y; + pos_add[2].x = v01; + pos_add[2].y = v10; + uv_add[2].x = split_uv.x; + uv_add[2].y = split_uv.y; + pos_add[3].x = v01; + pos_add[3].y = v11; + uv_add[3].x = split_uv.x; + uv_add[3].y = 0.0f; + + vec2 uv = elem->uv + elem->uv_scroll; + + mat4 mat = rotate_func(rend_group, elem, &up_vec); + mat4_clear_trans(&mat, &mat); + mat4_mul(dir_mat, &mat, &mat); + mat4_clear_trans(&mat, &mat); + + vec3 x_vec; + mat4_transform_vector(&mat, &x_vec_base, &x_vec); + vec3 y_vec; + mat4_transform_vector(&mat, &y_vec_base, &y_vec); + + if (use_scale) { + x_vec *= scale; + y_vec *= scale; + } + + float_t rot_z_cos = elem->rot_z_cos; + float_t rot_z_sin = elem->rot_z_sin; + for (int32_t k = 0; k < 4; k++, buf++) { + vec3 x_vec_rot = x_vec * (pos_add[k].x * rot_z_cos - pos_add[k].y * rot_z_sin); + vec3 y_vec_rot = y_vec * (pos_add[k].x * rot_z_sin + pos_add[k].y * rot_z_cos); + buf->position = pos + (x_vec_rot + y_vec_rot); + buf->uv[0] = uv + uv_add[k]; + buf->uv[1] = buf->uv[0]; + buf->color = elem->color; + } + disp++; + } + } + rend_group->disp = disp; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(rend_group->vbo); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + } + + void RenderScene::CalcDispQuadNormal( + RenderGroup* rend_group, mat4* model_mat, mat4* dir_mat) { + mat4 inv_model_mat; + mat4_invert(model_mat, &inv_model_mat); + mat4_clear_trans(&inv_model_mat, &inv_model_mat); + + vec3 x_vec = { 1.0f, 0.0f, 0.0f }; + vec3 y_vec = { 0.0f, 1.0f, 0.0f }; + bool use_z_offset = false; + vec3 dist_to_cam = 0.0f; + mat4 z_offset_inv_mat = mat4_identity; + if (fabsf(rend_group->z_offset) > 0.000001f) { + use_z_offset = true; + mat4_get_translation(model_mat, &dist_to_cam); + dist_to_cam = camera_data->view_point - dist_to_cam; + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { + mat4_normalize_rotation(model_mat, &z_offset_inv_mat); + mat4_invert(&z_offset_inv_mat, &z_offset_inv_mat); + } + } + + bool has_scale = false; + bool emitter_local = false; + vec3 scale = 0.0f; + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { + mat4_get_scale(model_mat, &scale); + if (rend_group->flags & PARTICLE_SCALE) { + x_vec.x = scale.x; + y_vec.y = scale.y; + } + scale -= 1.0f; + if (!(has_scale |= fabsf(scale.x) > 0.000001f ? true : false)) + scale.x = 0.0f; + if (!(has_scale |= fabsf(scale.y) > 0.000001f ? true : false)) + scale.y = 0.0f; + if (!(has_scale |= fabsf(scale.z) > 0.000001f ? true : false)) + scale.z = 0.0f; + + mat4 mat_rot; + mat4_transpose(&rend_group->mat_rot, &mat_rot); + mat4_transform_vector(&mat_rot, &scale, &scale); + emitter_local = true; + } + + vec3 ext_anim_scale; + float_t some_scale = 0.0f; + bool (FASTCALL * RenderGroup_GetExtAnimScale)(RenderGroup * rend_group, + vec3 * ext_anim_scale, float_t * some_scale) = (bool(FASTCALL*)(RenderGroup * rend_group, + vec3 * ext_anim_scale, float_t * some_scale))0x00000001403A6800; + if (RenderGroup_GetExtAnimScale(rend_group, &ext_anim_scale, &some_scale)) { + if (some_scale <= 0.0f) + some_scale = 1.0f; + + ext_anim_scale += some_scale; + x_vec.x *= ext_anim_scale.x; + y_vec.y *= ext_anim_scale.y; + } + + if (rend_group->draw_type != DIRECTION_BILLBOARD) { + mat4_transform_vector(dir_mat, &x_vec, &x_vec); + mat4_transform_vector(dir_mat, &y_vec, &y_vec); + } + else + mat4_mul(&inv_model_mat, dir_mat, &inv_model_mat); + + mat4_transform_vector(&inv_model_mat, &x_vec, &x_vec); + mat4_transform_vector(&inv_model_mat, &y_vec, &y_vec); + + Buffer* buf; + if (GL_VERSION_4_5) + buf = (Buffer*)glMapNamedBuffer(rend_group->vbo, GL_WRITE_ONLY); + else { + gl_state_bind_array_buffer(rend_group->vbo); + buf = (Buffer*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (!buf) { + if (!GL_VERSION_4_5) + gl_state_bind_array_buffer(0); + return; + } + + RenderElement* elem = rend_group->elements; + vec2 split_uv = rend_group->split_uv; + Pivot pivot = rend_group->pivot; + float_t z_offset = rend_group->z_offset; + size_t disp = 0; + if (rend_group->draw_type == DIRECTION_PARTICLE_ROTATION) + for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { + j_max = min_def(i, j_max); + for (size_t j = j_max; j > 0; elem++) { + if (!elem->alive) + continue; + j--; + + if (elem->color.w < 0.01f) + continue; + + vec2 scale_particle = *(vec2*)&elem->scale * elem->scale_particle * elem->scale_all; + if (fabsf(scale_particle.x) < 0.000001f || fabsf(scale_particle.y) < 0.000001f) + continue; + + vec3 pos = elem->translation; + if (has_scale) { + vec3 pos_diff = (pos - elem->base_translation) * scale; + mat4_transform_vector(&inv_model_mat, &pos_diff, &pos_diff); + pos += pos_diff; + } + + float_t v00; + float_t v01; + float_t v11; + float_t v10; + CalcDispQuadSetPivot(pivot, + scale_particle.x, scale_particle.y, + v00, v01, v10, v11); + + vec2 pos_add[4]; + vec2 uv_add[4]; + pos_add[0].x = v00; + pos_add[0].y = v11; + uv_add[0].x = 0.0f; + uv_add[0].y = 0.0f; + pos_add[1].x = v00; + pos_add[1].y = v10; + uv_add[1].x = 0.0f; + uv_add[1].y = split_uv.y; + pos_add[2].x = v01; + pos_add[2].y = v10; + uv_add[2].x = split_uv.x; + uv_add[2].y = split_uv.y; + pos_add[3].x = v01; + pos_add[3].y = v11; + uv_add[3].x = split_uv.x; + uv_add[3].y = 0.0f; + + vec2 uv = elem->uv + elem->uv_scroll; + + if (use_z_offset) { + vec3 z_offset_dir = vec3::normalize(dist_to_cam - pos); + if (emitter_local) + mat4_transform_vector(&z_offset_inv_mat, &z_offset_dir, &z_offset_dir); + pos += z_offset_dir * z_offset; + } + + mat3 ptc_rot; + mat3_rotate_zyx(elem->rotation.x, elem->rotation.y, elem->rotation.z, &ptc_rot); + for (int32_t k = 0; k < 4; k++, buf++) { + vec3 xy_vec_rot; + xy_vec_rot.x = x_vec.x * pos_add[k].x; + xy_vec_rot.y = y_vec.y * pos_add[k].y; + xy_vec_rot.z = 0.0f; + mat3_transform_vector(&ptc_rot, &xy_vec_rot, &xy_vec_rot); + buf->position = pos + xy_vec_rot; + buf->uv[0] = uv + uv_add[k]; + buf->uv[1] = buf->uv[0]; + buf->color = elem->color; + } + disp++; + } + } + else + for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { + j_max = min_def(i, j_max); + for (size_t j = j_max; j > 0; elem++) { + if (!elem->alive) + continue; + j--; + + if (elem->color.w < 0.01f) + continue; + + vec2 scale_particle = *(vec2*)&elem->scale * elem->scale_particle * elem->scale_all; + if (fabsf(scale_particle.x) < 0.000001f || fabsf(scale_particle.y) < 0.000001f) + continue; + + vec3 pos = elem->translation; + if (has_scale) { + vec3 pos_diff = (pos - elem->base_translation) * scale; + mat4_transform_vector(&inv_model_mat, &pos_diff, &pos_diff); + pos += pos_diff; + } + + float_t v00; + float_t v01; + float_t v11; + float_t v10; + CalcDispQuadSetPivot(pivot, + scale_particle.x, scale_particle.y, + v00, v01, v10, v11); + + vec2 pos_add[4]; + vec2 uv_add[4]; + pos_add[0].x = v00; + pos_add[0].y = v11; + uv_add[0].x = 0.0f; + uv_add[0].y = 0.0f; + pos_add[1].x = v00; + pos_add[1].y = v10; + uv_add[1].x = 0.0f; + uv_add[1].y = split_uv.y; + pos_add[2].x = v01; + pos_add[2].y = v10; + uv_add[2].x = split_uv.x; + uv_add[2].y = split_uv.y; + pos_add[3].x = v01; + pos_add[3].y = v11; + uv_add[3].x = split_uv.x; + uv_add[3].y = 0.0f; + + vec2 uv = elem->uv + elem->uv_scroll; + + if (use_z_offset) { + vec3 z_offset_dir = vec3::normalize(dist_to_cam - pos); + if (emitter_local) + mat4_transform_vector(&z_offset_inv_mat, &z_offset_dir, &z_offset_dir); + pos += z_offset_dir * z_offset; + } + + float_t rot_z_cos = elem->rot_z_cos; + float_t rot_z_sin = elem->rot_z_sin; + for (int32_t k = 0; k < 4; k++, buf++) { + vec3 x_vec_rot = x_vec * (rot_z_cos * pos_add[k].x - rot_z_sin * pos_add[k].y); + vec3 y_vec_rot = y_vec * (rot_z_sin * pos_add[k].x + rot_z_cos * pos_add[k].y); + buf->position = pos + (x_vec_rot + y_vec_rot); + buf->uv[0] = uv + uv_add[k]; + buf->uv[1] = buf->uv[0]; + buf->color = elem->color; + } + disp++; + } + } + rend_group->disp = disp; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(rend_group->vbo); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + } + + void RenderScene::Disp(RenderScene* rend_sc, RenderGroup* rend_group) { + switch (rend_group->type) { + case PARTICLE_QUAD: + case PARTICLE_LINE: + case PARTICLE_LOCUS: + break; + default: + return; + } + + if (!rend_group->vao || rend_group->disp < 1) + return; + + mat4 cam_view; + mat4 cam_projection; + mat4_transpose(&camera_data->view_matrix, &cam_view); + mat4_transpose(&camera_data->projection_matrix, &cam_projection); + + mat4 mat; + mat4_transpose(&rend_group->mat_draw, &mat); + mat4_mul(&mat, &cam_view, &mat); + mat4_mul(&mat, &cam_projection, &mat); + + float_t emission = 1.0f; + if (rend_group->flags & PARTICLE_EMISSION || rend_group->blend_mode == PARTICLE_BLEND_TYPICAL) + emission = rend_group->emission; + + glitter_batch_shader_data shader_data = {}; + mat4_transpose(&mat, &mat); + shader_data.g_mvp[0] = mat.row0; + shader_data.g_mvp[1] = mat.row1; + shader_data.g_mvp[2] = mat.row2; + shader_data.g_mvp[3] = mat.row3; + shader_data.g_glitter_blend_color = 1.0f; + shader_data.g_state_material_diffuse = 0.0f; + shader_data.g_state_material_emission = { emission, emission, emission, 1.0f }; + rctx->glitter_batch_ubo.WriteMemory(shader_data); + + GLenum blend_src = GL_SRC_ALPHA; + GLenum blend_dst = GL_ONE_MINUS_SRC_ALPHA; + switch (rend_group->blend_mode) { + case PARTICLE_BLEND_ADD: + blend_src = GL_SRC_ALPHA; + blend_dst = GL_ONE; + break; + case PARTICLE_BLEND_MULTIPLY: + blend_src = GL_ZERO; + blend_dst = GL_SRC_COLOR; + break; + } + + gl_state_enable_blend(true); + gl_state_set_blend_func(blend_src, blend_dst, true); + gl_state_set_blend_equation(GL_FUNC_ADD, true); + + GLuint texture = rctx->empty_texture_2d; + GLuint mask_texture = rctx->empty_texture_2d; + if (rend_group->type != PARTICLE_LINE && rend_group->texture) { + texture = rend_group->texture; + if (rend_group->mask_texture) { + mask_texture = rend_group->mask_texture; + + uniform->arr[U_TEXTURE_COUNT] = 2; + switch (rend_group->mask_blend_mode) { + default: + uniform->arr[U_TEXTURE_BLEND] = 0; + break; + case PARTICLE_BLEND_MULTIPLY: + uniform->arr[U_TEXTURE_BLEND] = 1; + break; + case PARTICLE_BLEND_ADD: + uniform->arr[U_TEXTURE_BLEND] = 2; + break; + } + } + else { + uniform->arr[U_TEXTURE_COUNT] = 1; + uniform->arr[U_TEXTURE_BLEND] = 0; + } + } + else { + uniform->arr[U_TEXTURE_COUNT] = 0; + uniform->arr[U_TEXTURE_BLEND] = 0; + } + + gl_state_active_bind_texture_2d(0, texture, true); + gl_state_active_bind_texture_2d(1, mask_texture, true); + + switch (rend_group->type) { + case PARTICLE_QUAD: + switch (rend_group->fog_type) { + default: + uniform->arr[U_FOG_HEIGHT] = 0; + break; + case Glitter::FOG_DEPTH: + uniform->arr[U_FOG_HEIGHT] = 1; + break; + case Glitter::FOG_HEIGHT: + uniform->arr[U_FOG_HEIGHT] = 2; + break; + } + + if (rend_group->blend_mode == PARTICLE_BLEND_PUNCH_THROUGH) { + uniform->arr[U_ALPHA_BLEND] = 1; + gl_state_enable_depth_test(true); + gl_state_set_depth_mask(GL_TRUE, true); + } + else { + uniform->arr[U_ALPHA_BLEND] = rend_group->disp_type ? 2 : 0; + gl_state_enable_depth_test(true); + gl_state_set_depth_mask(GL_FALSE, true); + } + + if (rend_group->draw_type == DIRECTION_BILLBOARD) { + gl_state_enable_cull_face(true); + gl_state_set_cull_face_mode(GL_BACK, true); + } + else + gl_state_disable_cull_face(true); + break; + case PARTICLE_LINE: + uniform->arr[U_FOG_HEIGHT] = 0; + uniform->arr[U_ALPHA_BLEND] = 2; + + gl_state_enable_depth_test(true); + gl_state_set_depth_mask(GL_FALSE, true); + gl_state_enable_cull_face(true); + gl_state_set_cull_face_mode(GL_BACK, true); + break; + case PARTICLE_LOCUS: + uniform->arr[U_FOG_HEIGHT] = 0; + uniform->arr[U_ALPHA_BLEND] = 2; + + gl_state_enable_depth_test(true); + gl_state_set_depth_mask(GL_FALSE, true); + gl_state_disable_cull_face(true); + break; + } + + shaders_ft.set(SHADER_FT_GLITTER_PT); + rctx->glitter_batch_ubo.Bind(2); + switch (rend_group->type) { + case PARTICLE_QUAD: + gl_state_bind_vertex_array(rend_group->vao, true); + shaders_ft.enable_primitive_restart(); + shaders_ft.draw_elements(GL_TRIANGLE_STRIP, (GLsizei)(5 * rend_group->disp - 1), GL_UNSIGNED_INT, 0); + shaders_ft.disable_primitive_restart(); + gl_state_bind_vertex_array(0); + break; + case PARTICLE_LINE: + case PARTICLE_LOCUS: + gl_state_bind_vertex_array(rend_group->vao, true); + DrawListData& draw_list = *rend_group->draw_list; + if (rend_group->type == PARTICLE_LINE) + for (prj::pair& i : draw_list) + shaders_ft.draw_arrays(GL_LINE_STRIP, i.first, i.second); + else + for (prj::pair& i : draw_list) + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, i.first, i.second); + gl_state_bind_vertex_array(0); + break; + } + shaders_ft.set(-1); + } + + void RenderScene::CalcDispLocusSetPivot(Pivot pivot, + float_t w, float_t& v00, float_t& v01) { + switch (pivot) { + case PIVOT_TOP_LEFT: + case PIVOT_MIDDLE_LEFT: + case PIVOT_BOTTOM_LEFT: + v00 = 0.0f; + v01 = w; + break; + case PIVOT_TOP_CENTER: + case PIVOT_MIDDLE_CENTER: + case PIVOT_BOTTOM_CENTER: + default: + v00 = w * -0.5f; + v01 = w * 0.5f; + break; + case PIVOT_TOP_RIGHT: + case PIVOT_MIDDLE_RIGHT: + case PIVOT_BOTTOM_RIGHT: + v00 = -w; + v01 = 0.0f; + break; + } + } + + void RenderScene::CalcDispQuadSetPivot(Pivot pivot, + float_t w, float_t h, float_t& v00, float_t& v01, float_t& v10, float_t& v11) { + switch (pivot) { + case PIVOT_TOP_LEFT: + v00 = 0.0f; + v01 = w; + v10 = -h; + v11 = 0.0f; + break; + case PIVOT_TOP_CENTER: + v00 = w * -0.5f; + v01 = w * 0.5f; + v10 = -h; + v11 = 0.0f; + break; + case PIVOT_TOP_RIGHT: + v00 = -w; + v01 = 0.0f; + v10 = -h; + v11 = 0.0f; + break; + case PIVOT_MIDDLE_LEFT: + v00 = 0.0f; + v01 = w; + v10 = h * -0.5f; + v11 = h * 0.5f; + break; + case PIVOT_MIDDLE_CENTER: + default: + v00 = w * -0.5f; + v01 = w * 0.5f; + v10 = h * -0.5f; + v11 = h * 0.5f; + break; + case PIVOT_MIDDLE_RIGHT: + v00 = -w; + v01 = 0.0f; + v10 = h * -0.5f; + v11 = h * 0.5f; + break; + case PIVOT_BOTTOM_LEFT: + v00 = 0.0f; + v01 = w; + v10 = 0.0f; + v11 = h; + break; + case PIVOT_BOTTOM_CENTER: + v00 = w * -0.5f; + v01 = w * 0.5f; + v10 = 0.0f; + v11 = h; + break; + case PIVOT_BOTTOM_RIGHT: + v00 = -w; + v01 = 0.0f; + v10 = 0.0f; + v11 = h; + break; + } + } +} diff --git a/src/DivaGL/Glitter/scene.cpp b/src/DivaGL/Glitter/scene.cpp new file mode 100644 index 0000000..f926d8b --- /dev/null +++ b/src/DivaGL/Glitter/scene.cpp @@ -0,0 +1,14 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "glitter.hpp" +#include "../gl_state.hpp" + +namespace Glitter { + void Scene::CalcDisp(Scene* sc) { + if (!(sc->flags & SCENE_NOT_DISP)) + RenderScene::CalcDisp(&sc->render_scene); + } +} diff --git a/src/DivaGL/auth_3d.cpp b/src/DivaGL/auth_3d.cpp new file mode 100644 index 0000000..7b5667c --- /dev/null +++ b/src/DivaGL/auth_3d.cpp @@ -0,0 +1,750 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "auth_3d.hpp" +#include "../KKdLib/database/item_table.hpp" +#include "light_param/fog.hpp" +#include "mdl/disp_manager.hpp" +#include "rob/rob.hpp" +#include "object.hpp" +#include "render_context.hpp" +#include "sprite.hpp" +#include "texture.hpp" +#include "types.hpp" +#include + +enum auth_3d_camera_auxiliary_flags { + AUTH_3D_CAMERA_AUXILIARY_EXPOSURE = 0x01, + AUTH_3D_CAMERA_AUXILIARY_GAMMA = 0x02, + AUTH_3D_CAMERA_AUXILIARY_SATURATE = 0x04, + AUTH_3D_CAMERA_AUXILIARY_AUTO_EXPOSURE = 0x08, +}; + +enum auth_3d_ep_type { + AUTH_3D_EP_NONE = 0x00, + AUTH_3D_EP_LINEAR = 0x01, + AUTH_3D_EP_CYCLE = 0x02, + AUTH_3D_EP_CYCLE_OFFSET = 0x03, +}; + +enum auth_3d_fog_flags { + AUTH_3D_FOG_DENSITY = 0x01, + AUTH_3D_FOG_START = 0x02, + AUTH_3D_FOG_END = 0x04, + AUTH_3D_FOG_COLOR = 0x08, +}; + +enum auth_3d_key_type { + AUTH_3D_KEY_NONE = 0x00, + AUTH_3D_KEY_STATIC = 0x01, + AUTH_3D_KEY_LINEAR = 0x02, + AUTH_3D_KEY_HERMITE = 0x03, + AUTH_3D_KEY_HOLD = 0x04, +}; + +enum auth_3d_light_flags { + AUTH_3D_LIGHT_AMBIENT = 0x01, + AUTH_3D_LIGHT_DIFFUSE = 0x02, + AUTH_3D_LIGHT_SPECULAR = 0x04, + AUTH_3D_LIGHT_TONE_CURVE = 0x08, +}; + +enum auth_3d_object_texture_transform_flags { + AUTH_3D_OBJECT_TEX_TRANSFORM_COVERAGE_U = 0x001, + AUTH_3D_OBJECT_TEX_TRANSFORM_COVERAGE_V = 0x002, + AUTH_3D_OBJECT_TEX_TRANSFORM_REPEAT_U = 0x004, + AUTH_3D_OBJECT_TEX_TRANSFORM_REPEAT_V = 0x008, + AUTH_3D_OBJECT_TEX_TRANSFORM_TRANSLATE_FRAME_U = 0x010, + AUTH_3D_OBJECT_TEX_TRANSFORM_TRANSLATE_FRAME_V = 0x020, + AUTH_3D_OBJECT_TEX_TRANSFORM_OFFSET_U = 0x040, + AUTH_3D_OBJECT_TEX_TRANSFORM_OFFSET_V = 0x080, + AUTH_3D_OBJECT_TEX_TRANSFORM_ROTATE_FRAME = 0x100, + AUTH_3D_OBJECT_TEX_TRANSFORM_ROTATE = 0x200, +}; + +enum auth_3d_post_process_flags { + AUTH_3D_POST_PROCESS_LENS_FLARE = 0x01, + AUTH_3D_POST_PROCESS_LENS_SHAFT = 0x02, + AUTH_3D_POST_PROCESS_LENS_GHOST = 0x04, + AUTH_3D_POST_PROCESS_RADIUS = 0x08, + AUTH_3D_POST_PROCESS_INTENSITY = 0x10, + AUTH_3D_POST_PROCESS_SCENE_FADE = 0x20, +}; + +struct kft3 { + float_t frame; + float_t value; + float_t tangent1; + float_t tangent2; +}; + +static_assert(sizeof(kft3) == 0x10, "\"kft3\" struct should have a size of 0x10"); + +struct auth_3d_key { + auth_3d_key_type type; + float_t value; + float_t max_frame; + auth_3d_ep_type ep_type_pre; + auth_3d_ep_type ep_type_post; + float_t frame_delta; + float_t value_delta; + prj::vector keys_vec; + size_t length; + kft3* keys; +}; + +static_assert(sizeof(auth_3d_key) == 0x48, "\"auth_3d_key\" struct should have a size of 0x48"); + +struct auth_3d_vec3 { + auth_3d_key x; + auth_3d_key y; + auth_3d_key z; +}; + +static_assert(sizeof(auth_3d_vec3) == 0xD8, "\"auth_3d_vec3\" struct should have a size of 0xD8"); + +struct auth_3d_rgba { + auth_3d_key r; + auth_3d_key g; + auth_3d_key b; + auth_3d_key a; + bool has_r; + bool has_g; + bool has_b; + bool has_a; + int32_t field_124; + vec4 value; + bool has_got[4]; +}; + +static_assert(sizeof(auth_3d_rgba) == 0x140, "\"auth_3d_rgba\" struct should have a size of 0x140"); + +struct auth_3d_model_transform { + mat4 mat; + auth_3d_vec3 scale; + auth_3d_vec3 rotation; + auth_3d_vec3 translation; + auth_3d_key visibility; + vec3 scale_value; + vec3 rotation_value; + vec3 translation_value; + bool visible; +}; + +static_assert(sizeof(auth_3d_model_transform) == 0x338, "\"auth_3d_model_transform\" struct should have a size of 0x338"); + +struct auth_3d_curve { + auth_3d_key curve; + prj::string name; + float_t value; +}; + +static_assert(sizeof(auth_3d_curve) == 0x70, "\"auth_3d_curve\" struct should have a size of 0x70"); + +struct auth_3d_object_curve { + auth_3d_curve* curve; + prj::string name; + float_t frame_offset; + float_t value; +}; + +static_assert(sizeof(auth_3d_object_curve) == 0x30, "\"auth_3d_object_curve\" struct should have a size of 0x30"); + +struct auth_3d_object_texture_pattern { + prj::string name; + int32_t texture_id; + auth_3d_object_curve pattern; +}; + +static_assert(sizeof(auth_3d_object_texture_pattern) == 0x58, "\"auth_3d_object_texture_pattern\" struct should have a size of 0x58"); + +struct auth_3d_object_texture_transform { + auth_3d_object_texture_transform_flags flags; + prj::string name; + int32_t texture_id; + auth_3d_key coverageU; + auth_3d_key coverageV; + auth_3d_key repeatU; + auth_3d_key repeatV; + auth_3d_key translateFrameU; + auth_3d_key translateFrameV; + auth_3d_key offsetU; + auth_3d_key offsetV; + auth_3d_key rotateFrame; + auth_3d_key rotate; + mat4 mat; + vec3 scale_value; + vec3 repeat_value; + vec3 rotate_value; + vec3 translateFrame_value; +}; + +static_assert(sizeof(auth_3d_object_texture_transform) == 0x370, "\"auth_3d_object_texture_transform\" struct should have a size of 0x370"); + +struct auth_3d_object_hrc; + +struct auth_3d_object { + auth_3d_model_transform model_transform; + int64_t field_338; + prj::string name; + prj::string uid_name; + prj::string parent_name; + prj::string parent_node; + auth_3d_object_curve pattern; + auth_3d_object_curve morph; + prj::vector texture_pattern; + prj::vectortexture_transform; + prj::vector children_object; + prj::vector children_object_hrc; + object_info object_info; + bool reflect; + bool refract; +}; + +static_assert(sizeof(auth_3d_object) == 0x488, "\"auth_3d_object\" struct should have a size of 0x488"); + +struct auth_3d_object_model_transform { + mat4 mat; + mat4 mat_inner; + auth_3d_vec3 translation; + auth_3d_vec3 rotation; + auth_3d_vec3 scale; + auth_3d_key visibility; + vec3 translation_value; + vec3 rotation_value; + vec3 scale_value; + bool visible; + mat4 mat_rot; + int64_t field_3B8; + int32_t field_3C0; + mat4 field_3C4; + vec3 field_404; + float_t frame; + bool has_rotation; + bool has_translation; + bool has_scale; + bool has_visibility; +}; + +static_assert(sizeof(auth_3d_object_model_transform) == 0x418, "\"auth_3d_object_model_transform\" struct should have a size of 0x418"); + +struct auth_3d_object_node { + prj::string name; + int32_t bone_id; + int32_t parent; + auth_3d_object_model_transform model_transform; + mat4* mat; + mat4 joint_orient; +}; + +static_assert(sizeof(auth_3d_object_node) == 0x488, "\"auth_3d_object_node\" struct should have a size of 0x488"); + +struct auth_3d_object_hrc { + prj::vector node; + prj::vector node_bone_mats; + mat4* bone_mats; + prj::string name; + prj::string uid_name; + object_info object_info; + bool reflect; + bool refract; + bool shadow; + prj::string parent_name; + prj::string parent_node; + prj::vector children_object; + prj::vector children_object_parent_node; + prj::vector children_object_hrc; + prj::vector children_object_hrc_parent_node; +}; + +static_assert(sizeof(auth_3d_object_hrc) == 0x120, "\"auth_3d_object_hrc\" struct should have a size of 0x120"); + +struct auth_3d_object_instance { + prj::string name; + prj::string uid_name; + object_info object_info; + bool shadow; + auth_3d_object_model_transform model_transform; + prj::vector object_bone_indices; + prj::vector mats; +}; + +static_assert(sizeof(auth_3d_object_instance) == 0x490, "\"auth_3d_object_instance\" struct should have a size of 0x490"); + +struct auth_3d_m_object_hrc { + prj::string name; + auth_3d_object_model_transform model_transform; + prj::vector node; + prj::vector instance; +}; + +static_assert(sizeof(auth_3d_m_object_hrc) == 0x468, "\"auth_3d_m_object_hrc\" struct should have a size of 0x468"); + +struct auth_3d_time_event { + float_t frame; + int32_t type; + size_t event_index; +}; + +static_assert(sizeof(auth_3d_time_event) == 0x10, "\"auth_3d_time_event\" struct should have a size of 0x10"); + +struct auth_3d_play_control { + float_t begin; + float_t size; + float_t fps; +}; + +static_assert(sizeof(auth_3d_play_control) == 0x0C, "\"auth_3d_play_control\" struct should have a size of 0x0C"); + +struct auth_3d_point { + prj::string name; + auth_3d_model_transform model_transform; +}; + +static_assert(sizeof(auth_3d_point) == 0x358, "\"auth_3d_point\" struct should have a size of 0x358"); + +struct auth_3d_camera_root_view_point { + auth_3d_model_transform model_transform; + auth_3d_key roll; + bool has_fov; + bool fov_is_horizontal; + auth_3d_key fov; + float_t aspect; + auth_3d_key focal_length; + float_t camera_aperture_w; + float_t camera_aperture_h; +}; + +static_assert(sizeof(auth_3d_camera_root_view_point) == 0x428, "\"auth_3d_camera_root_view_point\" struct should have a size of 0x428"); + +struct auth_3d_camera_root { + auth_3d_model_transform model_transform; + auth_3d_camera_root_view_point view_point; + auth_3d_model_transform interest; +}; + +static_assert(sizeof(auth_3d_camera_root) == 0xA98, "\"auth_3d_camera_root\" struct should have a size of 0xA98"); + +struct auth_3d_camera_auxiliary { + auth_3d_camera_auxiliary_flags flags; + auth_3d_key exposure; + auth_3d_key gamma; + auth_3d_key saturate; + auth_3d_key auto_exposure; + float_t exposure_value; + float_t gamma_value; + float_t saturate_value; + float_t auto_exposure_value; +}; + +static_assert(sizeof(auth_3d_camera_auxiliary) == 0x138, "\"auth_3d_camera_auxiliary\" struct should have a size of 0x138"); + +struct auth_3d_light { + auth_3d_light_flags flags; + auth_3d_light_flags flags_init; + light_id id; + prj::string name; + prj::string type; + auth_3d_model_transform position; + auth_3d_model_transform spot_direction; + auth_3d_rgba Ambient; + auth_3d_rgba Diffuse; + auth_3d_rgba Specular; + auth_3d_rgba Tone_Curve; + vec4 Ambient_init; + vec4 Diffuse_init; + vec4 Specular_init; + vec4 Tone_Curve_init; +}; + +static_assert(sizeof(auth_3d_light) == 0xC00, "\"auth_3d_light\" struct should have a size of 0xC00"); + +struct auth_3d_fog { + auth_3d_fog_flags flags; + auth_3d_fog_flags flags_init; + fog_id id; + prj::string name; + auth_3d_key density; + auth_3d_key start; + auth_3d_key end; + float_t density_value; + float_t start_value; + float_t end_value; + auth_3d_rgba color; + float_t density_init; + float_t start_init; + float_t end_init; + vec4 color_init; +}; + +static_assert(sizeof(auth_3d_fog) == 0x278, "\"auth_3d_fog\" struct should have a size of 0x278"); + +struct auth_3d_post_process { + auth_3d_post_process_flags flags; + auth_3d_post_process_flags flags_init; + auth_3d_key lens_flare; + auth_3d_key lens_shaft; + auth_3d_key lens_ghost; + auth_3d_rgba radius; + auth_3d_rgba intensity; + auth_3d_rgba scene_fade; + vec3 lens_init; + vec4 radius_init_value; + vec4 intensity_init_value; + vec4 scene_fade_value; + vec3 lens_value; +}; + +static_assert(sizeof(auth_3d_post_process) == 0x4E8, "\"auth_3d_post_process\" struct should have a size of 0x4E8"); + +struct auth_3d_dof { + bool has_dof; + auth_3d_model_transform model_transform; +}; + +static_assert(sizeof(auth_3d_dof) == 0x340, "\"auth_3d_dof\" struct should have a size of 0x340"); + +struct auth_3d_chara { + prj::string name; + auth_3d_model_transform model_transform; + int32_t index; +}; + +static_assert(sizeof(auth_3d_chara) == 0x360, "\"auth_3d_chara\" struct should have a size of 0x360"); + +struct auth_3d_motion { + prj::string name; +}; + +static_assert(sizeof(auth_3d_motion) == 0x20, "\"auth_3d_motion\" struct should have a size of 0x20"); + +struct auth_3d_auth_2d { + prj::string name; +}; + +static_assert(sizeof(auth_3d_auth_2d) == 0x20, "\"auth_3d_auth_2d\" struct should have a size of 0x20"); + +struct auth_3d { + int32_t uid; + int32_t id; + bool enable; + bool camera_root_update; + bool visible; + bool repeat; + bool field_C; + bool ended; + bool left_right_reverse; + bool once; + mat4 mat; + float_t alpha; + mdl::ObjFlags obj_flags; + bool field_58; + prj::map field_60; + prj::vector texture_pattern; + int32_t chara_id; + object_info object_info; + mat4* bone_mats; + bool shadow; + chara_index src_chara; + chara_index dst_chara; + int32_t pos; + int64_t field_A8; + void* frame_rate; // FrameRateControl + float_t frame; + float_t req_frame; + float_t max_frame; + bool frame_changed; + float_t frame_offset; + float_t last_frame; + float_t fov_scale; + prj::vector* field_D8; + float_t blend; + int64_t field_E8; + int64_t field_F0; + bool paused; + prj::vector event; + prj::vector event_time; + auth_3d_time_event* event_time_next; + auth_3d_play_control play_control; + prj::vector point; + prj::vector curve; + prj::vector camera_root; + auth_3d_camera_auxiliary camera_auxiliary; + prj::vector light; + prj::vector fog; + auth_3d_post_process post_process; + auth_3d_dof dof; + prj::vector chara; + prj::vector motion; + prj::vector object; + prj::vector object_list; + prj::vector object_hrc; + prj::vector object_hrc_list; + prj::vector m_object_hrc; + prj::vector m_object_hrc_list; + prj::vector field_BE0; + prj::vector object_list_string; + prj::vector object_hrc_list_string; + prj::vector m_object_hrc_list_string; + prj::vector auth_2d; + int32_t state; + prj::vector field_C60; +}; + +static_assert(sizeof(auth_3d) == 0xC78, "\"auth_3d\" struct should have a size of 0xC78"); + +HOOK(void, FASTCALL, auth_3d_m_object_hrc_disp, 0x00000001401D0760, auth_3d_m_object_hrc* moh, auth_3d* auth) { + if (!auth->visible || !moh->model_transform.visible) + return; + + mdl::DispManager& disp_manager = *::disp_manager; + + for (auth_3d_object_instance& i : moh->instance) { + if (!i.model_transform.visible) + return; + + mdl::ObjFlags flags = mdl::OBJ_SSS; + shadow_type_enum shadow_type = SHADOW_CHARA; + if (auth->shadow || i.shadow) { + enum_or(flags, mdl::OBJ_4 | mdl::OBJ_SHADOW); + shadow_type = SHADOW_STAGE; + } + if (auth->alpha < 1.0f) + enum_or(flags, auth->obj_flags); + + disp_manager.set_obj_flags(flags); + disp_manager.set_shadow_type(shadow_type); + + Shadow* shad = shadow_ptr_get(); + if (shad && flags & mdl::OBJ_SHADOW) { + disp_manager.set_shadow_type(SHADOW_STAGE); + + mat4* m = &moh->model_transform.mat; + for (auth_3d_object_node& j : moh->node) + if (j.mat) { + m = j.mat; + break; + } + + mat4 mat = i.model_transform.mat; + mat4 t = *m; + mat4_mul(&mat, &t, &mat); + + vec3 pos = *(vec3*)&mat.row3; + pos.y -= 0.2f; + shad->field_1D0[shadow_type].push_back(pos); + } + + if (i.mats.size()) + disp_manager.entry_obj_by_object_info_object_skin( + i.object_info, 0, 0, auth->alpha, i.mats.data(), 0, 0, &i.model_transform.mat); + } + + disp_manager.set_obj_flags(); + disp_manager.set_shadow_type(SHADOW_CHARA); +} + +HOOK(void, FASTCALL, auth_3d_object_hrc_disp, 0x00000001401D04A0, auth_3d_object_hrc* oh, auth_3d* auth) { + if (!auth->visible || !oh->node.front().model_transform.visible) + return; + + mdl::DispManager& disp_manager = *::disp_manager; + + mdl::ObjFlags flags = mdl::OBJ_SSS; + if (auth->shadow | oh->shadow) + enum_or(flags, mdl::OBJ_4 | mdl::OBJ_SHADOW); + if (oh->reflect) + enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFLECT); + if (oh->refract) + enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFRACT); + if (auth->alpha < 1.0f) + enum_or(flags, auth->obj_flags); + + disp_manager.set_obj_flags(flags); + disp_manager.set_shadow_type(SHADOW_CHARA); + + mat4 mat = mat4_identity; + if (auth->chara_id >= 0 && auth->chara_id < ROB_CHARA_COUNT) { + size_t rob_chara_smth = get_rob_chara_smth(); + if (rob_chara_pv_data_array_check_chara_id(rob_chara_smth, auth->chara_id)) { + size_t rob_chr = rob_chara_array_get(rob_chara_smth, auth->chara_id); + mat4_mul(rob_chara_get_adjust_data_mat(rob_chr), sub_140516740(rob_chr), &mat); + if (auth->chara_id) + disp_manager.set_shadow_type(SHADOW_STAGE); + } + } + else if (flags & mdl::OBJ_SHADOW) { + disp_manager.set_shadow_type(SHADOW_STAGE); + + mat4* m = &oh->node.front().model_transform.mat; + for (auth_3d_object_node& i : oh->node) + if (i.mat) { + m = i.mat; + break; + } + + Shadow* shad = shadow_ptr_get(); + if (shad) { + vec3 pos = *(vec3*)&m->row3; + pos.y -= 0.2f; + shad->field_1D0[SHADOW_STAGE].push_back(pos); + } + } + + if (oh->node_bone_mats.size()) + disp_manager.entry_obj_by_object_info_object_skin( + oh->object_info, 0, 0, auth->alpha, oh->node_bone_mats.data(), 0, 0, &mat); + + disp_manager.set_obj_flags(); + disp_manager.set_shadow_type(SHADOW_CHARA); + + extern void FASTCALL implOfauth_3d_object_disp(auth_3d_object * o, auth_3d * auth); + + for (auth_3d_object*& i : oh->children_object) + implOfauth_3d_object_disp(i, auth); + + for (auth_3d_object_hrc*& i : oh->children_object_hrc) + implOfauth_3d_object_hrc_disp(i, auth); +} + +HOOK(void, FASTCALL, auth_3d_object_disp, 0x00000001401D0970, auth_3d_object* o, auth_3d* auth) { + if (!o->model_transform.visible) + return; + + if (!auth->visible) { + if (auth->pos) + spr::put_rgb_cross(&o->model_transform.mat); + + for (auth_3d_object*& i : o->children_object) + implOfauth_3d_object_disp(i, auth); + for (auth_3d_object_hrc*& i : o->children_object_hrc) + implOfauth_3d_object_hrc_disp(i, auth); + return; + } + + mat4 mat = o->model_transform.mat; + + mdl::DispManager& disp_manager = *::disp_manager; + + if (auth->chara_id >= 0 && auth->chara_id < ROB_CHARA_COUNT) { + size_t rob_chara_smth = get_rob_chara_smth(); + if (rob_chara_pv_data_array_check_chara_id(rob_chara_smth, auth->chara_id)) { + size_t rob_chr = rob_chara_array_get(rob_chara_smth, auth->chara_id); + mat4 m; + mat4_mul(rob_chara_get_adjust_data_mat(rob_chr), sub_140516740(rob_chr), &m); + mat4_mul(&mat, &m, &mat); + disp_manager.set_shadow_type(auth->chara_id ? SHADOW_STAGE : SHADOW_CHARA); + } + } + + mdl::ObjFlags flags = (mdl::ObjFlags)0; + if (auth->shadow) + enum_or(flags, mdl::OBJ_4 | mdl::OBJ_SHADOW); + if (o->reflect) + enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFLECT); + if (o->refract) + enum_or(flags, mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFRACT); + + disp_manager.set_obj_flags(flags); + + char buf[0x80]; + int32_t tex_pat_count = 0; + texture_pattern_struct tex_pat[TEXTURE_PATTERN_COUNT]; + + for (auth_3d_object_texture_pattern& i : o->texture_pattern) { + if (!i.pattern.curve || i.name.size() <= 3) + continue; + else if (tex_pat_count >= TEXTURE_PATTERN_COUNT) + break; + + sprintf_s(buf, sizeof(buf), "%.*s%03d", + (int32_t)(i.name.size() - 3), i.name.c_str(), (int32_t)prj::roundf(i.pattern.value)); + + tex_pat[tex_pat_count].src = i.texture_id; + tex_pat[tex_pat_count].dst = texture_info_get_id(buf); + tex_pat_count++; + } + + if (tex_pat_count) + disp_manager.set_texture_pattern(tex_pat_count, tex_pat); + + int32_t tex_trans_count = 0; + texture_transform_struct tex_trans[TEXTURE_TRANSFORM_COUNT]; + + for (auth_3d_object_texture_transform& i : o->texture_transform) { + if (tex_trans_count >= TEXTURE_TRANSFORM_COUNT || i.texture_id == -1 + || !texture_handler_get_texture(i.texture_id)) + break; + + tex_trans[tex_trans_count].id = i.texture_id; + tex_trans[tex_trans_count].mat = i.mat; + tex_trans_count++; + } + + if (tex_trans_count) + disp_manager.set_texture_transform(tex_trans_count, tex_trans); + + const char* uid_name = o->uid_name.c_str(); + int32_t uid_name_length = (int32_t)o->uid_name.size(); + + if (uid_name_length <= 3) + disp_manager.entry_obj_by_object_info(&mat, o->object_info); + else if (o->morph.curve) { + float_t morph = o->morph.value; + int32_t morph_int = (int32_t)morph; + morph = fmodf(morph, 1.0f); + if (morph > 0.0f && morph < 1.0f) { + sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int + 1); + object_info morph_obj_info = obj_database_get_object_info(buf); + if (morph_obj_info.is_null()) + morph_obj_info = o->object_info; + disp_manager.set_morph(morph_obj_info, morph); + + sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int); + object_info obj_info = obj_database_get_object_info(buf); + if (auth->alpha < 0.999f) + disp_manager.entry_obj_by_object_info(&mat, obj_info, auth->alpha); + else + disp_manager.entry_obj_by_object_info(&mat, obj_info); + disp_manager.set_morph({}, 0.0f); + } + else { + if (morph >= 1.0f) + morph_int++; + + sprintf_s(buf, sizeof(buf), "%.*s%03d", uid_name_length - 3, uid_name, morph_int); + object_info obj_info = obj_database_get_object_info(buf); + if (obj_info.is_null()) + obj_info = o->object_info; + disp_manager.entry_obj_by_object_info(&mat, obj_info); + } + } + else if (o->pattern.curve) { + sprintf_s(buf, sizeof(buf), "%.*s%03d", + uid_name_length - 3, uid_name, (int32_t)prj::roundf(o->pattern.value)); + object_info obj_info = obj_database_get_object_info(buf); + disp_manager.entry_obj_by_object_info(&mat, obj_info); + } + else + disp_manager.entry_obj_by_object_info(&mat, o->object_info); + + disp_manager.set_texture_transform(); + disp_manager.set_texture_pattern(); + disp_manager.set_obj_flags(); + + if (auth->pos) + spr::put_rgb_cross(&o->model_transform.mat); + + for (auth_3d_object*& i : o->children_object) + implOfauth_3d_object_disp(i, auth); + for (auth_3d_object_hrc*& i : o->children_object_hrc) + implOfauth_3d_object_hrc_disp(i, auth); +} + +void auth_3d_patch() { + INSTALL_HOOK(auth_3d_m_object_hrc_disp); + INSTALL_HOOK(auth_3d_object_hrc_disp); + INSTALL_HOOK(auth_3d_object_disp); +} diff --git a/src/DivaGL/auth_3d.hpp b/src/DivaGL/auth_3d.hpp new file mode 100644 index 0000000..b19bd21 --- /dev/null +++ b/src/DivaGL/auth_3d.hpp @@ -0,0 +1,12 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" + +extern void auth_3d_patch(); diff --git a/src/DivaGL/camera.cpp b/src/DivaGL/camera.cpp new file mode 100644 index 0000000..09dd676 --- /dev/null +++ b/src/DivaGL/camera.cpp @@ -0,0 +1,92 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "camera.hpp" +#include "render.hpp" +#include "resolution_mode.hpp" +#include + +camera_struct* camera_data = (camera_struct*)0x0000000140FBC2C0; + +static void (FASTCALL* camera_struct__update_view)(camera_struct* cam) + = (void (FASTCALL*)(camera_struct * cam))0x00000001401F7690; + +HOOK(void, FASTCALL, camera_data_update_projection, 0x00000001401F8E90) { + resolution_struct* res_wind_int = res_window_internal_get(); + resolution_struct* res_wind = res_window_get(); + + float_t sprite_half_width = (float_t)res_wind->width * 0.5f; + float_t sprite_half_height = (float_t)res_wind->height * 0.5f; + float_t render_half_width = (float_t)res_wind_int->width * 0.5f; + float_t render_half_height = (float_t)res_wind_int->height * 0.5f; + + static float_t field_20 = tanf(atanf(tanf(0.34557518363f) * 0.75f)); + + float_t aet_depth = sprite_half_height / field_20; + camera_data->aet_depth = aet_depth; + + float_t fov_correct_height = sprite_half_height / tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT); + camera_data->fov_correct_height = fov_correct_height; + + float_t v8 = (float_t)camera_data->min_distance / aet_depth; + float_t v8a = v8 * sprite_half_width; + float_t v8b = v8 * sprite_half_height; + + mat4 spr_2d_proj; + mat4_frustrum(-v8a, v8a, v8b, -v8b, camera_data->min_distance, 3000.0, &spr_2d_proj); + + vec3 spr_2d_viewpoint = { sprite_half_width, sprite_half_height, aet_depth }; + vec3 spr_2d_interest = { sprite_half_width, sprite_half_height, 0.0f }; + vec3 spr_2d_up = { 0.0f, 1.0f, 0.0f }; + mat4 spr_2d_view; + mat4_look_at(&spr_2d_viewpoint, &spr_2d_interest, &spr_2d_up, &spr_2d_view); + + mat4_mul(&spr_2d_view, &spr_2d_proj, &camera_data->view_projection_aet_2d_matrix); + mat4_transpose(&camera_data->view_projection_aet_2d_matrix, + &camera_data->view_projection_aet_2d_matrix); + + float_t v13c = render_half_height / tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT); + + float_t v13 = (float_t)camera_data->min_distance / v13c; + float_t v13a = v13 * render_half_width; + float_t v13b = v13 * render_half_height; + + mat4 spr_3d_proj; + mat4_frustrum(-v13a, v13a, v13b, -v13b, camera_data->min_distance, 3000.0, &spr_3d_proj); + + vec3 spr_3d_viewpoint = { render_half_width, render_half_height, v13c }; + vec3 spr_3d_interest = { render_half_width, render_half_height, 0.0f }; + vec3 spr_3d_up = { 0.0f, 1.0f, 0.0f }; + mat4 spr_3d_view; + mat4_look_at(&spr_3d_viewpoint, &spr_3d_interest, &spr_3d_up, &spr_3d_view); + + mat4_mul(&spr_3d_view, &spr_3d_proj, &camera_data->view_projection_aet_3d_matrix); + mat4_transpose(&camera_data->view_projection_aet_3d_matrix, + &camera_data->view_projection_aet_3d_matrix); + + render->calc_projection_matrix(&camera_data->projection_matrix, + camera_data->fov, camera_data->aspect, camera_data->min_distance, camera_data->max_distance, + camera_data->projection_scale.x, camera_data->projection_scale.y, + camera_data->projection_scale.z, camera_data->projection_scale.w); + camera_data->fov_horizontal_rad = tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT); +} + +HOOK(void, FASTCALL, camera_update, 0x00000001401F8970) { + implOfcamera_data_update_projection(); + camera_struct__update_view(camera_data); + camera_data->fast_change_hist1 = camera_data->fast_change_hist0; + camera_data->fast_change_hist0 = camera_data->fast_change; + camera_data->fast_change = false; +} + +void camera_struct::update_data() { + implOfcamera_data_update_projection(); + camera_struct__update_view(camera_data); +} + +void camera_patch() { + INSTALL_HOOK(camera_data_update_projection); + INSTALL_HOOK(camera_update); +} diff --git a/src/DivaGL/camera.hpp b/src/DivaGL/camera.hpp new file mode 100644 index 0000000..0644066 --- /dev/null +++ b/src/DivaGL/camera.hpp @@ -0,0 +1,58 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" + +struct camera_struct { + vec3 view_point; + vec3 interest; + float_t roll; + float_t fov; + float_t field_20; + int32_t field_24; + double_t aspect; + float_t min_distance; + float_t max_distance; + vec4 projection_scale; + bool use_up; + char field_49; + char field_4A; + char field_4B; + vec3 up; + bool ignore_fov; + bool ignore_min_dist; + char field_5A; + char field_5B; + mat4 view_matrix; + mat4 inv_view_matrix; + mat4 projection_matrix; + mat4 view_projection_matrix; + mat4 view_projection_aet_2d_matrix; + mat4 view_projection_aet_3d_matrix; + float_t fov_correct_height; + float_t aet_depth; + vec3 field_1E4; + vec3 field_1F0; + vec3 field_1FC; + vec3 field_208; + float_t distance; + vec3 rotation; + float_t fov_horizontal_rad; + char field_228; + bool fast_change; + bool fast_change_hist0; + bool fast_change_hist1; + int32_t field_22C; + + static void update_data(); +}; + +extern camera_struct* camera_data; + +extern void camera_patch(); diff --git a/src/DivaGL/color.cpp b/src/DivaGL/color.cpp new file mode 100644 index 0000000..c36948a --- /dev/null +++ b/src/DivaGL/color.cpp @@ -0,0 +1,6 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "color.hpp" diff --git a/src/DivaGL/color.hpp b/src/DivaGL/color.hpp new file mode 100644 index 0000000..8d8bb19 --- /dev/null +++ b/src/DivaGL/color.hpp @@ -0,0 +1,77 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/vec.hpp" + +struct color4u8 { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; + + inline color4u8() : r(), g(), b(), a() { + + } + + inline color4u8(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) { + + } + + inline color4u8(uint32_t value) { + r = (uint8_t)(value & 0xFF); + g = (uint8_t)((value >> 8) & 0xFF); + b = (uint8_t)((value >> 16) & 0xFF); + a = (uint8_t)((value >> 24) & 0xFF); + } + + inline color4u8(vec4 value) { + vec4i _value = vec4i::store_xmm(_mm_cvtps_epi32(vec4::load_xmm(vec4::clamp(value, 0.0f, 1.0f) * 255.0f))); + r = (uint8_t)_value.x; + g = (uint8_t)_value.y; + b = (uint8_t)_value.z; + a = (uint8_t)_value.w; + } + + inline operator vec4() const { + return vec4::store_xmm(_mm_cvtepi32_ps(vec4i::load_xmm(vec4i(r, g, b, a)))) * (1.0f / 255.0f); + } +}; + +struct color4u8_bgra { + uint8_t b; + uint8_t g; + uint8_t r; + uint8_t a; + + inline color4u8_bgra() : r(), g(), b(), a() { + + } + + inline color4u8_bgra(uint8_t r, uint8_t g, uint8_t b, uint8_t a) : r(r), g(g), b(b), a(a) { + + } + + inline color4u8_bgra(uint32_t value) { + b = (uint8_t)(value & 0xFF); + g = (uint8_t)((value >> 8) & 0xFF); + r = (uint8_t)((value >> 16) & 0xFF); + a = (uint8_t)((value >> 24) & 0xFF); + } + + inline color4u8_bgra(vec4 value) { + vec4i _value = vec4i::store_xmm(_mm_cvtps_epi32(vec4::load_xmm(vec4::clamp(value, 0.0f, 1.0f) * 255.0f))); + r = (uint8_t)_value.x; + g = (uint8_t)_value.y; + b = (uint8_t)_value.z; + a = (uint8_t)_value.w; + } + + inline operator vec4() const { + return vec4::store_xmm(_mm_cvtepi32_ps(vec4i::load_xmm(vec4i(r, g, b, a)))) * (1.0f / 255.0f); + } +}; diff --git a/src/DivaGL/dllmain.cpp b/src/DivaGL/dllmain.cpp new file mode 100644 index 0000000..a9016c6 --- /dev/null +++ b/src/DivaGL/dllmain.cpp @@ -0,0 +1,133 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include +#include "../KKdLib/default.hpp" +#include "hook.hpp" +#include "inject.hpp" +#include "print.hpp" +#include "shader_table.hpp" +#include "wrap.hpp" +#include +#include +#include + +size_t diva_handle; +size_t glut_handle; +size_t opengl32_handle; +size_t dll_handle; +bool aes_ni; +bool f16c; + +#if defined(DINPUT8_DLL) +struct dinput8 { + HMODULE dll; + HRESULT(*DirectInput8Create)(HINSTANCE hinst, + DWORD dwVersion, REFIID riidltf, LPVOID* ppvOut, LPUNKNOWN punkOuter); + + void LoadOriginalLibrary(HMODULE module) { + dll = module; + DirectInput8Create = (HRESULT(*)(HINSTANCE hinst, DWORD dwVersion, + REFIID riidltf, LPVOID * ppvOut, LPUNKNOWN punkOuter))GetProcAddress(dll, "DirectInput8Create"); + } +} dinput8; + +extern "C" __declspec(dllexport) HRESULT DirectInput8Create(HINSTANCE hinst, + DWORD dwVersion, REFIID riidltf, LPVOID * ppvOut, LPUNKNOWN punkOuter) { + if (!dinput8.DirectInput8Create) + return (HRESULT)0x80000002; + return dinput8.DirectInput8Create(hinst, dwVersion, riidltf, ppvOut, punkOuter); +} + +void load_original_dll() { + wchar_t dll_file_path[MAX_PATH]; + GetModuleFileNameW((HMODULE)dll_handle, dll_file_path, MAX_PATH); + + wchar_t* dll_file_name = wcsrchr(dll_file_path, '\\'); + if (!dll_file_name) + dll_file_name = wcsrchr(dll_file_path, '/'); + + if (!dll_file_name) + return; + + dll_file_name++; + + _wcslwr_s(dll_file_name, MAX_PATH - (dll_file_name - dll_file_path)); + + wchar_t* sys_folder; + if (dll_file_name && SUCCEEDED(SHGetKnownFolderPath(FOLDERID_System, 0, 0, &sys_folder))) { + size_t dll_path_len = wcslen(sys_folder) + wcslen(dll_file_name) + 2; + wchar_t* dll_path = (wchar_t*)malloc(sizeof(wchar_t) * dll_path_len); + if (dll_path) { + wcscpy_s(dll_path, dll_path_len, sys_folder); + wcscat_s(dll_path, dll_path_len, L"\\"); + wcscat_s(dll_path, dll_path_len, dll_file_name); + if (!wcscmp(dll_file_name, L"dinput8.dll")) { + HMODULE dinput8_handle = LoadLibraryW(dll_path); + if (dinput8_handle) + dinput8.LoadOriginalLibrary(dinput8_handle); + } + free(dll_path); + } + CoTaskMemFree((LPVOID)sys_folder); + } +} +#endif + +void FASTCALL divagl_main() { + int32_t cpuid_data[4] = {}; + __cpuid(cpuid_data, 1); + aes_ni = (cpuid_data[2] & (1 << 25)) ? true : false; + f16c = (cpuid_data[2] & (1 << 29)) ? true : false; + + glut_handle = (size_t)GetModuleHandleW(L"glut32.dll"); + opengl32_handle = (size_t)GetModuleHandleW(L"opengl32.dll"); + +#if defined(DINPUT8_DLL) + load_original_dll(); + LoadLibraryW(L"N:\\DUMP\\plugins\\DivaSound.dva"); + LoadLibraryW(L"N:\\DUMP\\plugins\\TLAC.dva"); +#endif + extern void FASTCALL wrap_addresses(); + wrap_addresses(); + //return; + + printf_divagl("Patching memory"); + hook_funcs(); + wrap_patch(); + inject_patches(); +} + +bool APIENTRY DllMain(HMODULE handle, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + /*if (!GetConsoleWindow()) + AllocConsole(); + + FILE* f_stdin = 0; + FILE* f_stdout = 0; + freopen_s(&f_stdin, "CONIN$", "r", stdin); + freopen_s(&f_stdout, "CONOUT$", "w", stdout);*/ + + dll_handle = (size_t)handle; + printf_divagl("Current version - v0.1.3.0"); + printf_divagl("Attach"); + divagl_main(); + break; + } + return true; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void) { + return L"DivaGL"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void) { + return L"DivaGL Plugin by korenkonder"; +} + +extern "C" __declspec(dllexport) LPCWSTR GetBuildDate(void) { + return L"v0.2.0.0"; +} diff --git a/src/DivaGL/gl.hpp b/src/DivaGL/gl.hpp new file mode 100644 index 0000000..28be4ee --- /dev/null +++ b/src/DivaGL/gl.hpp @@ -0,0 +1,6371 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/half_t.hpp" + +#define GLAPIENTRY APIENTRY + +#undef WGL_FONT_LINES +#undef WGL_FONT_POLYGONS + +typedef void GLvoid; + +typedef char GLchar; +typedef int8_t GLbyte; +typedef int16_t GLshort; +typedef int32_t GLint; +typedef int32_t GLsizei; +typedef int64_t GLint64; + +typedef uint8_t GLboolean; +typedef uint8_t GLubyte; +typedef uint16_t GLushort; +typedef uint32_t GLbitfield; +typedef uint32_t GLenum; +typedef uint32_t GLuint; +typedef uint64_t GLuint64; + +typedef float_t GLfloat; +typedef float_t GLclampf; +typedef double_t GLdouble; +typedef double_t GLclampd; + +typedef ptrdiff_t GLintptr; +typedef ptrdiff_t GLsizeiptr; + +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; + +typedef half_t GLhalfNV; + +typedef char GLcharARB; +typedef uint32_t GLhandleARB; +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; + +typedef struct _HPBUFFERARB* HPBUFFERARB; +typedef struct _HPVIDEODEV* HPVIDEODEV; + +typedef enum AttribMask { + GL_CURRENT_BIT = 0x00000001, + GL_POINT_BIT = 0x00000002, + GL_LINE_BIT = 0x00000004, + GL_POLYGON_BIT = 0x00000008, + GL_POLYGON_STIPPLE_BIT = 0x00000010, + GL_PIXEL_MODE_BIT = 0x00000020, + GL_LIGHTING_BIT = 0x00000040, + GL_FOG_BIT = 0x00000080, + GL_DEPTH_BUFFER_BIT = 0x00000100, + GL_ACCUM_BUFFER_BIT = 0x00000200, + GL_STENCIL_BUFFER_BIT = 0x00000400, + GL_VIEWPORT_BIT = 0x00000800, + GL_TRANSFORM_BIT = 0x00001000, + GL_ENABLE_BIT = 0x00002000, + GL_COLOR_BUFFER_BIT = 0x00004000, + GL_HINT_BIT = 0x00008000, + GL_EVAL_BIT = 0x00010000, + GL_LIST_BIT = 0x00020000, + GL_TEXTURE_BIT = 0x00040000, + GL_SCISSOR_BIT = 0x00080000, + GL_MULTISAMPLE_BIT = 0x20000000, + GL_MULTISAMPLE_BIT_ARB = 0x20000000, + GL_MULTISAMPLE_BIT_EXT = 0x20000000, + GL_MULTISAMPLE_BIT_3DFX = 0x20000000, + GL_ALL_ATTRIB_BITS = 0xFFFFFFFF, +} AttribMask; + +typedef enum BufferStorageMask { + GL_DYNAMIC_STORAGE_BIT = 0x0100, + GL_DYNAMIC_STORAGE_BIT_EXT = 0x0100, + GL_CLIENT_STORAGE_BIT = 0x0200, + GL_CLIENT_STORAGE_BIT_EXT = 0x0200, + GL_SPARSE_STORAGE_BIT_ARB = 0x0400, + GL_LGPU_SEPARATE_STORAGE_BIT_NVX = 0x0800, + GL_PER_GPU_STORAGE_BIT_NV = 0x0800, + GL_EXTERNAL_STORAGE_BIT_NVX = 0x2000, +} BufferStorageMask; + +typedef enum ClearBufferMask { + GL_COVERAGE_BUFFER_BIT_NV = 0x00008000, +} ClearBufferMask; + +typedef enum ClientAttribMask { + GL_CLIENT_PIXEL_STORE_BIT = 0x00000001, + GL_CLIENT_VERTEX_ARRAY_BIT = 0x00000002, + GL_CLIENT_ALL_ATTRIB_BITS = 0xFFFFFFFF, +} ClientAttribMask; + +typedef enum ContextFlagMask { + GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = 0x00000001, + GL_CONTEXT_FLAG_DEBUG_BIT = 0x00000002, + GL_CONTEXT_FLAG_DEBUG_BIT_KHR = 0x00000002, + GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT = 0x00000004, + GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB = 0x00000004, + GL_CONTEXT_FLAG_NO_ERROR_BIT = 0x00000008, + GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR = 0x00000008, + GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT = 0x00000010, +} ContextFlagMask; + +typedef enum ContextProfileMask { + GL_CONTEXT_CORE_PROFILE_BIT = 0x00000001, + GL_CONTEXT_COMPATIBILITY_PROFILE_BIT = 0x00000002, +} ContextProfileMask; + +typedef enum MapBufferAccessMask { + GL_MAP_READ_BIT = 0x0001, + GL_MAP_READ_BIT_EXT = 0x0001, + GL_MAP_WRITE_BIT = 0x0002, + GL_MAP_WRITE_BIT_EXT = 0x0002, + GL_MAP_INVALIDATE_RANGE_BIT = 0x0004, + GL_MAP_INVALIDATE_RANGE_BIT_EXT = 0x0004, + GL_MAP_INVALIDATE_BUFFER_BIT = 0x0008, + GL_MAP_INVALIDATE_BUFFER_BIT_EXT = 0x0008, + GL_MAP_FLUSH_EXPLICIT_BIT = 0x0010, + GL_MAP_FLUSH_EXPLICIT_BIT_EXT = 0x0010, + GL_MAP_UNSYNCHRONIZED_BIT = 0x0020, + GL_MAP_UNSYNCHRONIZED_BIT_EXT = 0x0020, + GL_MAP_PERSISTENT_BIT = 0x0040, + GL_MAP_PERSISTENT_BIT_EXT = 0x0040, + GL_MAP_COHERENT_BIT = 0x0080, + GL_MAP_COHERENT_BIT_EXT = 0x0080, +} MapBufferAccessMask; + +typedef enum MemoryBarrierMask { + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT = 0x00000001, + GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT = 0x00000001, + GL_ELEMENT_ARRAY_BARRIER_BIT = 0x00000002, + GL_ELEMENT_ARRAY_BARRIER_BIT_EXT = 0x00000002, + GL_UNIFORM_BARRIER_BIT = 0x00000004, + GL_UNIFORM_BARRIER_BIT_EXT = 0x00000004, + GL_TEXTURE_FETCH_BARRIER_BIT = 0x00000008, + GL_TEXTURE_FETCH_BARRIER_BIT_EXT = 0x00000008, + GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV = 0x00000010, + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT = 0x00000020, + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT = 0x00000020, + GL_COMMAND_BARRIER_BIT = 0x00000040, + GL_COMMAND_BARRIER_BIT_EXT = 0x00000040, + GL_PIXEL_BUFFER_BARRIER_BIT = 0x00000080, + GL_PIXEL_BUFFER_BARRIER_BIT_EXT = 0x00000080, + GL_TEXTURE_UPDATE_BARRIER_BIT = 0x00000100, + GL_TEXTURE_UPDATE_BARRIER_BIT_EXT = 0x00000100, + GL_BUFFER_UPDATE_BARRIER_BIT = 0x00000200, + GL_BUFFER_UPDATE_BARRIER_BIT_EXT = 0x00000200, + GL_FRAMEBUFFER_BARRIER_BIT = 0x00000400, + GL_FRAMEBUFFER_BARRIER_BIT_EXT = 0x00000400, + GL_TRANSFORM_FEEDBACK_BARRIER_BIT = 0x00000800, + GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT = 0x00000800, + GL_ATOMIC_COUNTER_BARRIER_BIT = 0x00001000, + GL_ATOMIC_COUNTER_BARRIER_BIT_EXT = 0x00001000, + GL_SHADER_STORAGE_BARRIER_BIT = 0x00002000, + GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT = 0x00004000, + GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT = 0x00004000, + GL_QUERY_BUFFER_BARRIER_BIT = 0x00008000, + GL_ALL_BARRIER_BITS = 0xFFFFFFFF, + GL_ALL_BARRIER_BITS_EXT = 0xFFFFFFFF, +} MemoryBarrierMask; + +typedef enum OcclusionQueryEventMaskAMD { + GL_QUERY_DEPTH_PASS_EVENT_BIT_AMD = 0x00000001, + GL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD = 0x00000002, + GL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD = 0x00000004, + GL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD = 0x00000008, + GL_QUERY_ALL_EVENT_BITS_AMD = 0xFFFFFFFF, +} OcclusionQueryEventMaskAMD; + +typedef enum SyncObjectMask { + GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001, + GL_SYNC_FLUSH_COMMANDS_BIT_APPLE = 0x00000001, +} SyncObjectMask; + +typedef enum UseProgramStageMask { + GL_VERTEX_SHADER_BIT = 0x00000001, + GL_VERTEX_SHADER_BIT_EXT = 0x00000001, + GL_FRAGMENT_SHADER_BIT = 0x00000002, + GL_FRAGMENT_SHADER_BIT_EXT = 0x00000002, + GL_GEOMETRY_SHADER_BIT = 0x00000004, + GL_GEOMETRY_SHADER_BIT_EXT = 0x00000004, + GL_GEOMETRY_SHADER_BIT_OES = 0x00000004, + GL_TESS_CONTROL_SHADER_BIT = 0x00000008, + GL_TESS_CONTROL_SHADER_BIT_EXT = 0x00000008, + GL_TESS_CONTROL_SHADER_BIT_OES = 0x00000008, + GL_TESS_EVALUATION_SHADER_BIT = 0x00000010, + GL_TESS_EVALUATION_SHADER_BIT_EXT = 0x00000010, + GL_TESS_EVALUATION_SHADER_BIT_OES = 0x00000010, + GL_COMPUTE_SHADER_BIT = 0x00000020, + GL_MESH_SHADER_BIT_NV = 0x00000040, + GL_TASK_SHADER_BIT_NV = 0x00000080, + GL_ALL_SHADER_BITS = 0xFFFFFFFF, + GL_ALL_SHADER_BITS_EXT = 0xFFFFFFFF, +} UseProgramStageMask; + +typedef enum SubgroupSupportedFeatures { + GL_SUBGROUP_FEATURE_BASIC_BIT_KHR = 0x00000001, + GL_SUBGROUP_FEATURE_VOTE_BIT_KHR = 0x00000002, + GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR = 0x00000004, + GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR = 0x00000008, + GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR = 0x00000010, + GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR = 0x00000020, + GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR = 0x00000040, + GL_SUBGROUP_FEATURE_QUAD_BIT_KHR = 0x00000080, + GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100, +} SubgroupSupportedFeatures; + +typedef enum TextureStorageMaskAMD { + GL_TEXTURE_STORAGE_SPARSE_BIT_AMD = 0x00000001, +} TextureStorageMaskAMD; + +typedef enum FragmentShaderDestMaskATI { + GL_RED_BIT_ATI = 0x00000001, + GL_GREEN_BIT_ATI = 0x00000002, + GL_BLUE_BIT_ATI = 0x00000004, +} FragmentShaderDestMaskATI; + +typedef enum FragmentShaderDestModMaskATI { + GL_2X_BIT_ATI = 0x00000001, + GL_4X_BIT_ATI = 0x00000002, + GL_8X_BIT_ATI = 0x00000004, + GL_HALF_BIT_ATI = 0x00000008, + GL_QUARTER_BIT_ATI = 0x00000010, + GL_EIGHTH_BIT_ATI = 0x00000020, + GL_SATURATE_BIT_ATI = 0x00000040, +} FragmentShaderDestModMaskATI; + +typedef enum FragmentShaderColorModMaskATI { + GL_COMP_BIT_ATI = 0x00000002, + GL_NEGATE_BIT_ATI = 0x00000004, + GL_BIAS_BIT_ATI = 0x00000008, +} FragmentShaderColorModMaskATI; + +typedef enum TraceMaskMESA { + GL_TRACE_OPERATIONS_BIT_MESA = 0x0001, + GL_TRACE_PRIMITIVES_BIT_MESA = 0x0002, + GL_TRACE_ARRAYS_BIT_MESA = 0x0004, + GL_TRACE_TEXTURES_BIT_MESA = 0x0008, + GL_TRACE_PIXELS_BIT_MESA = 0x0010, + GL_TRACE_ERRORS_BIT_MESA = 0x0020, + GL_TRACE_ALL_BITS_MESA = 0xFFFF, +} TraceMaskMESA; + +typedef enum PathRenderingMaskNV { + GL_BOLD_BIT_NV = 0x01, + GL_ITALIC_BIT_NV = 0x02, + GL_GLYPH_WIDTH_BIT_NV = 0x01, + GL_GLYPH_HEIGHT_BIT_NV = 0x02, + GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV = 0x04, + GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV = 0x08, + GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV = 0x10, + GL_GLYPH_VERTICAL_BEARING_X_BIT_NV = 0x20, + GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV = 0x40, + GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV = 0x80, + GL_GLYPH_HAS_KERNING_BIT_NV = 0x100, + GL_FONT_X_MIN_BOUNDS_BIT_NV = 0x00010000, + GL_FONT_Y_MIN_BOUNDS_BIT_NV = 0x00020000, + GL_FONT_X_MAX_BOUNDS_BIT_NV = 0x00040000, + GL_FONT_Y_MAX_BOUNDS_BIT_NV = 0x00080000, + GL_FONT_UNITS_PER_EM_BIT_NV = 0x00100000, + GL_FONT_ASCENDER_BIT_NV = 0x00200000, + GL_FONT_DESCENDER_BIT_NV = 0x00400000, + GL_FONT_HEIGHT_BIT_NV = 0x00800000, + GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV = 0x01000000, + GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV = 0x02000000, + GL_FONT_UNDERLINE_POSITION_BIT_NV = 0x04000000, + GL_FONT_UNDERLINE_THICKNESS_BIT_NV = 0x08000000, + GL_FONT_HAS_KERNING_BIT_NV = 0x10000000, + GL_FONT_NUM_GLYPH_INDICES_BIT_NV = 0x20000000, +} PathRenderingMaskNV; + +typedef enum PerformanceQueryCapsMaskINTEL { + GL_PERFQUERY_SINGLE_CONTEXT_INTEL = 0x00000000, + GL_PERFQUERY_GLOBAL_CONTEXT_INTEL = 0x00000001, +} PerformanceQueryCapsMaskINTEL; + +typedef enum VertexHintsMaskPGI { + GL_VERTEX23_BIT_PGI = 0x00000004, + GL_VERTEX4_BIT_PGI = 0x00000008, + GL_COLOR3_BIT_PGI = 0x00010000, + GL_COLOR4_BIT_PGI = 0x00020000, + GL_EDGEFLAG_BIT_PGI = 0x00040000, + GL_INDEX_BIT_PGI = 0x00080000, + GL_MAT_AMBIENT_BIT_PGI = 0x00100000, + GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI = 0x00200000, + GL_MAT_DIFFUSE_BIT_PGI = 0x00400000, + GL_MAT_EMISSION_BIT_PGI = 0x00800000, + GL_MAT_COLOR_INDEXES_BIT_PGI = 0x01000000, + GL_MAT_SHININESS_BIT_PGI = 0x02000000, + GL_MAT_SPECULAR_BIT_PGI = 0x04000000, + GL_NORMAL_BIT_PGI = 0x08000000, + GL_TEXCOORD1_BIT_PGI = 0x10000000, + GL_TEXCOORD2_BIT_PGI = 0x20000000, + GL_TEXCOORD3_BIT_PGI = 0x40000000, + GL_TEXCOORD4_BIT_PGI = 0x80000000, +} VertexHintsMaskPGI; + +typedef enum BufferBitQCOM { + GL_COLOR_BUFFER_BIT0_QCOM = 0x00000001, + GL_COLOR_BUFFER_BIT1_QCOM = 0x00000002, + GL_COLOR_BUFFER_BIT2_QCOM = 0x00000004, + GL_COLOR_BUFFER_BIT3_QCOM = 0x00000008, + GL_COLOR_BUFFER_BIT4_QCOM = 0x00000010, + GL_COLOR_BUFFER_BIT5_QCOM = 0x00000020, + GL_COLOR_BUFFER_BIT6_QCOM = 0x00000040, + GL_COLOR_BUFFER_BIT7_QCOM = 0x00000080, + GL_DEPTH_BUFFER_BIT0_QCOM = 0x00000100, + GL_DEPTH_BUFFER_BIT1_QCOM = 0x00000200, + GL_DEPTH_BUFFER_BIT2_QCOM = 0x00000400, + GL_DEPTH_BUFFER_BIT3_QCOM = 0x00000800, + GL_DEPTH_BUFFER_BIT4_QCOM = 0x00001000, + GL_DEPTH_BUFFER_BIT5_QCOM = 0x00002000, + GL_DEPTH_BUFFER_BIT6_QCOM = 0x00004000, + GL_DEPTH_BUFFER_BIT7_QCOM = 0x00008000, + GL_STENCIL_BUFFER_BIT0_QCOM = 0x00010000, + GL_STENCIL_BUFFER_BIT1_QCOM = 0x00020000, + GL_STENCIL_BUFFER_BIT2_QCOM = 0x00040000, + GL_STENCIL_BUFFER_BIT3_QCOM = 0x00080000, + GL_STENCIL_BUFFER_BIT4_QCOM = 0x00100000, + GL_STENCIL_BUFFER_BIT5_QCOM = 0x00200000, + GL_STENCIL_BUFFER_BIT6_QCOM = 0x00400000, + GL_STENCIL_BUFFER_BIT7_QCOM = 0x00800000, + GL_MULTISAMPLE_BUFFER_BIT0_QCOM = 0x01000000, + GL_MULTISAMPLE_BUFFER_BIT1_QCOM = 0x02000000, + GL_MULTISAMPLE_BUFFER_BIT2_QCOM = 0x04000000, + GL_MULTISAMPLE_BUFFER_BIT3_QCOM = 0x08000000, + GL_MULTISAMPLE_BUFFER_BIT4_QCOM = 0x10000000, + GL_MULTISAMPLE_BUFFER_BIT5_QCOM = 0x20000000, + GL_MULTISAMPLE_BUFFER_BIT6_QCOM = 0x40000000, + GL_MULTISAMPLE_BUFFER_BIT7_QCOM = 0x80000000, +} BufferBitQCOM; + +typedef enum FoveationConfigBitQCOM { + GL_FOVEATION_ENABLE_BIT_QCOM = 0x00000001, + GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM = 0x00000002, + GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM = 0x00000004, +} FoveationConfigBitQCOM; + +typedef enum FfdMaskSGIX { + GL_TEXTURE_DEFORMATION_BIT_SGIX = 0x00000001, + GL_GEOMETRY_DEFORMATION_BIT_SGIX = 0x00000002, +} FfdMaskSGIX; + +typedef enum CommandOpcodesNV { + GL_TERMINATE_SEQUENCE_COMMAND_NV = 0x0000, + GL_NOP_COMMAND_NV = 0x0001, + GL_DRAW_ELEMENTS_COMMAND_NV = 0x0002, + GL_DRAW_ARRAYS_COMMAND_NV = 0x0003, + GL_DRAW_ELEMENTS_STRIP_COMMAND_NV = 0x0004, + GL_DRAW_ARRAYS_STRIP_COMMAND_NV = 0x0005, + GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV = 0x0006, + GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV = 0x0007, + GL_ELEMENT_ADDRESS_COMMAND_NV = 0x0008, + GL_ATTRIBUTE_ADDRESS_COMMAND_NV = 0x0009, + GL_UNIFORM_ADDRESS_COMMAND_NV = 0x000A, + GL_BLEND_COLOR_COMMAND_NV = 0x000B, + GL_STENCIL_REF_COMMAND_NV = 0x000C, + GL_LINE_WIDTH_COMMAND_NV = 0x000D, + GL_POLYGON_OFFSET_COMMAND_NV = 0x000E, + GL_ALPHA_REF_COMMAND_NV = 0x000F, + GL_VIEWPORT_COMMAND_NV = 0x0010, + GL_SCISSOR_COMMAND_NV = 0x0011, + GL_FRONT_FACE_COMMAND_NV = 0x0012, +} CommandOpcodesNV; + +typedef enum MapTextureFormatINTEL { + GL_LAYOUT_DEFAULT_INTEL = 0, + GL_LAYOUT_LINEAR_INTEL = 1, + GL_LAYOUT_LINEAR_CPU_CACHED_INTEL = 2, +} MapTextureFormatINTEL; + +typedef enum PathRenderingTokenNV { + GL_CLOSE_PATH_NV = 0x00, + GL_MOVE_TO_NV = 0x02, + GL_RELATIVE_MOVE_TO_NV = 0x03, + GL_LINE_TO_NV = 0x04, + GL_RELATIVE_LINE_TO_NV = 0x05, + GL_HORIZONTAL_LINE_TO_NV = 0x06, + GL_RELATIVE_HORIZONTAL_LINE_TO_NV = 0x07, + GL_VERTICAL_LINE_TO_NV = 0x08, + GL_RELATIVE_VERTICAL_LINE_TO_NV = 0x09, + GL_QUADRATIC_CURVE_TO_NV = 0x0A, + GL_RELATIVE_QUADRATIC_CURVE_TO_NV = 0x0B, + GL_CUBIC_CURVE_TO_NV = 0x0C, + GL_RELATIVE_CUBIC_CURVE_TO_NV = 0x0D, + GL_SMOOTH_QUADRATIC_CURVE_TO_NV = 0x0E, + GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV = 0x0F, + GL_SMOOTH_CUBIC_CURVE_TO_NV = 0x10, + GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV = 0x11, + GL_SMALL_CCW_ARC_TO_NV = 0x12, + GL_RELATIVE_SMALL_CCW_ARC_TO_NV = 0x13, + GL_SMALL_CW_ARC_TO_NV = 0x14, + GL_RELATIVE_SMALL_CW_ARC_TO_NV = 0x15, + GL_LARGE_CCW_ARC_TO_NV = 0x16, + GL_RELATIVE_LARGE_CCW_ARC_TO_NV = 0x17, + GL_LARGE_CW_ARC_TO_NV = 0x18, + GL_RELATIVE_LARGE_CW_ARC_TO_NV = 0x19, + GL_CONIC_CURVE_TO_NV = 0x1A, + GL_RELATIVE_CONIC_CURVE_TO_NV = 0x1B, + GL_SHARED_EDGE_NV = 0xC0, + GL_ROUNDED_RECT_NV = 0xE8, + GL_RELATIVE_ROUNDED_RECT_NV = 0xE9, + GL_ROUNDED_RECT2_NV = 0xEA, + GL_RELATIVE_ROUNDED_RECT2_NV = 0xEB, + GL_ROUNDED_RECT4_NV = 0xEC, + GL_RELATIVE_ROUNDED_RECT4_NV = 0xED, + GL_ROUNDED_RECT8_NV = 0xEE, + GL_RELATIVE_ROUNDED_RECT8_NV = 0xEF, + GL_RESTART_PATH_NV = 0xF0, + GL_DUP_FIRST_CUBIC_CURVE_TO_NV = 0xF2, + GL_DUP_LAST_CUBIC_CURVE_TO_NV = 0xF4, + GL_RECT_NV = 0xF6, + GL_RELATIVE_RECT_NV = 0xF7, + GL_CIRCULAR_CCW_ARC_TO_NV = 0xF8, + GL_CIRCULAR_CW_ARC_TO_NV = 0xFA, + GL_CIRCULAR_TANGENT_ARC_TO_NV = 0xFC, + GL_ARC_TO_NV = 0xFE, + GL_RELATIVE_ARC_TO_NV = 0xFF, +} PathRenderingTokenNV; + +typedef enum TransformFeedbackTokenNV { + GL_NEXT_BUFFER_NV = -2, + GL_SKIP_COMPONENTS4_NV = -3, + GL_SKIP_COMPONENTS3_NV = -4, + GL_SKIP_COMPONENTS2_NV = -5, + GL_SKIP_COMPONENTS1_NV = -6, +} TransformFeedbackTokenNV; + +typedef enum TriangleListSUN { + GL_RESTART_SUN = 0x0001, + GL_REPLACE_MIDDLE_SUN = 0x0002, + GL_REPLACE_OLDEST_SUN = 0x0003, +} TriangleListSUN; + +typedef enum SpecialNumbers { + GL_FALSE = 0, + GL_NO_ERROR = 0, + GL_ZERO = 0, + GL_NONE = 0, + GL_NONE_OES = 0, + GL_TRUE = 1, + GL_ONE = 1, + GL_INVALID_INDEX = 0xFFFFFFFF, + GL_ALL_PIXELS_AMD = 0xFFFFFFFF, + GL_TIMEOUT_IGNORED = 0xFFFFFFFFFFFFFFFF, + GL_TIMEOUT_IGNORED_APPLE = 0xFFFFFFFFFFFFFFFF, + GL_VERSION_ES_CL_1_0 = 1, + GL_VERSION_ES_CM_1_1 = 1, + GL_VERSION_ES_CL_1_1 = 1, + GL_UUID_SIZE_EXT = 16, + GL_LUID_SIZE_EXT = 8, + WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB = 0, + WGL_FONT_LINES = 0, + WGL_FONT_POLYGONS = 1, +} SpecialNumbers; + +typedef enum GL { + GL_POINTS = 0x0000, + GL_LINES = 0x0001, + GL_LINE_LOOP = 0x0002, + GL_LINE_STRIP = 0x0003, + GL_TRIANGLES = 0x0004, + GL_TRIANGLE_STRIP = 0x0005, + GL_TRIANGLE_FAN = 0x0006, + GL_QUADS = 0x0007, + GL_QUADS_EXT = 0x0007, + GL_QUADS_OES = 0x0007, + GL_QUAD_STRIP = 0x0008, + GL_POLYGON = 0x0009, + GL_LINES_ADJACENCY = 0x000A, + GL_LINES_ADJACENCY_ARB = 0x000A, + GL_LINES_ADJACENCY_EXT = 0x000A, + GL_LINES_ADJACENCY_OES = 0x000A, + GL_LINE_STRIP_ADJACENCY = 0x000B, + GL_LINE_STRIP_ADJACENCY_ARB = 0x000B, + GL_LINE_STRIP_ADJACENCY_EXT = 0x000B, + GL_LINE_STRIP_ADJACENCY_OES = 0x000B, + GL_TRIANGLES_ADJACENCY = 0x000C, + GL_TRIANGLES_ADJACENCY_ARB = 0x000C, + GL_TRIANGLES_ADJACENCY_EXT = 0x000C, + GL_TRIANGLES_ADJACENCY_OES = 0x000C, + GL_TRIANGLE_STRIP_ADJACENCY = 0x000D, + GL_TRIANGLE_STRIP_ADJACENCY_ARB = 0x000D, + GL_TRIANGLE_STRIP_ADJACENCY_EXT = 0x000D, + GL_TRIANGLE_STRIP_ADJACENCY_OES = 0x000D, + GL_PATCHES = 0x000E, + GL_PATCHES_EXT = 0x000E, + GL_PATCHES_OES = 0x000E, + GL_ACCUM = 0x0100, + GL_LOAD = 0x0101, + GL_RETURN = 0x0102, + GL_MULT = 0x0103, + GL_ADD = 0x0104, + GL_NEVER = 0x0200, + GL_LESS = 0x0201, + GL_EQUAL = 0x0202, + GL_LEQUAL = 0x0203, + GL_GREATER = 0x0204, + GL_NOTEQUAL = 0x0205, + GL_GEQUAL = 0x0206, + GL_ALWAYS = 0x0207, + GL_SRC_COLOR = 0x0300, + GL_ONE_MINUS_SRC_COLOR = 0x0301, + GL_SRC_ALPHA = 0x0302, + GL_ONE_MINUS_SRC_ALPHA = 0x0303, + GL_DST_ALPHA = 0x0304, + GL_ONE_MINUS_DST_ALPHA = 0x0305, + GL_DST_COLOR = 0x0306, + GL_ONE_MINUS_DST_COLOR = 0x0307, + GL_SRC_ALPHA_SATURATE = 0x0308, + GL_SRC_ALPHA_SATURATE_EXT = 0x0308, + GL_FRONT_LEFT = 0x0400, + GL_FRONT_RIGHT = 0x0401, + GL_BACK_LEFT = 0x0402, + GL_BACK_RIGHT = 0x0403, + GL_FRONT = 0x0404, + GL_BACK = 0x0405, + GL_LEFT = 0x0406, + GL_RIGHT = 0x0407, + GL_FRONT_AND_BACK = 0x0408, + GL_AUX0 = 0x0409, + GL_AUX1 = 0x040A, + GL_AUX2 = 0x040B, + GL_AUX3 = 0x040C, + GL_INVALID_ENUM = 0x0500, + GL_INVALID_VALUE = 0x0501, + GL_INVALID_OPERATION = 0x0502, + GL_STACK_OVERFLOW = 0x0503, + GL_STACK_OVERFLOW_KHR = 0x0503, + GL_STACK_UNDERFLOW = 0x0504, + GL_STACK_UNDERFLOW_KHR = 0x0504, + GL_OUT_OF_MEMORY = 0x0505, + GL_INVALID_FRAMEBUFFER_OPERATION = 0x0506, + GL_INVALID_FRAMEBUFFER_OPERATION_EXT = 0x0506, + GL_INVALID_FRAMEBUFFER_OPERATION_OES = 0x0506, + GL_CONTEXT_LOST = 0x0507, + GL_CONTEXT_LOST_KHR = 0x0507, + GL_2D = 0x0600, + GL_3D = 0x0601, + GL_3D_COLOR = 0x0602, + GL_3D_COLOR_TEXTURE = 0x0603, + GL_4D_COLOR_TEXTURE = 0x0604, + GL_PASS_THROUGH_TOKEN = 0x0700, + GL_POINT_TOKEN = 0x0701, + GL_LINE_TOKEN = 0x0702, + GL_POLYGON_TOKEN = 0x0703, + GL_BITMAP_TOKEN = 0x0704, + GL_DRAW_PIXEL_TOKEN = 0x0705, + GL_COPY_PIXEL_TOKEN = 0x0706, + GL_LINE_RESET_TOKEN = 0x0707, + GL_EXP = 0x0800, + GL_EXP2 = 0x0801, + GL_CW = 0x0900, + GL_CCW = 0x0901, + GL_COEFF = 0x0A00, + GL_ORDER = 0x0A01, + GL_DOMAIN = 0x0A02, + GL_CURRENT_COLOR = 0x0B00, + GL_CURRENT_INDEX = 0x0B01, + GL_CURRENT_NORMAL = 0x0B02, + GL_CURRENT_TEXTURE_COORDS = 0x0B03, + GL_CURRENT_RASTER_COLOR = 0x0B04, + GL_CURRENT_RASTER_INDEX = 0x0B05, + GL_CURRENT_RASTER_TEXTURE_COORDS = 0x0B06, + GL_CURRENT_RASTER_POSITION = 0x0B07, + GL_CURRENT_RASTER_POSITION_VALID = 0x0B08, + GL_CURRENT_RASTER_DISTANCE = 0x0B09, + GL_POINT_SMOOTH = 0x0B10, + GL_POINT_SIZE = 0x0B11, + GL_POINT_SIZE_RANGE = 0x0B12, + GL_SMOOTH_POINT_SIZE_RANGE = 0x0B12, + GL_POINT_SIZE_GRANULARITY = 0x0B13, + GL_SMOOTH_POINT_SIZE_GRANULARITY = 0x0B13, + GL_LINE_SMOOTH = 0x0B20, + GL_LINE_WIDTH = 0x0B21, + GL_LINE_WIDTH_RANGE = 0x0B22, + GL_SMOOTH_LINE_WIDTH_RANGE = 0x0B22, + GL_LINE_WIDTH_GRANULARITY = 0x0B23, + GL_SMOOTH_LINE_WIDTH_GRANULARITY = 0x0B23, + GL_LINE_STIPPLE = 0x0B24, + GL_LINE_STIPPLE_PATTERN = 0x0B25, + GL_LINE_STIPPLE_REPEAT = 0x0B26, + GL_LIST_MODE = 0x0B30, + GL_MAX_LIST_NESTING = 0x0B31, + GL_LIST_BASE = 0x0B32, + GL_LIST_INDEX = 0x0B33, + GL_POLYGON_MODE = 0x0B40, + GL_POLYGON_MODE_NV = 0x0B40, + GL_POLYGON_SMOOTH = 0x0B41, + GL_POLYGON_STIPPLE = 0x0B42, + GL_EDGE_FLAG = 0x0B43, + GL_CULL_FACE = 0x0B44, + GL_CULL_FACE_MODE = 0x0B45, + GL_FRONT_FACE = 0x0B46, + GL_LIGHTING = 0x0B50, + GL_LIGHT_MODEL_LOCAL_VIEWER = 0x0B51, + GL_LIGHT_MODEL_TWO_SIDE = 0x0B52, + GL_LIGHT_MODEL_AMBIENT = 0x0B53, + GL_SHADE_MODEL = 0x0B54, + GL_COLOR_MATERIAL_FACE = 0x0B55, + GL_COLOR_MATERIAL_PARAMETER = 0x0B56, + GL_COLOR_MATERIAL = 0x0B57, + GL_FOG = 0x0B60, + GL_FOG_INDEX = 0x0B61, + GL_FOG_DENSITY = 0x0B62, + GL_FOG_START = 0x0B63, + GL_FOG_END = 0x0B64, + GL_FOG_MODE = 0x0B65, + GL_FOG_COLOR = 0x0B66, + GL_DEPTH_RANGE = 0x0B70, + GL_DEPTH_TEST = 0x0B71, + GL_DEPTH_WRITEMASK = 0x0B72, + GL_DEPTH_CLEAR_VALUE = 0x0B73, + GL_DEPTH_FUNC = 0x0B74, + GL_ACCUM_CLEAR_VALUE = 0x0B80, + GL_STENCIL_TEST = 0x0B90, + GL_STENCIL_CLEAR_VALUE = 0x0B91, + GL_STENCIL_FUNC = 0x0B92, + GL_STENCIL_VALUE_MASK = 0x0B93, + GL_STENCIL_FAIL = 0x0B94, + GL_STENCIL_PASS_DEPTH_FAIL = 0x0B95, + GL_STENCIL_PASS_DEPTH_PASS = 0x0B96, + GL_STENCIL_REF = 0x0B97, + GL_STENCIL_WRITEMASK = 0x0B98, + GL_MATRIX_MODE = 0x0BA0, + GL_NORMALIZE = 0x0BA1, + GL_VIEWPORT = 0x0BA2, + GL_MODELVIEW_STACK_DEPTH = 0x0BA3, + GL_MODELVIEW0_STACK_DEPTH_EXT = 0x0BA3, + GL_PATH_MODELVIEW_STACK_DEPTH_NV = 0x0BA3, + GL_PROJECTION_STACK_DEPTH = 0x0BA4, + GL_PATH_PROJECTION_STACK_DEPTH_NV = 0x0BA4, + GL_TEXTURE_STACK_DEPTH = 0x0BA5, + GL_MODELVIEW_MATRIX = 0x0BA6, + GL_MODELVIEW0_MATRIX_EXT = 0x0BA6, + GL_PATH_MODELVIEW_MATRIX_NV = 0x0BA6, + GL_PROJECTION_MATRIX = 0x0BA7, + GL_PATH_PROJECTION_MATRIX_NV = 0x0BA7, + GL_TEXTURE_MATRIX = 0x0BA8, + GL_ATTRIB_STACK_DEPTH = 0x0BB0, + GL_CLIENT_ATTRIB_STACK_DEPTH = 0x0BB1, + GL_ALPHA_TEST = 0x0BC0, + GL_ALPHA_TEST_QCOM = 0x0BC0, + GL_ALPHA_TEST_FUNC = 0x0BC1, + GL_ALPHA_TEST_FUNC_QCOM = 0x0BC1, + GL_ALPHA_TEST_REF = 0x0BC2, + GL_ALPHA_TEST_REF_QCOM = 0x0BC2, + GL_DITHER = 0x0BD0, + GL_BLEND_DST = 0x0BE0, + GL_BLEND_SRC = 0x0BE1, + GL_BLEND = 0x0BE2, + GL_LOGIC_OP_MODE = 0x0BF0, + GL_INDEX_LOGIC_OP = 0x0BF1, + GL_LOGIC_OP = 0x0BF1, + GL_COLOR_LOGIC_OP = 0x0BF2, + GL_AUX_BUFFERS = 0x0C00, + GL_DRAW_BUFFER = 0x0C01, + GL_DRAW_BUFFER_EXT = 0x0C01, + GL_READ_BUFFER = 0x0C02, + GL_READ_BUFFER_EXT = 0x0C02, + GL_READ_BUFFER_NV = 0x0C02, + GL_SCISSOR_BOX = 0x0C10, + GL_SCISSOR_TEST = 0x0C11, + GL_INDEX_CLEAR_VALUE = 0x0C20, + GL_INDEX_WRITEMASK = 0x0C21, + GL_COLOR_CLEAR_VALUE = 0x0C22, + GL_COLOR_WRITEMASK = 0x0C23, + GL_INDEX_MODE = 0x0C30, + GL_RGBA_MODE = 0x0C31, + GL_DOUBLEBUFFER = 0x0C32, + GL_STEREO = 0x0C33, + GL_RENDER_MODE = 0x0C40, + GL_PERSPECTIVE_CORRECTION_HINT = 0x0C50, + GL_POINT_SMOOTH_HINT = 0x0C51, + GL_LINE_SMOOTH_HINT = 0x0C52, + GL_POLYGON_SMOOTH_HINT = 0x0C53, + GL_FOG_HINT = 0x0C54, + GL_TEXTURE_GEN_S = 0x0C60, + GL_TEXTURE_GEN_T = 0x0C61, + GL_TEXTURE_GEN_R = 0x0C62, + GL_TEXTURE_GEN_Q = 0x0C63, + GL_PIXEL_MAP_I_TO_I = 0x0C70, + GL_PIXEL_MAP_S_TO_S = 0x0C71, + GL_PIXEL_MAP_I_TO_R = 0x0C72, + GL_PIXEL_MAP_I_TO_G = 0x0C73, + GL_PIXEL_MAP_I_TO_B = 0x0C74, + GL_PIXEL_MAP_I_TO_A = 0x0C75, + GL_PIXEL_MAP_R_TO_R = 0x0C76, + GL_PIXEL_MAP_G_TO_G = 0x0C77, + GL_PIXEL_MAP_B_TO_B = 0x0C78, + GL_PIXEL_MAP_A_TO_A = 0x0C79, + GL_PIXEL_MAP_I_TO_I_SIZE = 0x0CB0, + GL_PIXEL_MAP_S_TO_S_SIZE = 0x0CB1, + GL_PIXEL_MAP_I_TO_R_SIZE = 0x0CB2, + GL_PIXEL_MAP_I_TO_G_SIZE = 0x0CB3, + GL_PIXEL_MAP_I_TO_B_SIZE = 0x0CB4, + GL_PIXEL_MAP_I_TO_A_SIZE = 0x0CB5, + GL_PIXEL_MAP_R_TO_R_SIZE = 0x0CB6, + GL_PIXEL_MAP_G_TO_G_SIZE = 0x0CB7, + GL_PIXEL_MAP_B_TO_B_SIZE = 0x0CB8, + GL_PIXEL_MAP_A_TO_A_SIZE = 0x0CB9, + GL_UNPACK_SWAP_BYTES = 0x0CF0, + GL_UNPACK_LSB_FIRST = 0x0CF1, + GL_UNPACK_ROW_LENGTH = 0x0CF2, + GL_UNPACK_ROW_LENGTH_EXT = 0x0CF2, + GL_UNPACK_SKIP_ROWS = 0x0CF3, + GL_UNPACK_SKIP_ROWS_EXT = 0x0CF3, + GL_UNPACK_SKIP_PIXELS = 0x0CF4, + GL_UNPACK_SKIP_PIXELS_EXT = 0x0CF4, + GL_UNPACK_ALIGNMENT = 0x0CF5, + GL_PACK_SWAP_BYTES = 0x0D00, + GL_PACK_LSB_FIRST = 0x0D01, + GL_PACK_ROW_LENGTH = 0x0D02, + GL_PACK_SKIP_ROWS = 0x0D03, + GL_PACK_SKIP_PIXELS = 0x0D04, + GL_PACK_ALIGNMENT = 0x0D05, + GL_MAP_COLOR = 0x0D10, + GL_MAP_STENCIL = 0x0D11, + GL_INDEX_SHIFT = 0x0D12, + GL_INDEX_OFFSET = 0x0D13, + GL_RED_SCALE = 0x0D14, + GL_RED_BIAS = 0x0D15, + GL_ZOOM_X = 0x0D16, + GL_ZOOM_Y = 0x0D17, + GL_GREEN_SCALE = 0x0D18, + GL_GREEN_BIAS = 0x0D19, + GL_BLUE_SCALE = 0x0D1A, + GL_BLUE_BIAS = 0x0D1B, + GL_ALPHA_SCALE = 0x0D1C, + GL_ALPHA_BIAS = 0x0D1D, + GL_DEPTH_SCALE = 0x0D1E, + GL_DEPTH_BIAS = 0x0D1F, + GL_MAX_EVAL_ORDER = 0x0D30, + GL_MAX_LIGHTS = 0x0D31, + GL_MAX_CLIP_PLANES = 0x0D32, + GL_MAX_CLIP_PLANES_IMG = 0x0D32, + GL_MAX_CLIP_DISTANCES = 0x0D32, + GL_MAX_CLIP_DISTANCES_EXT = 0x0D32, + GL_MAX_CLIP_DISTANCES_APPLE = 0x0D32, + GL_MAX_TEXTURE_SIZE = 0x0D33, + GL_MAX_PIXEL_MAP_TABLE = 0x0D34, + GL_MAX_ATTRIB_STACK_DEPTH = 0x0D35, + GL_MAX_MODELVIEW_STACK_DEPTH = 0x0D36, + GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV = 0x0D36, + GL_MAX_NAME_STACK_DEPTH = 0x0D37, + GL_MAX_PROJECTION_STACK_DEPTH = 0x0D38, + GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV = 0x0D38, + GL_MAX_TEXTURE_STACK_DEPTH = 0x0D39, + GL_MAX_VIEWPORT_DIMS = 0x0D3A, + GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = 0x0D3B, + GL_SUBPIXEL_BITS = 0x0D50, + GL_INDEX_BITS = 0x0D51, + GL_RED_BITS = 0x0D52, + GL_GREEN_BITS = 0x0D53, + GL_BLUE_BITS = 0x0D54, + GL_ALPHA_BITS = 0x0D55, + GL_DEPTH_BITS = 0x0D56, + GL_STENCIL_BITS = 0x0D57, + GL_ACCUM_RED_BITS = 0x0D58, + GL_ACCUM_GREEN_BITS = 0x0D59, + GL_ACCUM_BLUE_BITS = 0x0D5A, + GL_ACCUM_ALPHA_BITS = 0x0D5B, + GL_NAME_STACK_DEPTH = 0x0D70, + GL_AUTO_NORMAL = 0x0D80, + GL_MAP1_COLOR_4 = 0x0D90, + GL_MAP1_INDEX = 0x0D91, + GL_MAP1_NORMAL = 0x0D92, + GL_MAP1_TEXTURE_COORD_1 = 0x0D93, + GL_MAP1_TEXTURE_COORD_2 = 0x0D94, + GL_MAP1_TEXTURE_COORD_3 = 0x0D95, + GL_MAP1_TEXTURE_COORD_4 = 0x0D96, + GL_MAP1_VERTEX_3 = 0x0D97, + GL_MAP1_VERTEX_4 = 0x0D98, + GL_MAP2_COLOR_4 = 0x0DB0, + GL_MAP2_INDEX = 0x0DB1, + GL_MAP2_NORMAL = 0x0DB2, + GL_MAP2_TEXTURE_COORD_1 = 0x0DB3, + GL_MAP2_TEXTURE_COORD_2 = 0x0DB4, + GL_MAP2_TEXTURE_COORD_3 = 0x0DB5, + GL_MAP2_TEXTURE_COORD_4 = 0x0DB6, + GL_MAP2_VERTEX_3 = 0x0DB7, + GL_MAP2_VERTEX_4 = 0x0DB8, + GL_MAP1_GRID_DOMAIN = 0x0DD0, + GL_MAP1_GRID_SEGMENTS = 0x0DD1, + GL_MAP2_GRID_DOMAIN = 0x0DD2, + GL_MAP2_GRID_SEGMENTS = 0x0DD3, + GL_TEXTURE_1D = 0x0DE0, + GL_TEXTURE_2D = 0x0DE1, + GL_FEEDBACK_BUFFER_POINTER = 0x0DF0, + GL_FEEDBACK_BUFFER_SIZE = 0x0DF1, + GL_FEEDBACK_BUFFER_TYPE = 0x0DF2, + GL_SELECTION_BUFFER_POINTER = 0x0DF3, + GL_SELECTION_BUFFER_SIZE = 0x0DF4, + GL_TEXTURE_WIDTH = 0x1000, + GL_TEXTURE_HEIGHT = 0x1001, + GL_TEXTURE_INTERNAL_FORMAT = 0x1003, + GL_TEXTURE_COMPONENTS = 0x1003, + GL_TEXTURE_BORDER_COLOR = 0x1004, + GL_TEXTURE_BORDER_COLOR_EXT = 0x1004, + GL_TEXTURE_BORDER_COLOR_NV = 0x1004, + GL_TEXTURE_BORDER_COLOR_OES = 0x1004, + GL_TEXTURE_BORDER = 0x1005, + GL_TEXTURE_TARGET = 0x1006, + GL_DONT_CARE = 0x1100, + GL_FASTEST = 0x1101, + GL_NICEST = 0x1102, + GL_AMBIENT = 0x1200, + GL_DIFFUSE = 0x1201, + GL_SPECULAR = 0x1202, + GL_POSITION = 0x1203, + GL_SPOT_DIRECTION = 0x1204, + GL_SPOT_EXPONENT = 0x1205, + GL_SPOT_CUTOFF = 0x1206, + GL_CONSTANT_ATTENUATION = 0x1207, + GL_LINEAR_ATTENUATION = 0x1208, + GL_QUADRATIC_ATTENUATION = 0x1209, + GL_COMPILE = 0x1300, + GL_COMPILE_AND_EXECUTE = 0x1301, + GL_BYTE = 0x1400, + GL_UNSIGNED_BYTE = 0x1401, + GL_SHORT = 0x1402, + GL_UNSIGNED_SHORT = 0x1403, + GL_INT = 0x1404, + GL_UNSIGNED_INT = 0x1405, + GL_FLOAT = 0x1406, + GL_2_BYTES = 0x1407, + GL_2_BYTES_NV = 0x1407, + GL_3_BYTES = 0x1408, + GL_3_BYTES_NV = 0x1408, + GL_4_BYTES = 0x1409, + GL_4_BYTES_NV = 0x1409, + GL_DOUBLE = 0x140A, + GL_DOUBLE_EXT = 0x140A, + GL_HALF_FLOAT = 0x140B, + GL_HALF_FLOAT_ARB = 0x140B, + GL_HALF_FLOAT_NV = 0x140B, + GL_HALF_APPLE = 0x140B, + GL_FIXED = 0x140C, + GL_FIXED_OES = 0x140C, + GL_INT64_ARB = 0x140E, + GL_INT64_NV = 0x140E, + GL_UNSIGNED_INT64_ARB = 0x140F, + GL_UNSIGNED_INT64_NV = 0x140F, + GL_CLEAR = 0x1500, + GL_AND = 0x1501, + GL_AND_REVERSE = 0x1502, + GL_COPY = 0x1503, + GL_AND_INVERTED = 0x1504, + GL_NOOP = 0x1505, + GL_XOR = 0x1506, + GL_XOR_NV = 0x1506, + GL_OR = 0x1507, + GL_NOR = 0x1508, + GL_EQUIV = 0x1509, + GL_INVERT = 0x150A, + GL_OR_REVERSE = 0x150B, + GL_COPY_INVERTED = 0x150C, + GL_OR_INVERTED = 0x150D, + GL_NAND = 0x150E, + GL_SET = 0x150F, + GL_EMISSION = 0x1600, + GL_SHININESS = 0x1601, + GL_AMBIENT_AND_DIFFUSE = 0x1602, + GL_COLOR_INDEXES = 0x1603, + GL_MODELVIEW = 0x1700, + GL_MODELVIEW0_ARB = 0x1700, + GL_MODELVIEW0_EXT = 0x1700, + GL_PATH_MODELVIEW_NV = 0x1700, + GL_PROJECTION = 0x1701, + GL_PATH_PROJECTION_NV = 0x1701, + GL_TEXTURE = 0x1702, + GL_COLOR = 0x1800, + GL_COLOR_EXT = 0x1800, + GL_DEPTH = 0x1801, + GL_DEPTH_EXT = 0x1801, + GL_STENCIL = 0x1802, + GL_STENCIL_EXT = 0x1802, + GL_COLOR_INDEX = 0x1900, + GL_STENCIL_INDEX = 0x1901, + GL_STENCIL_INDEX_OES = 0x1901, + GL_DEPTH_COMPONENT = 0x1902, + GL_RED = 0x1903, + GL_RED_EXT = 0x1903, + GL_RED_NV = 0x1903, + GL_GREEN = 0x1904, + GL_GREEN_NV = 0x1904, + GL_BLUE = 0x1905, + GL_BLUE_NV = 0x1905, + GL_ALPHA = 0x1906, + GL_RGB = 0x1907, + GL_RGBA = 0x1908, + GL_LUMINANCE = 0x1909, + GL_LUMINANCE_ALPHA = 0x190A, + GL_BITMAP = 0x1A00, + GL_POINT = 0x1B00, + GL_POINT_NV = 0x1B00, + GL_LINE = 0x1B01, + GL_LINE_NV = 0x1B01, + GL_FILL = 0x1B02, + GL_FILL_NV = 0x1B02, + GL_RENDER = 0x1C00, + GL_FEEDBACK = 0x1C01, + GL_SELECT = 0x1C02, + GL_FLAT = 0x1D00, + GL_SMOOTH = 0x1D01, + GL_KEEP = 0x1E00, + GL_REPLACE = 0x1E01, + GL_INCR = 0x1E02, + GL_DECR = 0x1E03, + GL_VENDOR = 0x1F00, + GL_RENDERER = 0x1F01, + GL_VERSION = 0x1F02, + GL_EXTENSIONS = 0x1F03, + GL_S = 0x2000, + GL_T = 0x2001, + GL_R = 0x2002, + GL_Q = 0x2003, + GL_MODULATE = 0x2100, + GL_DECAL = 0x2101, + GL_TEXTURE_ENV_MODE = 0x2200, + GL_TEXTURE_ENV_COLOR = 0x2201, + GL_TEXTURE_ENV = 0x2300, + GL_EYE_LINEAR = 0x2400, + GL_EYE_LINEAR_NV = 0x2400, + GL_OBJECT_LINEAR = 0x2401, + GL_OBJECT_LINEAR_NV = 0x2401, + GL_SPHERE_MAP = 0x2402, + GL_TEXTURE_GEN_MODE = 0x2500, + GL_TEXTURE_GEN_MODE_OES = 0x2500, + GL_OBJECT_PLANE = 0x2501, + GL_EYE_PLANE = 0x2502, + GL_NEAREST = 0x2600, + GL_LINEAR = 0x2601, + GL_NEAREST_MIPMAP_NEAREST = 0x2700, + GL_LINEAR_MIPMAP_NEAREST = 0x2701, + GL_NEAREST_MIPMAP_LINEAR = 0x2702, + GL_LINEAR_MIPMAP_LINEAR = 0x2703, + GL_TEXTURE_MAG_FILTER = 0x2800, + GL_TEXTURE_MIN_FILTER = 0x2801, + GL_TEXTURE_WRAP_S = 0x2802, + GL_TEXTURE_WRAP_T = 0x2803, + GL_CLAMP = 0x2900, + GL_REPEAT = 0x2901, + GL_POLYGON_OFFSET_UNITS = 0x2A00, + GL_POLYGON_OFFSET_POINT = 0x2A01, + GL_POLYGON_OFFSET_POINT_NV = 0x2A01, + GL_POLYGON_OFFSET_LINE = 0x2A02, + GL_POLYGON_OFFSET_LINE_NV = 0x2A02, + GL_R3_G3_B2 = 0x2A10, + GL_V2F = 0x2A20, + GL_V3F = 0x2A21, + GL_C4UB_V2F = 0x2A22, + GL_C4UB_V3F = 0x2A23, + GL_C3F_V3F = 0x2A24, + GL_N3F_V3F = 0x2A25, + GL_C4F_N3F_V3F = 0x2A26, + GL_T2F_V3F = 0x2A27, + GL_T4F_V4F = 0x2A28, + GL_T2F_C4UB_V3F = 0x2A29, + GL_T2F_C3F_V3F = 0x2A2A, + GL_T2F_N3F_V3F = 0x2A2B, + GL_T2F_C4F_N3F_V3F = 0x2A2C, + GL_T4F_C4F_N3F_V4F = 0x2A2D, + GL_CLIP_PLANE0 = 0x3000, + GL_CLIP_PLANE0_IMG = 0x3000, + GL_CLIP_DISTANCE0 = 0x3000, + GL_CLIP_DISTANCE0_EXT = 0x3000, + GL_CLIP_DISTANCE0_APPLE = 0x3000, + GL_CLIP_PLANE1 = 0x3001, + GL_CLIP_PLANE1_IMG = 0x3001, + GL_CLIP_DISTANCE1 = 0x3001, + GL_CLIP_DISTANCE1_EXT = 0x3001, + GL_CLIP_DISTANCE1_APPLE = 0x3001, + GL_CLIP_PLANE2 = 0x3002, + GL_CLIP_PLANE2_IMG = 0x3002, + GL_CLIP_DISTANCE2 = 0x3002, + GL_CLIP_DISTANCE2_EXT = 0x3002, + GL_CLIP_DISTANCE2_APPLE = 0x3002, + GL_CLIP_PLANE3 = 0x3003, + GL_CLIP_PLANE3_IMG = 0x3003, + GL_CLIP_DISTANCE3 = 0x3003, + GL_CLIP_DISTANCE3_EXT = 0x3003, + GL_CLIP_DISTANCE3_APPLE = 0x3003, + GL_CLIP_PLANE4 = 0x3004, + GL_CLIP_PLANE4_IMG = 0x3004, + GL_CLIP_DISTANCE4 = 0x3004, + GL_CLIP_DISTANCE4_EXT = 0x3004, + GL_CLIP_DISTANCE4_APPLE = 0x3004, + GL_CLIP_PLANE5 = 0x3005, + GL_CLIP_PLANE5_IMG = 0x3005, + GL_CLIP_DISTANCE5 = 0x3005, + GL_CLIP_DISTANCE5_EXT = 0x3005, + GL_CLIP_DISTANCE5_APPLE = 0x3005, + GL_CLIP_DISTANCE6 = 0x3006, + GL_CLIP_DISTANCE6_EXT = 0x3006, + GL_CLIP_DISTANCE6_APPLE = 0x3006, + GL_CLIP_DISTANCE7 = 0x3007, + GL_CLIP_DISTANCE7_EXT = 0x3007, + GL_CLIP_DISTANCE7_APPLE = 0x3007, + GL_LIGHT0 = 0x4000, + GL_LIGHT1 = 0x4001, + GL_LIGHT2 = 0x4002, + GL_LIGHT3 = 0x4003, + GL_LIGHT4 = 0x4004, + GL_LIGHT5 = 0x4005, + GL_LIGHT6 = 0x4006, + GL_LIGHT7 = 0x4007, + GL_ABGR_EXT = 0x8000, + GL_CONSTANT_COLOR = 0x8001, + GL_CONSTANT_COLOR_EXT = 0x8001, + GL_ONE_MINUS_CONSTANT_COLOR = 0x8002, + GL_ONE_MINUS_CONSTANT_COLOR_EXT = 0x8002, + GL_CONSTANT_ALPHA = 0x8003, + GL_CONSTANT_ALPHA_EXT = 0x8003, + GL_ONE_MINUS_CONSTANT_ALPHA = 0x8004, + GL_ONE_MINUS_CONSTANT_ALPHA_EXT = 0x8004, + GL_BLEND_COLOR = 0x8005, + GL_BLEND_COLOR_EXT = 0x8005, + GL_FUNC_ADD = 0x8006, + GL_FUNC_ADD_EXT = 0x8006, + GL_FUNC_ADD_OES = 0x8006, + GL_MIN = 0x8007, + GL_MIN_EXT = 0x8007, + GL_MAX = 0x8008, + GL_MAX_EXT = 0x8008, + GL_BLEND_EQUATION = 0x8009, + GL_BLEND_EQUATION_EXT = 0x8009, + GL_BLEND_EQUATION_OES = 0x8009, + GL_BLEND_EQUATION_RGB = 0x8009, + GL_BLEND_EQUATION_RGB_EXT = 0x8009, + GL_BLEND_EQUATION_RGB_OES = 0x8009, + GL_FUNC_SUBTRACT = 0x800A, + GL_FUNC_SUBTRACT_EXT = 0x800A, + GL_FUNC_SUBTRACT_OES = 0x800A, + GL_FUNC_REVERSE_SUBTRACT = 0x800B, + GL_FUNC_REVERSE_SUBTRACT_EXT = 0x800B, + GL_FUNC_REVERSE_SUBTRACT_OES = 0x800B, + GL_CMYK_EXT = 0x800C, + GL_CMYKA_EXT = 0x800D, + GL_PACK_CMYK_HINT_EXT = 0x800E, + GL_UNPACK_CMYK_HINT_EXT = 0x800F, + GL_CONVOLUTION_1D = 0x8010, + GL_CONVOLUTION_1D_EXT = 0x8010, + GL_CONVOLUTION_2D = 0x8011, + GL_CONVOLUTION_2D_EXT = 0x8011, + GL_SEPARABLE_2D = 0x8012, + GL_SEPARABLE_2D_EXT = 0x8012, + GL_CONVOLUTION_BORDER_MODE = 0x8013, + GL_CONVOLUTION_BORDER_MODE_EXT = 0x8013, + GL_CONVOLUTION_FILTER_SCALE = 0x8014, + GL_CONVOLUTION_FILTER_SCALE_EXT = 0x8014, + GL_CONVOLUTION_FILTER_BIAS = 0x8015, + GL_CONVOLUTION_FILTER_BIAS_EXT = 0x8015, + GL_REDUCE = 0x8016, + GL_REDUCE_EXT = 0x8016, + GL_CONVOLUTION_FORMAT = 0x8017, + GL_CONVOLUTION_FORMAT_EXT = 0x8017, + GL_CONVOLUTION_WIDTH = 0x8018, + GL_CONVOLUTION_WIDTH_EXT = 0x8018, + GL_CONVOLUTION_HEIGHT = 0x8019, + GL_CONVOLUTION_HEIGHT_EXT = 0x8019, + GL_MAX_CONVOLUTION_WIDTH = 0x801A, + GL_MAX_CONVOLUTION_WIDTH_EXT = 0x801A, + GL_MAX_CONVOLUTION_HEIGHT = 0x801B, + GL_MAX_CONVOLUTION_HEIGHT_EXT = 0x801B, + GL_POST_CONVOLUTION_RED_SCALE = 0x801C, + GL_POST_CONVOLUTION_RED_SCALE_EXT = 0x801C, + GL_POST_CONVOLUTION_GREEN_SCALE = 0x801D, + GL_POST_CONVOLUTION_GREEN_SCALE_EXT = 0x801D, + GL_POST_CONVOLUTION_BLUE_SCALE = 0x801E, + GL_POST_CONVOLUTION_BLUE_SCALE_EXT = 0x801E, + GL_POST_CONVOLUTION_ALPHA_SCALE = 0x801F, + GL_POST_CONVOLUTION_ALPHA_SCALE_EXT = 0x801F, + GL_POST_CONVOLUTION_RED_BIAS = 0x8020, + GL_POST_CONVOLUTION_RED_BIAS_EXT = 0x8020, + GL_POST_CONVOLUTION_GREEN_BIAS = 0x8021, + GL_POST_CONVOLUTION_GREEN_BIAS_EXT = 0x8021, + GL_POST_CONVOLUTION_BLUE_BIAS = 0x8022, + GL_POST_CONVOLUTION_BLUE_BIAS_EXT = 0x8022, + GL_POST_CONVOLUTION_ALPHA_BIAS = 0x8023, + GL_POST_CONVOLUTION_ALPHA_BIAS_EXT = 0x8023, + GL_HISTOGRAM = 0x8024, + GL_HISTOGRAM_EXT = 0x8024, + GL_PROXY_HISTOGRAM = 0x8025, + GL_PROXY_HISTOGRAM_EXT = 0x8025, + GL_HISTOGRAM_WIDTH = 0x8026, + GL_HISTOGRAM_WIDTH_EXT = 0x8026, + GL_HISTOGRAM_FORMAT = 0x8027, + GL_HISTOGRAM_FORMAT_EXT = 0x8027, + GL_HISTOGRAM_RED_SIZE = 0x8028, + GL_HISTOGRAM_RED_SIZE_EXT = 0x8028, + GL_HISTOGRAM_GREEN_SIZE = 0x8029, + GL_HISTOGRAM_GREEN_SIZE_EXT = 0x8029, + GL_HISTOGRAM_BLUE_SIZE = 0x802A, + GL_HISTOGRAM_BLUE_SIZE_EXT = 0x802A, + GL_HISTOGRAM_ALPHA_SIZE = 0x802B, + GL_HISTOGRAM_ALPHA_SIZE_EXT = 0x802B, + GL_HISTOGRAM_LUMINANCE_SIZE = 0x802C, + GL_HISTOGRAM_LUMINANCE_SIZE_EXT = 0x802C, + GL_HISTOGRAM_SINK = 0x802D, + GL_HISTOGRAM_SINK_EXT = 0x802D, + GL_MINMAX = 0x802E, + GL_MINMAX_EXT = 0x802E, + GL_MINMAX_FORMAT = 0x802F, + GL_MINMAX_FORMAT_EXT = 0x802F, + GL_MINMAX_SINK = 0x8030, + GL_MINMAX_SINK_EXT = 0x8030, + GL_TABLE_TOO_LARGE_EXT = 0x8031, + GL_TABLE_TOO_LARGE = 0x8031, + GL_UNSIGNED_BYTE_3_3_2 = 0x8032, + GL_UNSIGNED_BYTE_3_3_2_EXT = 0x8032, + GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033, + GL_UNSIGNED_SHORT_4_4_4_4_EXT = 0x8033, + GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034, + GL_UNSIGNED_SHORT_5_5_5_1_EXT = 0x8034, + GL_UNSIGNED_INT_8_8_8_8 = 0x8035, + GL_UNSIGNED_INT_8_8_8_8_EXT = 0x8035, + GL_UNSIGNED_INT_10_10_10_2 = 0x8036, + GL_UNSIGNED_INT_10_10_10_2_EXT = 0x8036, + GL_POLYGON_OFFSET_EXT = 0x8037, + GL_POLYGON_OFFSET_FILL = 0x8037, + GL_POLYGON_OFFSET_FACTOR = 0x8038, + GL_POLYGON_OFFSET_FACTOR_EXT = 0x8038, + GL_POLYGON_OFFSET_BIAS_EXT = 0x8039, + GL_RESCALE_NORMAL = 0x803A, + GL_RESCALE_NORMAL_EXT = 0x803A, + GL_ALPHA4 = 0x803B, + GL_ALPHA4_EXT = 0x803B, + GL_ALPHA8 = 0x803C, + GL_ALPHA8_EXT = 0x803C, + GL_ALPHA8_OES = 0x803C, + GL_ALPHA12 = 0x803D, + GL_ALPHA12_EXT = 0x803D, + GL_ALPHA16 = 0x803E, + GL_ALPHA16_EXT = 0x803E, + GL_LUMINANCE4 = 0x803F, + GL_LUMINANCE4_EXT = 0x803F, + GL_LUMINANCE8 = 0x8040, + GL_LUMINANCE8_EXT = 0x8040, + GL_LUMINANCE8_OES = 0x8040, + GL_LUMINANCE12 = 0x8041, + GL_LUMINANCE12_EXT = 0x8041, + GL_LUMINANCE16 = 0x8042, + GL_LUMINANCE16_EXT = 0x8042, + GL_LUMINANCE4_ALPHA4 = 0x8043, + GL_LUMINANCE4_ALPHA4_EXT = 0x8043, + GL_LUMINANCE4_ALPHA4_OES = 0x8043, + GL_LUMINANCE6_ALPHA2 = 0x8044, + GL_LUMINANCE6_ALPHA2_EXT = 0x8044, + GL_LUMINANCE8_ALPHA8 = 0x8045, + GL_LUMINANCE8_ALPHA8_EXT = 0x8045, + GL_LUMINANCE8_ALPHA8_OES = 0x8045, + GL_LUMINANCE12_ALPHA4 = 0x8046, + GL_LUMINANCE12_ALPHA4_EXT = 0x8046, + GL_LUMINANCE12_ALPHA12 = 0x8047, + GL_LUMINANCE12_ALPHA12_EXT = 0x8047, + GL_LUMINANCE16_ALPHA16 = 0x8048, + GL_LUMINANCE16_ALPHA16_EXT = 0x8048, + GL_INTENSITY = 0x8049, + GL_INTENSITY_EXT = 0x8049, + GL_INTENSITY4 = 0x804A, + GL_INTENSITY4_EXT = 0x804A, + GL_INTENSITY8 = 0x804B, + GL_INTENSITY8_EXT = 0x804B, + GL_INTENSITY12 = 0x804C, + GL_INTENSITY12_EXT = 0x804C, + GL_INTENSITY16 = 0x804D, + GL_INTENSITY16_EXT = 0x804D, + GL_RGB2_EXT = 0x804E, + GL_RGB4 = 0x804F, + GL_RGB4_EXT = 0x804F, + GL_RGB5 = 0x8050, + GL_RGB5_EXT = 0x8050, + GL_RGB8 = 0x8051, + GL_RGB8_EXT = 0x8051, + GL_RGB8_OES = 0x8051, + GL_RGB10 = 0x8052, + GL_RGB10_EXT = 0x8052, + GL_RGB12 = 0x8053, + GL_RGB12_EXT = 0x8053, + GL_RGB16 = 0x8054, + GL_RGB16_EXT = 0x8054, + GL_RGBA2 = 0x8055, + GL_RGBA2_EXT = 0x8055, + GL_RGBA4 = 0x8056, + GL_RGBA4_EXT = 0x8056, + GL_RGBA4_OES = 0x8056, + GL_RGB5_A1 = 0x8057, + GL_RGB5_A1_EXT = 0x8057, + GL_RGB5_A1_OES = 0x8057, + GL_RGBA8 = 0x8058, + GL_RGBA8_EXT = 0x8058, + GL_RGBA8_OES = 0x8058, + GL_RGB10_A2 = 0x8059, + GL_RGB10_A2_EXT = 0x8059, + GL_RGBA12 = 0x805A, + GL_RGBA12_EXT = 0x805A, + GL_RGBA16 = 0x805B, + GL_RGBA16_EXT = 0x805B, + GL_TEXTURE_RED_SIZE = 0x805C, + GL_TEXTURE_RED_SIZE_EXT = 0x805C, + GL_TEXTURE_GREEN_SIZE = 0x805D, + GL_TEXTURE_GREEN_SIZE_EXT = 0x805D, + GL_TEXTURE_BLUE_SIZE = 0x805E, + GL_TEXTURE_BLUE_SIZE_EXT = 0x805E, + GL_TEXTURE_ALPHA_SIZE = 0x805F, + GL_TEXTURE_ALPHA_SIZE_EXT = 0x805F, + GL_TEXTURE_LUMINANCE_SIZE = 0x8060, + GL_TEXTURE_LUMINANCE_SIZE_EXT = 0x8060, + GL_TEXTURE_INTENSITY_SIZE = 0x8061, + GL_TEXTURE_INTENSITY_SIZE_EXT = 0x8061, + GL_REPLACE_EXT = 0x8062, + GL_PROXY_TEXTURE_1D = 0x8063, + GL_PROXY_TEXTURE_1D_EXT = 0x8063, + GL_PROXY_TEXTURE_2D = 0x8064, + GL_PROXY_TEXTURE_2D_EXT = 0x8064, + GL_TEXTURE_TOO_LARGE_EXT = 0x8065, + GL_TEXTURE_PRIORITY = 0x8066, + GL_TEXTURE_PRIORITY_EXT = 0x8066, + GL_TEXTURE_RESIDENT = 0x8067, + GL_TEXTURE_RESIDENT_EXT = 0x8067, + GL_TEXTURE_1D_BINDING_EXT = 0x8068, + GL_TEXTURE_BINDING_1D = 0x8068, + GL_TEXTURE_2D_BINDING_EXT = 0x8069, + GL_TEXTURE_BINDING_2D = 0x8069, + GL_TEXTURE_3D_BINDING_EXT = 0x806A, + GL_TEXTURE_3D_BINDING_OES = 0x806A, + GL_TEXTURE_BINDING_3D = 0x806A, + GL_TEXTURE_BINDING_3D_OES = 0x806A, + GL_PACK_SKIP_IMAGES = 0x806B, + GL_PACK_SKIP_IMAGES_EXT = 0x806B, + GL_PACK_IMAGE_HEIGHT = 0x806C, + GL_PACK_IMAGE_HEIGHT_EXT = 0x806C, + GL_UNPACK_SKIP_IMAGES = 0x806D, + GL_UNPACK_SKIP_IMAGES_EXT = 0x806D, + GL_UNPACK_IMAGE_HEIGHT = 0x806E, + GL_UNPACK_IMAGE_HEIGHT_EXT = 0x806E, + GL_TEXTURE_3D = 0x806F, + GL_TEXTURE_3D_EXT = 0x806F, + GL_TEXTURE_3D_OES = 0x806F, + GL_PROXY_TEXTURE_3D = 0x8070, + GL_PROXY_TEXTURE_3D_EXT = 0x8070, + GL_TEXTURE_DEPTH = 0x8071, + GL_TEXTURE_DEPTH_EXT = 0x8071, + GL_TEXTURE_WRAP_R = 0x8072, + GL_TEXTURE_WRAP_R_EXT = 0x8072, + GL_TEXTURE_WRAP_R_OES = 0x8072, + GL_MAX_3D_TEXTURE_SIZE = 0x8073, + GL_MAX_3D_TEXTURE_SIZE_EXT = 0x8073, + GL_MAX_3D_TEXTURE_SIZE_OES = 0x8073, + GL_VERTEX_ARRAY = 0x8074, + GL_VERTEX_ARRAY_EXT = 0x8074, + GL_VERTEX_ARRAY_KHR = 0x8074, + GL_NORMAL_ARRAY = 0x8075, + GL_NORMAL_ARRAY_EXT = 0x8075, + GL_COLOR_ARRAY = 0x8076, + GL_COLOR_ARRAY_EXT = 0x8076, + GL_INDEX_ARRAY = 0x8077, + GL_INDEX_ARRAY_EXT = 0x8077, + GL_TEXTURE_COORD_ARRAY = 0x8078, + GL_TEXTURE_COORD_ARRAY_EXT = 0x8078, + GL_EDGE_FLAG_ARRAY = 0x8079, + GL_EDGE_FLAG_ARRAY_EXT = 0x8079, + GL_VERTEX_ARRAY_SIZE = 0x807A, + GL_VERTEX_ARRAY_SIZE_EXT = 0x807A, + GL_VERTEX_ARRAY_TYPE = 0x807B, + GL_VERTEX_ARRAY_TYPE_EXT = 0x807B, + GL_VERTEX_ARRAY_STRIDE = 0x807C, + GL_VERTEX_ARRAY_STRIDE_EXT = 0x807C, + GL_VERTEX_ARRAY_COUNT_EXT = 0x807D, + GL_NORMAL_ARRAY_TYPE = 0x807E, + GL_NORMAL_ARRAY_TYPE_EXT = 0x807E, + GL_NORMAL_ARRAY_STRIDE = 0x807F, + GL_NORMAL_ARRAY_STRIDE_EXT = 0x807F, + GL_NORMAL_ARRAY_COUNT_EXT = 0x8080, + GL_COLOR_ARRAY_SIZE = 0x8081, + GL_COLOR_ARRAY_SIZE_EXT = 0x8081, + GL_COLOR_ARRAY_TYPE = 0x8082, + GL_COLOR_ARRAY_TYPE_EXT = 0x8082, + GL_COLOR_ARRAY_STRIDE = 0x8083, + GL_COLOR_ARRAY_STRIDE_EXT = 0x8083, + GL_COLOR_ARRAY_COUNT_EXT = 0x8084, + GL_INDEX_ARRAY_TYPE = 0x8085, + GL_INDEX_ARRAY_TYPE_EXT = 0x8085, + GL_INDEX_ARRAY_STRIDE = 0x8086, + GL_INDEX_ARRAY_STRIDE_EXT = 0x8086, + GL_INDEX_ARRAY_COUNT_EXT = 0x8087, + GL_TEXTURE_COORD_ARRAY_SIZE = 0x8088, + GL_TEXTURE_COORD_ARRAY_SIZE_EXT = 0x8088, + GL_TEXTURE_COORD_ARRAY_TYPE = 0x8089, + GL_TEXTURE_COORD_ARRAY_TYPE_EXT = 0x8089, + GL_TEXTURE_COORD_ARRAY_STRIDE = 0x808A, + GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = 0x808A, + GL_TEXTURE_COORD_ARRAY_COUNT_EXT = 0x808B, + GL_EDGE_FLAG_ARRAY_STRIDE = 0x808C, + GL_EDGE_FLAG_ARRAY_STRIDE_EXT = 0x808C, + GL_EDGE_FLAG_ARRAY_COUNT_EXT = 0x808D, + GL_VERTEX_ARRAY_POINTER = 0x808E, + GL_VERTEX_ARRAY_POINTER_EXT = 0x808E, + GL_NORMAL_ARRAY_POINTER = 0x808F, + GL_NORMAL_ARRAY_POINTER_EXT = 0x808F, + GL_COLOR_ARRAY_POINTER = 0x8090, + GL_COLOR_ARRAY_POINTER_EXT = 0x8090, + GL_INDEX_ARRAY_POINTER = 0x8091, + GL_INDEX_ARRAY_POINTER_EXT = 0x8091, + GL_TEXTURE_COORD_ARRAY_POINTER = 0x8092, + GL_TEXTURE_COORD_ARRAY_POINTER_EXT = 0x8092, + GL_EDGE_FLAG_ARRAY_POINTER = 0x8093, + GL_EDGE_FLAG_ARRAY_POINTER_EXT = 0x8093, + GL_INTERLACE_SGIX = 0x8094, + GL_DETAIL_TEXTURE_2D_SGIS = 0x8095, + GL_DETAIL_TEXTURE_2D_BINDING_SGIS = 0x8096, + GL_LINEAR_DETAIL_SGIS = 0x8097, + GL_LINEAR_DETAIL_ALPHA_SGIS = 0x8098, + GL_LINEAR_DETAIL_COLOR_SGIS = 0x8099, + GL_DETAIL_TEXTURE_LEVEL_SGIS = 0x809A, + GL_DETAIL_TEXTURE_MODE_SGIS = 0x809B, + GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS = 0x809C, + GL_MULTISAMPLE = 0x809D, + GL_MULTISAMPLE_ARB = 0x809D, + GL_MULTISAMPLE_EXT = 0x809D, + GL_MULTISAMPLE_SGIS = 0x809D, + GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E, + GL_SAMPLE_ALPHA_TO_COVERAGE_ARB = 0x809E, + GL_SAMPLE_ALPHA_TO_MASK_EXT = 0x809E, + GL_SAMPLE_ALPHA_TO_MASK_SGIS = 0x809E, + GL_SAMPLE_ALPHA_TO_ONE = 0x809F, + GL_SAMPLE_ALPHA_TO_ONE_ARB = 0x809F, + GL_SAMPLE_ALPHA_TO_ONE_EXT = 0x809F, + GL_SAMPLE_ALPHA_TO_ONE_SGIS = 0x809F, + GL_SAMPLE_COVERAGE = 0x80A0, + GL_SAMPLE_COVERAGE_ARB = 0x80A0, + GL_SAMPLE_MASK_EXT = 0x80A0, + GL_SAMPLE_MASK_SGIS = 0x80A0, + GL_1PASS_EXT = 0x80A1, + GL_1PASS_SGIS = 0x80A1, + GL_2PASS_0_EXT = 0x80A2, + GL_2PASS_0_SGIS = 0x80A2, + GL_2PASS_1_EXT = 0x80A3, + GL_2PASS_1_SGIS = 0x80A3, + GL_4PASS_0_EXT = 0x80A4, + GL_4PASS_0_SGIS = 0x80A4, + GL_4PASS_1_EXT = 0x80A5, + GL_4PASS_1_SGIS = 0x80A5, + GL_4PASS_2_EXT = 0x80A6, + GL_4PASS_2_SGIS = 0x80A6, + GL_4PASS_3_EXT = 0x80A7, + GL_4PASS_3_SGIS = 0x80A7, + GL_SAMPLE_BUFFERS = 0x80A8, + GL_SAMPLE_BUFFERS_ARB = 0x80A8, + GL_SAMPLE_BUFFERS_EXT = 0x80A8, + GL_SAMPLE_BUFFERS_SGIS = 0x80A8, + GL_SAMPLES = 0x80A9, + GL_SAMPLES_ARB = 0x80A9, + GL_SAMPLES_EXT = 0x80A9, + GL_SAMPLES_SGIS = 0x80A9, + GL_SAMPLE_COVERAGE_VALUE = 0x80AA, + GL_SAMPLE_COVERAGE_VALUE_ARB = 0x80AA, + GL_SAMPLE_MASK_VALUE_EXT = 0x80AA, + GL_SAMPLE_MASK_VALUE_SGIS = 0x80AA, + GL_SAMPLE_COVERAGE_INVERT = 0x80AB, + GL_SAMPLE_COVERAGE_INVERT_ARB = 0x80AB, + GL_SAMPLE_MASK_INVERT_EXT = 0x80AB, + GL_SAMPLE_MASK_INVERT_SGIS = 0x80AB, + GL_SAMPLE_PATTERN_EXT = 0x80AC, + GL_SAMPLE_PATTERN_SGIS = 0x80AC, + GL_LINEAR_SHARPEN_SGIS = 0x80AD, + GL_LINEAR_SHARPEN_ALPHA_SGIS = 0x80AE, + GL_LINEAR_SHARPEN_COLOR_SGIS = 0x80AF, + GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS = 0x80B0, + GL_COLOR_MATRIX = 0x80B1, + GL_COLOR_MATRIX_SGI = 0x80B1, + GL_COLOR_MATRIX_STACK_DEPTH = 0x80B2, + GL_COLOR_MATRIX_STACK_DEPTH_SGI = 0x80B2, + GL_MAX_COLOR_MATRIX_STACK_DEPTH = 0x80B3, + GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = 0x80B3, + GL_POST_COLOR_MATRIX_RED_SCALE = 0x80B4, + GL_POST_COLOR_MATRIX_RED_SCALE_SGI = 0x80B4, + GL_POST_COLOR_MATRIX_GREEN_SCALE = 0x80B5, + GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = 0x80B5, + GL_POST_COLOR_MATRIX_BLUE_SCALE = 0x80B6, + GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = 0x80B6, + GL_POST_COLOR_MATRIX_ALPHA_SCALE = 0x80B7, + GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = 0x80B7, + GL_POST_COLOR_MATRIX_RED_BIAS = 0x80B8, + GL_POST_COLOR_MATRIX_RED_BIAS_SGI = 0x80B8, + GL_POST_COLOR_MATRIX_GREEN_BIAS = 0x80B9, + GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = 0x80B9, + GL_POST_COLOR_MATRIX_BLUE_BIAS = 0x80BA, + GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = 0x80BA, + GL_POST_COLOR_MATRIX_ALPHA_BIAS = 0x80BB, + GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = 0x80BB, + GL_TEXTURE_COLOR_TABLE_SGI = 0x80BC, + GL_PROXY_TEXTURE_COLOR_TABLE_SGI = 0x80BD, + GL_TEXTURE_ENV_BIAS_SGIX = 0x80BE, + GL_SHADOW_AMBIENT_SGIX = 0x80BF, + GL_TEXTURE_COMPARE_FAIL_VALUE_ARB = 0x80BF, + GL_BLEND_DST_RGB = 0x80C8, + GL_BLEND_DST_RGB_EXT = 0x80C8, + GL_BLEND_DST_RGB_OES = 0x80C8, + GL_BLEND_SRC_RGB = 0x80C9, + GL_BLEND_SRC_RGB_EXT = 0x80C9, + GL_BLEND_SRC_RGB_OES = 0x80C9, + GL_BLEND_DST_ALPHA = 0x80CA, + GL_BLEND_DST_ALPHA_EXT = 0x80CA, + GL_BLEND_DST_ALPHA_OES = 0x80CA, + GL_BLEND_SRC_ALPHA = 0x80CB, + GL_BLEND_SRC_ALPHA_EXT = 0x80CB, + GL_BLEND_SRC_ALPHA_OES = 0x80CB, + GL_422_EXT = 0x80CC, + GL_422_REV_EXT = 0x80CD, + GL_422_AVERAGE_EXT = 0x80CE, + GL_422_REV_AVERAGE_EXT = 0x80CF, + GL_COLOR_TABLE = 0x80D0, + GL_COLOR_TABLE_SGI = 0x80D0, + GL_POST_CONVOLUTION_COLOR_TABLE = 0x80D1, + GL_POST_CONVOLUTION_COLOR_TABLE_SGI = 0x80D1, + GL_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D2, + GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = 0x80D2, + GL_PROXY_COLOR_TABLE = 0x80D3, + GL_PROXY_COLOR_TABLE_SGI = 0x80D3, + GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = 0x80D4, + GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = 0x80D4, + GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D5, + GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = 0x80D5, + GL_COLOR_TABLE_SCALE = 0x80D6, + GL_COLOR_TABLE_SCALE_SGI = 0x80D6, + GL_COLOR_TABLE_BIAS = 0x80D7, + GL_COLOR_TABLE_BIAS_SGI = 0x80D7, + GL_COLOR_TABLE_FORMAT = 0x80D8, + GL_COLOR_TABLE_FORMAT_SGI = 0x80D8, + GL_COLOR_TABLE_WIDTH = 0x80D9, + GL_COLOR_TABLE_WIDTH_SGI = 0x80D9, + GL_COLOR_TABLE_RED_SIZE = 0x80DA, + GL_COLOR_TABLE_RED_SIZE_SGI = 0x80DA, + GL_COLOR_TABLE_GREEN_SIZE = 0x80DB, + GL_COLOR_TABLE_GREEN_SIZE_SGI = 0x80DB, + GL_COLOR_TABLE_BLUE_SIZE = 0x80DC, + GL_COLOR_TABLE_BLUE_SIZE_SGI = 0x80DC, + GL_COLOR_TABLE_ALPHA_SIZE = 0x80DD, + GL_COLOR_TABLE_ALPHA_SIZE_SGI = 0x80DD, + GL_COLOR_TABLE_LUMINANCE_SIZE = 0x80DE, + GL_COLOR_TABLE_LUMINANCE_SIZE_SGI = 0x80DE, + GL_COLOR_TABLE_INTENSITY_SIZE = 0x80DF, + GL_COLOR_TABLE_INTENSITY_SIZE_SGI = 0x80DF, + GL_BGR = 0x80E0, + GL_BGR_EXT = 0x80E0, + GL_BGRA = 0x80E1, + GL_BGRA_EXT = 0x80E1, + GL_BGRA_IMG = 0x80E1, + GL_COLOR_INDEX1_EXT = 0x80E2, + GL_COLOR_INDEX2_EXT = 0x80E3, + GL_COLOR_INDEX4_EXT = 0x80E4, + GL_COLOR_INDEX8_EXT = 0x80E5, + GL_COLOR_INDEX12_EXT = 0x80E6, + GL_COLOR_INDEX16_EXT = 0x80E7, + GL_MAX_ELEMENTS_VERTICES = 0x80E8, + GL_MAX_ELEMENTS_VERTICES_EXT = 0x80E8, + GL_MAX_ELEMENTS_INDICES = 0x80E9, + GL_MAX_ELEMENTS_INDICES_EXT = 0x80E9, + GL_PHONG_WIN = 0x80EA, + GL_PHONG_HINT_WIN = 0x80EB, + GL_FOG_SPECULAR_TEXTURE_WIN = 0x80EC, + GL_TEXTURE_INDEX_SIZE_EXT = 0x80ED, + GL_PARAMETER_BUFFER = 0x80EE, + GL_PARAMETER_BUFFER_ARB = 0x80EE, + GL_PARAMETER_BUFFER_BINDING = 0x80EF, + GL_PARAMETER_BUFFER_BINDING_ARB = 0x80EF, + GL_CLIP_VOLUME_CLIPPING_HINT_EXT = 0x80F0, + GL_DUAL_ALPHA4_SGIS = 0x8110, + GL_DUAL_ALPHA8_SGIS = 0x8111, + GL_DUAL_ALPHA12_SGIS = 0x8112, + GL_DUAL_ALPHA16_SGIS = 0x8113, + GL_DUAL_LUMINANCE4_SGIS = 0x8114, + GL_DUAL_LUMINANCE8_SGIS = 0x8115, + GL_DUAL_LUMINANCE12_SGIS = 0x8116, + GL_DUAL_LUMINANCE16_SGIS = 0x8117, + GL_DUAL_INTENSITY4_SGIS = 0x8118, + GL_DUAL_INTENSITY8_SGIS = 0x8119, + GL_DUAL_INTENSITY12_SGIS = 0x811A, + GL_DUAL_INTENSITY16_SGIS = 0x811B, + GL_DUAL_LUMINANCE_ALPHA4_SGIS = 0x811C, + GL_DUAL_LUMINANCE_ALPHA8_SGIS = 0x811D, + GL_QUAD_ALPHA4_SGIS = 0x811E, + GL_QUAD_ALPHA8_SGIS = 0x811F, + GL_QUAD_LUMINANCE4_SGIS = 0x8120, + GL_QUAD_LUMINANCE8_SGIS = 0x8121, + GL_QUAD_INTENSITY4_SGIS = 0x8122, + GL_QUAD_INTENSITY8_SGIS = 0x8123, + GL_DUAL_TEXTURE_SELECT_SGIS = 0x8124, + GL_QUAD_TEXTURE_SELECT_SGIS = 0x8125, + GL_POINT_SIZE_MIN = 0x8126, + GL_POINT_SIZE_MIN_ARB = 0x8126, + GL_POINT_SIZE_MIN_EXT = 0x8126, + GL_POINT_SIZE_MIN_SGIS = 0x8126, + GL_POINT_SIZE_MAX = 0x8127, + GL_POINT_SIZE_MAX_ARB = 0x8127, + GL_POINT_SIZE_MAX_EXT = 0x8127, + GL_POINT_SIZE_MAX_SGIS = 0x8127, + GL_POINT_FADE_THRESHOLD_SIZE = 0x8128, + GL_POINT_FADE_THRESHOLD_SIZE_ARB = 0x8128, + GL_POINT_FADE_THRESHOLD_SIZE_EXT = 0x8128, + GL_POINT_FADE_THRESHOLD_SIZE_SGIS = 0x8128, + GL_DISTANCE_ATTENUATION_EXT = 0x8129, + GL_DISTANCE_ATTENUATION_SGIS = 0x8129, + GL_POINT_DISTANCE_ATTENUATION = 0x8129, + GL_POINT_DISTANCE_ATTENUATION_ARB = 0x8129, + GL_FOG_FUNC_SGIS = 0x812A, + GL_FOG_FUNC_POINTS_SGIS = 0x812B, + GL_MAX_FOG_FUNC_POINTS_SGIS = 0x812C, + GL_CLAMP_TO_BORDER = 0x812D, + GL_CLAMP_TO_BORDER_ARB = 0x812D, + GL_CLAMP_TO_BORDER_EXT = 0x812D, + GL_CLAMP_TO_BORDER_NV = 0x812D, + GL_CLAMP_TO_BORDER_SGIS = 0x812D, + GL_CLAMP_TO_BORDER_OES = 0x812D, + GL_TEXTURE_MULTI_BUFFER_HINT_SGIX = 0x812E, + GL_CLAMP_TO_EDGE = 0x812F, + GL_CLAMP_TO_EDGE_SGIS = 0x812F, + GL_PACK_SKIP_VOLUMES_SGIS = 0x8130, + GL_PACK_IMAGE_DEPTH_SGIS = 0x8131, + GL_UNPACK_SKIP_VOLUMES_SGIS = 0x8132, + GL_UNPACK_IMAGE_DEPTH_SGIS = 0x8133, + GL_TEXTURE_4D_SGIS = 0x8134, + GL_PROXY_TEXTURE_4D_SGIS = 0x8135, + GL_TEXTURE_4DSIZE_SGIS = 0x8136, + GL_TEXTURE_WRAP_Q_SGIS = 0x8137, + GL_MAX_4D_TEXTURE_SIZE_SGIS = 0x8138, + GL_PIXEL_TEX_GEN_SGIX = 0x8139, + GL_TEXTURE_MIN_LOD = 0x813A, + GL_TEXTURE_MIN_LOD_SGIS = 0x813A, + GL_TEXTURE_MAX_LOD = 0x813B, + GL_TEXTURE_MAX_LOD_SGIS = 0x813B, + GL_TEXTURE_BASE_LEVEL = 0x813C, + GL_TEXTURE_BASE_LEVEL_SGIS = 0x813C, + GL_TEXTURE_MAX_LEVEL = 0x813D, + GL_TEXTURE_MAX_LEVEL_APPLE = 0x813D, + GL_TEXTURE_MAX_LEVEL_SGIS = 0x813D, + GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX = 0x813E, + GL_PIXEL_TILE_CACHE_INCREMENT_SGIX = 0x813F, + GL_PIXEL_TILE_WIDTH_SGIX = 0x8140, + GL_PIXEL_TILE_HEIGHT_SGIX = 0x8141, + GL_PIXEL_TILE_GRID_WIDTH_SGIX = 0x8142, + GL_PIXEL_TILE_GRID_HEIGHT_SGIX = 0x8143, + GL_PIXEL_TILE_GRID_DEPTH_SGIX = 0x8144, + GL_PIXEL_TILE_CACHE_SIZE_SGIX = 0x8145, + GL_FILTER4_SGIS = 0x8146, + GL_TEXTURE_FILTER4_SIZE_SGIS = 0x8147, + GL_SPRITE_SGIX = 0x8148, + GL_SPRITE_MODE_SGIX = 0x8149, + GL_SPRITE_AXIS_SGIX = 0x814A, + GL_SPRITE_TRANSLATION_SGIX = 0x814B, + GL_SPRITE_AXIAL_SGIX = 0x814C, + GL_SPRITE_OBJECT_ALIGNED_SGIX = 0x814D, + GL_SPRITE_EYE_ALIGNED_SGIX = 0x814E, + GL_TEXTURE_4D_BINDING_SGIS = 0x814F, + GL_IGNORE_BORDER_HP = 0x8150, + GL_CONSTANT_BORDER = 0x8151, + GL_CONSTANT_BORDER_HP = 0x8151, + GL_REPLICATE_BORDER = 0x8153, + GL_REPLICATE_BORDER_HP = 0x8153, + GL_CONVOLUTION_BORDER_COLOR = 0x8154, + GL_CONVOLUTION_BORDER_COLOR_HP = 0x8154, + GL_IMAGE_SCALE_X_HP = 0x8155, + GL_IMAGE_SCALE_Y_HP = 0x8156, + GL_IMAGE_TRANSLATE_X_HP = 0x8157, + GL_IMAGE_TRANSLATE_Y_HP = 0x8158, + GL_IMAGE_ROTATE_ANGLE_HP = 0x8159, + GL_IMAGE_ROTATE_ORIGIN_X_HP = 0x815A, + GL_IMAGE_ROTATE_ORIGIN_Y_HP = 0x815B, + GL_IMAGE_MAG_FILTER_HP = 0x815C, + GL_IMAGE_MIN_FILTER_HP = 0x815D, + GL_IMAGE_CUBIC_WEIGHT_HP = 0x815E, + GL_CUBIC_HP = 0x815F, + GL_AVERAGE_HP = 0x8160, + GL_IMAGE_TRANSFORM_2D_HP = 0x8161, + GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = 0x8162, + GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = 0x8163, + GL_OCCLUSION_TEST_HP = 0x8165, + GL_OCCLUSION_TEST_RESULT_HP = 0x8166, + GL_TEXTURE_LIGHTING_MODE_HP = 0x8167, + GL_TEXTURE_POST_SPECULAR_HP = 0x8168, + GL_TEXTURE_PRE_SPECULAR_HP = 0x8169, + GL_LINEAR_CLIPMAP_LINEAR_SGIX = 0x8170, + GL_TEXTURE_CLIPMAP_CENTER_SGIX = 0x8171, + GL_TEXTURE_CLIPMAP_FRAME_SGIX = 0x8172, + GL_TEXTURE_CLIPMAP_OFFSET_SGIX = 0x8173, + GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX = 0x8174, + GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX = 0x8175, + GL_TEXTURE_CLIPMAP_DEPTH_SGIX = 0x8176, + GL_MAX_CLIPMAP_DEPTH_SGIX = 0x8177, + GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX = 0x8178, + GL_POST_TEXTURE_FILTER_BIAS_SGIX = 0x8179, + GL_POST_TEXTURE_FILTER_SCALE_SGIX = 0x817A, + GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX = 0x817B, + GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX = 0x817C, + GL_REFERENCE_PLANE_SGIX = 0x817D, + GL_REFERENCE_PLANE_EQUATION_SGIX = 0x817E, + GL_IR_INSTRUMENT1_SGIX = 0x817F, + GL_INSTRUMENT_BUFFER_POINTER_SGIX = 0x8180, + GL_INSTRUMENT_MEASUREMENTS_SGIX = 0x8181, + GL_LIST_PRIORITY_SGIX = 0x8182, + GL_CALLIGRAPHIC_FRAGMENT_SGIX = 0x8183, + GL_PIXEL_TEX_GEN_Q_CEILING_SGIX = 0x8184, + GL_PIXEL_TEX_GEN_Q_ROUND_SGIX = 0x8185, + GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX = 0x8186, + GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX = 0x8187, + GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX = 0x8188, + GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX = 0x8189, + GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX = 0x818A, + GL_FRAMEZOOM_SGIX = 0x818B, + GL_FRAMEZOOM_FACTOR_SGIX = 0x818C, + GL_MAX_FRAMEZOOM_FACTOR_SGIX = 0x818D, + GL_TEXTURE_LOD_BIAS_S_SGIX = 0x818E, + GL_TEXTURE_LOD_BIAS_T_SGIX = 0x818F, + GL_TEXTURE_LOD_BIAS_R_SGIX = 0x8190, + GL_GENERATE_MIPMAP = 0x8191, + GL_GENERATE_MIPMAP_SGIS = 0x8191, + GL_GENERATE_MIPMAP_HINT = 0x8192, + GL_GENERATE_MIPMAP_HINT_SGIS = 0x8192, + GL_GEOMETRY_DEFORMATION_SGIX = 0x8194, + GL_TEXTURE_DEFORMATION_SGIX = 0x8195, + GL_DEFORMATIONS_MASK_SGIX = 0x8196, + GL_MAX_DEFORMATION_ORDER_SGIX = 0x8197, + GL_FOG_OFFSET_SGIX = 0x8198, + GL_FOG_OFFSET_VALUE_SGIX = 0x8199, + GL_TEXTURE_COMPARE_SGIX = 0x819A, + GL_TEXTURE_COMPARE_OPERATOR_SGIX = 0x819B, + GL_TEXTURE_LEQUAL_R_SGIX = 0x819C, + GL_TEXTURE_GEQUAL_R_SGIX = 0x819D, + GL_DEPTH_COMPONENT16 = 0x81A5, + GL_DEPTH_COMPONENT16_ARB = 0x81A5, + GL_DEPTH_COMPONENT16_OES = 0x81A5, + GL_DEPTH_COMPONENT16_SGIX = 0x81A5, + GL_DEPTH_COMPONENT24 = 0x81A6, + GL_DEPTH_COMPONENT24_ARB = 0x81A6, + GL_DEPTH_COMPONENT24_OES = 0x81A6, + GL_DEPTH_COMPONENT24_SGIX = 0x81A6, + GL_DEPTH_COMPONENT32 = 0x81A7, + GL_DEPTH_COMPONENT32_ARB = 0x81A7, + GL_DEPTH_COMPONENT32_OES = 0x81A7, + GL_DEPTH_COMPONENT32_SGIX = 0x81A7, + GL_ARRAY_ELEMENT_LOCK_FIRST_EXT = 0x81A8, + GL_ARRAY_ELEMENT_LOCK_COUNT_EXT = 0x81A9, + GL_CULL_VERTEX_EXT = 0x81AA, + GL_CULL_VERTEX_EYE_POSITION_EXT = 0x81AB, + GL_CULL_VERTEX_OBJECT_POSITION_EXT = 0x81AC, + GL_IUI_V2F_EXT = 0x81AD, + GL_IUI_V3F_EXT = 0x81AE, + GL_IUI_N3F_V2F_EXT = 0x81AF, + GL_IUI_N3F_V3F_EXT = 0x81B0, + GL_T2F_IUI_V2F_EXT = 0x81B1, + GL_T2F_IUI_V3F_EXT = 0x81B2, + GL_T2F_IUI_N3F_V2F_EXT = 0x81B3, + GL_T2F_IUI_N3F_V3F_EXT = 0x81B4, + GL_INDEX_TEST_EXT = 0x81B5, + GL_INDEX_TEST_FUNC_EXT = 0x81B6, + GL_INDEX_TEST_REF_EXT = 0x81B7, + GL_INDEX_MATERIAL_EXT = 0x81B8, + GL_INDEX_MATERIAL_PARAMETER_EXT = 0x81B9, + GL_INDEX_MATERIAL_FACE_EXT = 0x81BA, + GL_YCRCB_422_SGIX = 0x81BB, + GL_YCRCB_444_SGIX = 0x81BC, + GL_WRAP_BORDER_SUN = 0x81D4, + GL_UNPACK_CONSTANT_DATA_SUNX = 0x81D5, + GL_TEXTURE_CONSTANT_DATA_SUNX = 0x81D6, + GL_TRIANGLE_LIST_SUN = 0x81D7, + GL_REPLACEMENT_CODE_SUN = 0x81D8, + GL_GLOBAL_ALPHA_SUN = 0x81D9, + GL_GLOBAL_ALPHA_FACTOR_SUN = 0x81DA, + GL_TEXTURE_COLOR_WRITEMASK_SGIS = 0x81EF, + GL_EYE_DISTANCE_TO_POINT_SGIS = 0x81F0, + GL_OBJECT_DISTANCE_TO_POINT_SGIS = 0x81F1, + GL_EYE_DISTANCE_TO_LINE_SGIS = 0x81F2, + GL_OBJECT_DISTANCE_TO_LINE_SGIS = 0x81F3, + GL_EYE_POINT_SGIS = 0x81F4, + GL_OBJECT_POINT_SGIS = 0x81F5, + GL_EYE_LINE_SGIS = 0x81F6, + GL_OBJECT_LINE_SGIS = 0x81F7, + GL_LIGHT_MODEL_COLOR_CONTROL = 0x81F8, + GL_LIGHT_MODEL_COLOR_CONTROL_EXT = 0x81F8, + GL_SINGLE_COLOR = 0x81F9, + GL_SINGLE_COLOR_EXT = 0x81F9, + GL_SEPARATE_SPECULAR_COLOR = 0x81FA, + GL_SEPARATE_SPECULAR_COLOR_EXT = 0x81FA, + GL_SHARED_TEXTURE_PALETTE_EXT = 0x81FB, + GL_TEXT_FRAGMENT_SHADER_ATI = 0x8200, + GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210, + GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT = 0x8210, + GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211, + GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211, + GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212, + GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213, + GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217, + GL_FRAMEBUFFER_DEFAULT = 0x8218, + GL_FRAMEBUFFER_UNDEFINED = 0x8219, + GL_FRAMEBUFFER_UNDEFINED_OES = 0x8219, + GL_DEPTH_STENCIL_ATTACHMENT = 0x821A, + GL_MAJOR_VERSION = 0x821B, + GL_MINOR_VERSION = 0x821C, + GL_NUM_EXTENSIONS = 0x821D, + GL_CONTEXT_FLAGS = 0x821E, + GL_BUFFER_IMMUTABLE_STORAGE = 0x821F, + GL_BUFFER_IMMUTABLE_STORAGE_EXT = 0x821F, + GL_BUFFER_STORAGE_FLAGS = 0x8220, + GL_BUFFER_STORAGE_FLAGS_EXT = 0x8220, + GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED = 0x8221, + GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES = 0x8221, + GL_INDEX = 0x8222, + GL_COMPRESSED_RED = 0x8225, + GL_COMPRESSED_RG = 0x8226, + GL_RG = 0x8227, + GL_RG_EXT = 0x8227, + GL_RG_INTEGER = 0x8228, + GL_R8 = 0x8229, + GL_R8_EXT = 0x8229, + GL_R16 = 0x822A, + GL_R16_EXT = 0x822A, + GL_RG8 = 0x822B, + GL_RG8_EXT = 0x822B, + GL_RG16 = 0x822C, + GL_RG16_EXT = 0x822C, + GL_R16F = 0x822D, + GL_R16F_EXT = 0x822D, + GL_R32F = 0x822E, + GL_R32F_EXT = 0x822E, + GL_RG16F = 0x822F, + GL_RG16F_EXT = 0x822F, + GL_RG32F = 0x8230, + GL_RG32F_EXT = 0x8230, + GL_R8I = 0x8231, + GL_R8UI = 0x8232, + GL_R16I = 0x8233, + GL_R16UI = 0x8234, + GL_R32I = 0x8235, + GL_R32UI = 0x8236, + GL_RG8I = 0x8237, + GL_RG8UI = 0x8238, + GL_RG16I = 0x8239, + GL_RG16UI = 0x823A, + GL_RG32I = 0x823B, + GL_RG32UI = 0x823C, + GL_SYNC_CL_EVENT_ARB = 0x8240, + GL_SYNC_CL_EVENT_COMPLETE_ARB = 0x8241, + GL_DEBUG_OUTPUT_SYNCHRONOUS = 0x8242, + GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB = 0x8242, + GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR = 0x8242, + GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH = 0x8243, + GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB = 0x8243, + GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR = 0x8243, + GL_DEBUG_CALLBACK_FUNCTION = 0x8244, + GL_DEBUG_CALLBACK_FUNCTION_ARB = 0x8244, + GL_DEBUG_CALLBACK_FUNCTION_KHR = 0x8244, + GL_DEBUG_CALLBACK_USER_PARAM = 0x8245, + GL_DEBUG_CALLBACK_USER_PARAM_ARB = 0x8245, + GL_DEBUG_CALLBACK_USER_PARAM_KHR = 0x8245, + GL_DEBUG_SOURCE_API = 0x8246, + GL_DEBUG_SOURCE_API_ARB = 0x8246, + GL_DEBUG_SOURCE_API_KHR = 0x8246, + GL_DEBUG_SOURCE_WINDOW_SYSTEM = 0x8247, + GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB = 0x8247, + GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR = 0x8247, + GL_DEBUG_SOURCE_SHADER_COMPILER = 0x8248, + GL_DEBUG_SOURCE_SHADER_COMPILER_ARB = 0x8248, + GL_DEBUG_SOURCE_SHADER_COMPILER_KHR = 0x8248, + GL_DEBUG_SOURCE_THIRD_PARTY = 0x8249, + GL_DEBUG_SOURCE_THIRD_PARTY_ARB = 0x8249, + GL_DEBUG_SOURCE_THIRD_PARTY_KHR = 0x8249, + GL_DEBUG_SOURCE_APPLICATION = 0x824A, + GL_DEBUG_SOURCE_APPLICATION_ARB = 0x824A, + GL_DEBUG_SOURCE_APPLICATION_KHR = 0x824A, + GL_DEBUG_SOURCE_OTHER = 0x824B, + GL_DEBUG_SOURCE_OTHER_ARB = 0x824B, + GL_DEBUG_SOURCE_OTHER_KHR = 0x824B, + GL_DEBUG_TYPE_ERROR = 0x824C, + GL_DEBUG_TYPE_ERROR_ARB = 0x824C, + GL_DEBUG_TYPE_ERROR_KHR = 0x824C, + GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR = 0x824D, + GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB = 0x824D, + GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR = 0x824D, + GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR = 0x824E, + GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB = 0x824E, + GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR = 0x824E, + GL_DEBUG_TYPE_PORTABILITY = 0x824F, + GL_DEBUG_TYPE_PORTABILITY_ARB = 0x824F, + GL_DEBUG_TYPE_PORTABILITY_KHR = 0x824F, + GL_DEBUG_TYPE_PERFORMANCE = 0x8250, + GL_DEBUG_TYPE_PERFORMANCE_ARB = 0x8250, + GL_DEBUG_TYPE_PERFORMANCE_KHR = 0x8250, + GL_DEBUG_TYPE_OTHER = 0x8251, + GL_DEBUG_TYPE_OTHER_ARB = 0x8251, + GL_DEBUG_TYPE_OTHER_KHR = 0x8251, + GL_LOSE_CONTEXT_ON_RESET = 0x8252, + GL_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, + GL_LOSE_CONTEXT_ON_RESET_EXT = 0x8252, + GL_LOSE_CONTEXT_ON_RESET_KHR = 0x8252, + GL_GUILTY_CONTEXT_RESET = 0x8253, + GL_GUILTY_CONTEXT_RESET_ARB = 0x8253, + GL_GUILTY_CONTEXT_RESET_EXT = 0x8253, + GL_GUILTY_CONTEXT_RESET_KHR = 0x8253, + GL_INNOCENT_CONTEXT_RESET = 0x8254, + GL_INNOCENT_CONTEXT_RESET_ARB = 0x8254, + GL_INNOCENT_CONTEXT_RESET_EXT = 0x8254, + GL_INNOCENT_CONTEXT_RESET_KHR = 0x8254, + GL_UNKNOWN_CONTEXT_RESET = 0x8255, + GL_UNKNOWN_CONTEXT_RESET_ARB = 0x8255, + GL_UNKNOWN_CONTEXT_RESET_EXT = 0x8255, + GL_UNKNOWN_CONTEXT_RESET_KHR = 0x8255, + GL_RESET_NOTIFICATION_STRATEGY = 0x8256, + GL_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, + GL_RESET_NOTIFICATION_STRATEGY_EXT = 0x8256, + GL_RESET_NOTIFICATION_STRATEGY_KHR = 0x8256, + GL_PROGRAM_BINARY_RETRIEVABLE_HINT = 0x8257, + GL_PROGRAM_SEPARABLE = 0x8258, + GL_PROGRAM_SEPARABLE_EXT = 0x8258, + GL_ACTIVE_PROGRAM = 0x8259, + GL_ACTIVE_PROGRAM_EXT = 0x8259, + GL_PROGRAM_PIPELINE_BINDING = 0x825A, + GL_PROGRAM_PIPELINE_BINDING_EXT = 0x825A, + GL_MAX_VIEWPORTS = 0x825B, + GL_MAX_VIEWPORTS_NV = 0x825B, + GL_MAX_VIEWPORTS_OES = 0x825B, + GL_VIEWPORT_SUBPIXEL_BITS = 0x825C, + GL_VIEWPORT_SUBPIXEL_BITS_EXT = 0x825C, + GL_VIEWPORT_SUBPIXEL_BITS_NV = 0x825C, + GL_VIEWPORT_SUBPIXEL_BITS_OES = 0x825C, + GL_VIEWPORT_BOUNDS_RANGE = 0x825D, + GL_VIEWPORT_BOUNDS_RANGE_EXT = 0x825D, + GL_VIEWPORT_BOUNDS_RANGE_NV = 0x825D, + GL_VIEWPORT_BOUNDS_RANGE_OES = 0x825D, + GL_LAYER_PROVOKING_VERTEX = 0x825E, + GL_LAYER_PROVOKING_VERTEX_EXT = 0x825E, + GL_LAYER_PROVOKING_VERTEX_OES = 0x825E, + GL_VIEWPORT_INDEX_PROVOKING_VERTEX = 0x825F, + GL_VIEWPORT_INDEX_PROVOKING_VERTEX_EXT = 0x825F, + GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV = 0x825F, + GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES = 0x825F, + GL_UNDEFINED_VERTEX = 0x8260, + GL_UNDEFINED_VERTEX_EXT = 0x8260, + GL_UNDEFINED_VERTEX_OES = 0x8260, + GL_NO_RESET_NOTIFICATION = 0x8261, + GL_NO_RESET_NOTIFICATION_ARB = 0x8261, + GL_NO_RESET_NOTIFICATION_EXT = 0x8261, + GL_NO_RESET_NOTIFICATION_KHR = 0x8261, + GL_MAX_COMPUTE_SHARED_MEMORY_SIZE = 0x8262, + GL_MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263, + GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS = 0x8264, + GL_MAX_COMPUTE_ATOMIC_COUNTERS = 0x8265, + GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS = 0x8266, + GL_COMPUTE_WORK_GROUP_SIZE = 0x8267, + GL_DEBUG_TYPE_MARKER = 0x8268, + GL_DEBUG_TYPE_MARKER_KHR = 0x8268, + GL_DEBUG_TYPE_PUSH_GROUP = 0x8269, + GL_DEBUG_TYPE_PUSH_GROUP_KHR = 0x8269, + GL_DEBUG_TYPE_POP_GROUP = 0x826A, + GL_DEBUG_TYPE_POP_GROUP_KHR = 0x826A, + GL_DEBUG_SEVERITY_NOTIFICATION = 0x826B, + GL_DEBUG_SEVERITY_NOTIFICATION_KHR = 0x826B, + GL_MAX_DEBUG_GROUP_STACK_DEPTH = 0x826C, + GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR = 0x826C, + GL_DEBUG_GROUP_STACK_DEPTH = 0x826D, + GL_DEBUG_GROUP_STACK_DEPTH_KHR = 0x826D, + GL_MAX_UNIFORM_LOCATIONS = 0x826E, + GL_INTERNALFORMAT_SUPPORTED = 0x826F, + GL_INTERNALFORMAT_PREFERRED = 0x8270, + GL_INTERNALFORMAT_RED_SIZE = 0x8271, + GL_INTERNALFORMAT_GREEN_SIZE = 0x8272, + GL_INTERNALFORMAT_BLUE_SIZE = 0x8273, + GL_INTERNALFORMAT_ALPHA_SIZE = 0x8274, + GL_INTERNALFORMAT_DEPTH_SIZE = 0x8275, + GL_INTERNALFORMAT_STENCIL_SIZE = 0x8276, + GL_INTERNALFORMAT_SHARED_SIZE = 0x8277, + GL_INTERNALFORMAT_RED_TYPE = 0x8278, + GL_INTERNALFORMAT_GREEN_TYPE = 0x8279, + GL_INTERNALFORMAT_BLUE_TYPE = 0x827A, + GL_INTERNALFORMAT_ALPHA_TYPE = 0x827B, + GL_INTERNALFORMAT_DEPTH_TYPE = 0x827C, + GL_INTERNALFORMAT_STENCIL_TYPE = 0x827D, + GL_MAX_WIDTH = 0x827E, + GL_MAX_HEIGHT = 0x827F, + GL_MAX_DEPTH = 0x8280, + GL_MAX_LAYERS = 0x8281, + GL_MAX_COMBINED_DIMENSIONS = 0x8282, + GL_COLOR_COMPONENTS = 0x8283, + GL_DEPTH_COMPONENTS = 0x8284, + GL_STENCIL_COMPONENTS = 0x8285, + GL_COLOR_RENDERABLE = 0x8286, + GL_DEPTH_RENDERABLE = 0x8287, + GL_STENCIL_RENDERABLE = 0x8288, + GL_FRAMEBUFFER_RENDERABLE = 0x8289, + GL_FRAMEBUFFER_RENDERABLE_LAYERED = 0x828A, + GL_FRAMEBUFFER_BLEND = 0x828B, + GL_READ_PIXELS = 0x828C, + GL_READ_PIXELS_FORMAT = 0x828D, + GL_READ_PIXELS_TYPE = 0x828E, + GL_TEXTURE_IMAGE_FORMAT = 0x828F, + GL_TEXTURE_IMAGE_TYPE = 0x8290, + GL_GET_TEXTURE_IMAGE_FORMAT = 0x8291, + GL_GET_TEXTURE_IMAGE_TYPE = 0x8292, + GL_MIPMAP = 0x8293, + GL_MANUAL_GENERATE_MIPMAP = 0x8294, + GL_AUTO_GENERATE_MIPMAP = 0x8295, + GL_COLOR_ENCODING = 0x8296, + GL_SRGB_READ = 0x8297, + GL_SRGB_WRITE = 0x8298, + GL_SRGB_DECODE_ARB = 0x8299, + GL_FILTER = 0x829A, + GL_VERTEX_TEXTURE = 0x829B, + GL_TESS_CONTROL_TEXTURE = 0x829C, + GL_TESS_EVALUATION_TEXTURE = 0x829D, + GL_GEOMETRY_TEXTURE = 0x829E, + GL_FRAGMENT_TEXTURE = 0x829F, + GL_COMPUTE_TEXTURE = 0x82A0, + GL_TEXTURE_SHADOW = 0x82A1, + GL_TEXTURE_GATHER = 0x82A2, + GL_TEXTURE_GATHER_SHADOW = 0x82A3, + GL_SHADER_IMAGE_LOAD = 0x82A4, + GL_SHADER_IMAGE_STORE = 0x82A5, + GL_SHADER_IMAGE_ATOMIC = 0x82A6, + GL_IMAGE_TEXEL_SIZE = 0x82A7, + GL_IMAGE_COMPATIBILITY_CLASS = 0x82A8, + GL_IMAGE_PIXEL_FORMAT = 0x82A9, + GL_IMAGE_PIXEL_TYPE = 0x82AA, + GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST = 0x82AC, + GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST = 0x82AD, + GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE = 0x82AE, + GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE = 0x82AF, + GL_TEXTURE_COMPRESSED_BLOCK_WIDTH = 0x82B1, + GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT = 0x82B2, + GL_TEXTURE_COMPRESSED_BLOCK_SIZE = 0x82B3, + GL_CLEAR_BUFFER = 0x82B4, + GL_TEXTURE_VIEW = 0x82B5, + GL_VIEW_COMPATIBILITY_CLASS = 0x82B6, + GL_FULL_SUPPORT = 0x82B7, + GL_CAVEAT_SUPPORT = 0x82B8, + GL_IMAGE_CLASS_4_X_32 = 0x82B9, + GL_IMAGE_CLASS_2_X_32 = 0x82BA, + GL_IMAGE_CLASS_1_X_32 = 0x82BB, + GL_IMAGE_CLASS_4_X_16 = 0x82BC, + GL_IMAGE_CLASS_2_X_16 = 0x82BD, + GL_IMAGE_CLASS_1_X_16 = 0x82BE, + GL_IMAGE_CLASS_4_X_8 = 0x82BF, + GL_IMAGE_CLASS_2_X_8 = 0x82C0, + GL_IMAGE_CLASS_1_X_8 = 0x82C1, + GL_IMAGE_CLASS_11_11_10 = 0x82C2, + GL_IMAGE_CLASS_10_10_10_2 = 0x82C3, + GL_VIEW_CLASS_128_BITS = 0x82C4, + GL_VIEW_CLASS_96_BITS = 0x82C5, + GL_VIEW_CLASS_64_BITS = 0x82C6, + GL_VIEW_CLASS_48_BITS = 0x82C7, + GL_VIEW_CLASS_32_BITS = 0x82C8, + GL_VIEW_CLASS_24_BITS = 0x82C9, + GL_VIEW_CLASS_16_BITS = 0x82CA, + GL_VIEW_CLASS_8_BITS = 0x82CB, + GL_VIEW_CLASS_S3TC_DXT1_RGB = 0x82CC, + GL_VIEW_CLASS_S3TC_DXT1_RGBA = 0x82CD, + GL_VIEW_CLASS_S3TC_DXT3_RGBA = 0x82CE, + GL_VIEW_CLASS_S3TC_DXT5_RGBA = 0x82CF, + GL_VIEW_CLASS_RGTC1_RED = 0x82D0, + GL_VIEW_CLASS_RGTC2_RG = 0x82D1, + GL_VIEW_CLASS_BPTC_UNORM = 0x82D2, + GL_VIEW_CLASS_BPTC_FLOAT = 0x82D3, + GL_VERTEX_ATTRIB_BINDING = 0x82D4, + GL_VERTEX_ATTRIB_RELATIVE_OFFSET = 0x82D5, + GL_VERTEX_BINDING_DIVISOR = 0x82D6, + GL_VERTEX_BINDING_OFFSET = 0x82D7, + GL_VERTEX_BINDING_STRIDE = 0x82D8, + GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET = 0x82D9, + GL_MAX_VERTEX_ATTRIB_BINDINGS = 0x82DA, + GL_TEXTURE_VIEW_MIN_LEVEL = 0x82DB, + GL_TEXTURE_VIEW_MIN_LEVEL_EXT = 0x82DB, + GL_TEXTURE_VIEW_MIN_LEVEL_OES = 0x82DB, + GL_TEXTURE_VIEW_NUM_LEVELS = 0x82DC, + GL_TEXTURE_VIEW_NUM_LEVELS_EXT = 0x82DC, + GL_TEXTURE_VIEW_NUM_LEVELS_OES = 0x82DC, + GL_TEXTURE_VIEW_MIN_LAYER = 0x82DD, + GL_TEXTURE_VIEW_MIN_LAYER_EXT = 0x82DD, + GL_TEXTURE_VIEW_MIN_LAYER_OES = 0x82DD, + GL_TEXTURE_VIEW_NUM_LAYERS = 0x82DE, + GL_TEXTURE_VIEW_NUM_LAYERS_EXT = 0x82DE, + GL_TEXTURE_VIEW_NUM_LAYERS_OES = 0x82DE, + GL_TEXTURE_IMMUTABLE_LEVELS = 0x82DF, + GL_BUFFER = 0x82E0, + GL_BUFFER_KHR = 0x82E0, + GL_SHADER = 0x82E1, + GL_SHADER_KHR = 0x82E1, + GL_PROGRAM = 0x82E2, + GL_PROGRAM_KHR = 0x82E2, + GL_QUERY = 0x82E3, + GL_QUERY_KHR = 0x82E3, + GL_PROGRAM_PIPELINE = 0x82E4, + GL_PROGRAM_PIPELINE_KHR = 0x82E4, + GL_MAX_VERTEX_ATTRIB_STRIDE = 0x82E5, + GL_SAMPLER = 0x82E6, + GL_SAMPLER_KHR = 0x82E6, + GL_DISPLAY_LIST = 0x82E7, + GL_MAX_LABEL_LENGTH = 0x82E8, + GL_MAX_LABEL_LENGTH_KHR = 0x82E8, + GL_NUM_SHADING_LANGUAGE_VERSIONS = 0x82E9, + GL_QUERY_TARGET = 0x82EA, + GL_TRANSFORM_FEEDBACK_OVERFLOW = 0x82EC, + GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB = 0x82EC, + GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW = 0x82ED, + GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB = 0x82ED, + GL_VERTICES_SUBMITTED = 0x82EE, + GL_VERTICES_SUBMITTED_ARB = 0x82EE, + GL_PRIMITIVES_SUBMITTED = 0x82EF, + GL_PRIMITIVES_SUBMITTED_ARB = 0x82EF, + GL_VERTEX_SHADER_INVOCATIONS = 0x82F0, + GL_VERTEX_SHADER_INVOCATIONS_ARB = 0x82F0, + GL_TESS_CONTROL_SHADER_PATCHES = 0x82F1, + GL_TESS_CONTROL_SHADER_PATCHES_ARB = 0x82F1, + GL_TESS_EVALUATION_SHADER_INVOCATIONS = 0x82F2, + GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB = 0x82F2, + GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED = 0x82F3, + GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB = 0x82F3, + GL_FRAGMENT_SHADER_INVOCATIONS = 0x82F4, + GL_FRAGMENT_SHADER_INVOCATIONS_ARB = 0x82F4, + GL_COMPUTE_SHADER_INVOCATIONS = 0x82F5, + GL_COMPUTE_SHADER_INVOCATIONS_ARB = 0x82F5, + GL_CLIPPING_INPUT_PRIMITIVES = 0x82F6, + GL_CLIPPING_INPUT_PRIMITIVES_ARB = 0x82F6, + GL_CLIPPING_OUTPUT_PRIMITIVES = 0x82F7, + GL_CLIPPING_OUTPUT_PRIMITIVES_ARB = 0x82F7, + GL_SPARSE_BUFFER_PAGE_SIZE_ARB = 0x82F8, + GL_MAX_CULL_DISTANCES = 0x82F9, + GL_MAX_CULL_DISTANCES_EXT = 0x82F9, + GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES = 0x82FA, + GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT = 0x82FA, + GL_CONTEXT_RELEASE_BEHAVIOR = 0x82FB, + GL_CONTEXT_RELEASE_BEHAVIOR_KHR = 0x82FB, + GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x82FC, + GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR = 0x82FC, + GL_ROBUST_GPU_TIMEOUT_MS_KHR = 0x82FD, + GL_DEPTH_PASS_INSTRUMENT_SGIX = 0x8310, + GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX = 0x8311, + GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX = 0x8312, + GL_FRAGMENTS_INSTRUMENT_SGIX = 0x8313, + GL_FRAGMENTS_INSTRUMENT_COUNTERS_SGIX = 0x8314, + GL_FRAGMENTS_INSTRUMENT_MAX_SGIX = 0x8315, + GL_CONVOLUTION_HINT_SGIX = 0x8316, + GL_YCRCB_SGIX = 0x8318, + GL_YCRCBA_SGIX = 0x8319, + GL_UNPACK_COMPRESSED_SIZE_SGIX = 0x831A, + GL_PACK_MAX_COMPRESSED_SIZE_SGIX = 0x831B, + GL_PACK_COMPRESSED_SIZE_SGIX = 0x831C, + GL_SLIM8U_SGIX = 0x831D, + GL_SLIM10U_SGIX = 0x831E, + GL_SLIM12S_SGIX = 0x831F, + GL_ALPHA_MIN_SGIX = 0x8320, + GL_ALPHA_MAX_SGIX = 0x8321, + GL_SCALEBIAS_HINT_SGIX = 0x8322, + GL_ASYNC_MARKER_SGIX = 0x8329, + GL_PIXEL_TEX_GEN_MODE_SGIX = 0x832B, + GL_ASYNC_HISTOGRAM_SGIX = 0x832C, + GL_MAX_ASYNC_HISTOGRAM_SGIX = 0x832D, + GL_PIXEL_TRANSFORM_2D_EXT = 0x8330, + GL_PIXEL_MAG_FILTER_EXT = 0x8331, + GL_PIXEL_MIN_FILTER_EXT = 0x8332, + GL_PIXEL_CUBIC_WEIGHT_EXT = 0x8333, + GL_CUBIC_EXT = 0x8334, + GL_AVERAGE_EXT = 0x8335, + GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = 0x8336, + GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = 0x8337, + GL_PIXEL_TRANSFORM_2D_MATRIX_EXT = 0x8338, + GL_FRAGMENT_MATERIAL_EXT = 0x8349, + GL_FRAGMENT_NORMAL_EXT = 0x834A, + GL_FRAGMENT_COLOR_EXT = 0x834C, + GL_ATTENUATION_EXT = 0x834D, + GL_SHADOW_ATTENUATION_EXT = 0x834E, + GL_TEXTURE_APPLICATION_MODE_EXT = 0x834F, + GL_TEXTURE_LIGHT_EXT = 0x8350, + GL_TEXTURE_MATERIAL_FACE_EXT = 0x8351, + GL_TEXTURE_MATERIAL_PARAMETER_EXT = 0x8352, + GL_PIXEL_TEXTURE_SGIS = 0x8353, + GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = 0x8354, + GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = 0x8355, + GL_PIXEL_GROUP_COLOR_SGIS = 0x8356, + GL_LINE_QUALITY_HINT_SGIX = 0x835B, + GL_ASYNC_TEX_IMAGE_SGIX = 0x835C, + GL_ASYNC_DRAW_PIXELS_SGIX = 0x835D, + GL_ASYNC_READ_PIXELS_SGIX = 0x835E, + GL_MAX_ASYNC_TEX_IMAGE_SGIX = 0x835F, + GL_MAX_ASYNC_DRAW_PIXELS_SGIX = 0x8360, + GL_MAX_ASYNC_READ_PIXELS_SGIX = 0x8361, + GL_UNSIGNED_BYTE_2_3_3_REV = 0x8362, + GL_UNSIGNED_BYTE_2_3_3_REV_EXT = 0x8362, + GL_UNSIGNED_SHORT_5_6_5 = 0x8363, + GL_UNSIGNED_SHORT_5_6_5_EXT = 0x8363, + GL_UNSIGNED_SHORT_5_6_5_REV = 0x8364, + GL_UNSIGNED_SHORT_5_6_5_REV_EXT = 0x8364, + GL_UNSIGNED_SHORT_4_4_4_4_REV = 0x8365, + GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT = 0x8365, + GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG = 0x8365, + GL_UNSIGNED_SHORT_1_5_5_5_REV = 0x8366, + GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT = 0x8366, + GL_UNSIGNED_INT_8_8_8_8_REV = 0x8367, + GL_UNSIGNED_INT_8_8_8_8_REV_EXT = 0x8367, + GL_UNSIGNED_INT_2_10_10_10_REV = 0x8368, + GL_UNSIGNED_INT_2_10_10_10_REV_EXT = 0x8368, + GL_TEXTURE_MAX_CLAMP_S_SGIX = 0x8369, + GL_TEXTURE_MAX_CLAMP_T_SGIX = 0x836A, + GL_TEXTURE_MAX_CLAMP_R_SGIX = 0x836B, + GL_MIRRORED_REPEAT = 0x8370, + GL_MIRRORED_REPEAT_ARB = 0x8370, + GL_MIRRORED_REPEAT_IBM = 0x8370, + GL_MIRRORED_REPEAT_OES = 0x8370, + GL_RGB_S3TC = 0x83A0, + GL_RGB4_S3TC = 0x83A1, + GL_RGBA_S3TC = 0x83A2, + GL_RGBA4_S3TC = 0x83A3, + GL_RGBA_DXT5_S3TC = 0x83A4, + GL_RGBA4_DXT5_S3TC = 0x83A5, + GL_VERTEX_PRECLIP_SGIX = 0x83EE, + GL_VERTEX_PRECLIP_HINT_SGIX = 0x83EF, + GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1, + GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE = 0x83F2, + GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2, + GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE = 0x83F3, + GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3, + GL_PARALLEL_ARRAYS_INTEL = 0x83F4, + GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F5, + GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F6, + GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F7, + GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F8, + GL_PERFQUERY_DONOT_FLUSH_INTEL = 0x83F9, + GL_PERFQUERY_FLUSH_INTEL = 0x83FA, + GL_PERFQUERY_WAIT_INTEL = 0x83FB, + GL_BLACKHOLE_RENDER_INTEL = 0x83FC, + GL_CONSERVATIVE_RASTERIZATION_INTEL = 0x83FE, + GL_TEXTURE_MEMORY_LAYOUT_INTEL = 0x83FF, + GL_FRAGMENT_LIGHTING_SGIX = 0x8400, + GL_FRAGMENT_COLOR_MATERIAL_SGIX = 0x8401, + GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX = 0x8402, + GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX = 0x8403, + GL_MAX_FRAGMENT_LIGHTS_SGIX = 0x8404, + GL_MAX_ACTIVE_LIGHTS_SGIX = 0x8405, + GL_CURRENT_RASTER_NORMAL_SGIX = 0x8406, + GL_LIGHT_ENV_MODE_SGIX = 0x8407, + GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX = 0x8408, + GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX = 0x8409, + GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX = 0x840A, + GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX = 0x840B, + GL_FRAGMENT_LIGHT0_SGIX = 0x840C, + GL_FRAGMENT_LIGHT1_SGIX = 0x840D, + GL_FRAGMENT_LIGHT2_SGIX = 0x840E, + GL_FRAGMENT_LIGHT3_SGIX = 0x840F, + GL_FRAGMENT_LIGHT4_SGIX = 0x8410, + GL_FRAGMENT_LIGHT5_SGIX = 0x8411, + GL_FRAGMENT_LIGHT6_SGIX = 0x8412, + GL_FRAGMENT_LIGHT7_SGIX = 0x8413, + GL_PACK_RESAMPLE_SGIX = 0x842E, + GL_UNPACK_RESAMPLE_SGIX = 0x842F, + GL_RESAMPLE_DECIMATE_SGIX = 0x8430, + GL_RESAMPLE_REPLICATE_SGIX = 0x8433, + GL_RESAMPLE_ZERO_FILL_SGIX = 0x8434, + GL_TANGENT_ARRAY_EXT = 0x8439, + GL_BINORMAL_ARRAY_EXT = 0x843A, + GL_CURRENT_TANGENT_EXT = 0x843B, + GL_CURRENT_BINORMAL_EXT = 0x843C, + GL_TANGENT_ARRAY_TYPE_EXT = 0x843E, + GL_TANGENT_ARRAY_STRIDE_EXT = 0x843F, + GL_BINORMAL_ARRAY_TYPE_EXT = 0x8440, + GL_BINORMAL_ARRAY_STRIDE_EXT = 0x8441, + GL_TANGENT_ARRAY_POINTER_EXT = 0x8442, + GL_BINORMAL_ARRAY_POINTER_EXT = 0x8443, + GL_MAP1_TANGENT_EXT = 0x8444, + GL_MAP2_TANGENT_EXT = 0x8445, + GL_MAP1_BINORMAL_EXT = 0x8446, + GL_MAP2_BINORMAL_EXT = 0x8447, + GL_NEAREST_CLIPMAP_NEAREST_SGIX = 0x844D, + GL_NEAREST_CLIPMAP_LINEAR_SGIX = 0x844E, + GL_LINEAR_CLIPMAP_NEAREST_SGIX = 0x844F, + GL_FOG_COORDINATE_SOURCE = 0x8450, + GL_FOG_COORDINATE_SOURCE_EXT = 0x8450, + GL_FOG_COORD_SRC = 0x8450, + GL_FOG_COORDINATE = 0x8451, + GL_FOG_COORD = 0x8451, + GL_FOG_COORDINATE_EXT = 0x8451, + GL_FRAGMENT_DEPTH = 0x8452, + GL_FRAGMENT_DEPTH_EXT = 0x8452, + GL_CURRENT_FOG_COORDINATE = 0x8453, + GL_CURRENT_FOG_COORD = 0x8453, + GL_CURRENT_FOG_COORDINATE_EXT = 0x8453, + GL_FOG_COORDINATE_ARRAY_TYPE = 0x8454, + GL_FOG_COORDINATE_ARRAY_TYPE_EXT = 0x8454, + GL_FOG_COORD_ARRAY_TYPE = 0x8454, + GL_FOG_COORDINATE_ARRAY_STRIDE = 0x8455, + GL_FOG_COORDINATE_ARRAY_STRIDE_EXT = 0x8455, + GL_FOG_COORD_ARRAY_STRIDE = 0x8455, + GL_FOG_COORDINATE_ARRAY_POINTER = 0x8456, + GL_FOG_COORDINATE_ARRAY_POINTER_EXT = 0x8456, + GL_FOG_COORD_ARRAY_POINTER = 0x8456, + GL_FOG_COORDINATE_ARRAY = 0x8457, + GL_FOG_COORDINATE_ARRAY_EXT = 0x8457, + GL_FOG_COORD_ARRAY = 0x8457, + GL_COLOR_SUM = 0x8458, + GL_COLOR_SUM_ARB = 0x8458, + GL_COLOR_SUM_EXT = 0x8458, + GL_CURRENT_SECONDARY_COLOR = 0x8459, + GL_CURRENT_SECONDARY_COLOR_EXT = 0x8459, + GL_SECONDARY_COLOR_ARRAY_SIZE = 0x845A, + GL_SECONDARY_COLOR_ARRAY_SIZE_EXT = 0x845A, + GL_SECONDARY_COLOR_ARRAY_TYPE = 0x845B, + GL_SECONDARY_COLOR_ARRAY_TYPE_EXT = 0x845B, + GL_SECONDARY_COLOR_ARRAY_STRIDE = 0x845C, + GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = 0x845C, + GL_SECONDARY_COLOR_ARRAY_POINTER = 0x845D, + GL_SECONDARY_COLOR_ARRAY_POINTER_EXT = 0x845D, + GL_SECONDARY_COLOR_ARRAY = 0x845E, + GL_SECONDARY_COLOR_ARRAY_EXT = 0x845E, + GL_CURRENT_RASTER_SECONDARY_COLOR = 0x845F, + GL_ALIASED_POINT_SIZE_RANGE = 0x846D, + GL_ALIASED_LINE_WIDTH_RANGE = 0x846E, + GL_SCREEN_COORDINATES_REND = 0x8490, + GL_INVERTED_SCREEN_W_REND = 0x8491, + GL_TEXTURE0 = 0x84C0, + GL_TEXTURE0_ARB = 0x84C0, + GL_TEXTURE1 = 0x84C1, + GL_TEXTURE1_ARB = 0x84C1, + GL_TEXTURE2 = 0x84C2, + GL_TEXTURE2_ARB = 0x84C2, + GL_TEXTURE3 = 0x84C3, + GL_TEXTURE3_ARB = 0x84C3, + GL_TEXTURE4 = 0x84C4, + GL_TEXTURE4_ARB = 0x84C4, + GL_TEXTURE5 = 0x84C5, + GL_TEXTURE5_ARB = 0x84C5, + GL_TEXTURE6 = 0x84C6, + GL_TEXTURE6_ARB = 0x84C6, + GL_TEXTURE7 = 0x84C7, + GL_TEXTURE7_ARB = 0x84C7, + GL_TEXTURE8 = 0x84C8, + GL_TEXTURE8_ARB = 0x84C8, + GL_TEXTURE9 = 0x84C9, + GL_TEXTURE9_ARB = 0x84C9, + GL_TEXTURE10 = 0x84CA, + GL_TEXTURE10_ARB = 0x84CA, + GL_TEXTURE11 = 0x84CB, + GL_TEXTURE11_ARB = 0x84CB, + GL_TEXTURE12 = 0x84CC, + GL_TEXTURE12_ARB = 0x84CC, + GL_TEXTURE13 = 0x84CD, + GL_TEXTURE13_ARB = 0x84CD, + GL_TEXTURE14 = 0x84CE, + GL_TEXTURE14_ARB = 0x84CE, + GL_TEXTURE15 = 0x84CF, + GL_TEXTURE15_ARB = 0x84CF, + GL_TEXTURE16 = 0x84D0, + GL_TEXTURE16_ARB = 0x84D0, + GL_TEXTURE17 = 0x84D1, + GL_TEXTURE17_ARB = 0x84D1, + GL_TEXTURE18 = 0x84D2, + GL_TEXTURE18_ARB = 0x84D2, + GL_TEXTURE19 = 0x84D3, + GL_TEXTURE19_ARB = 0x84D3, + GL_TEXTURE20 = 0x84D4, + GL_TEXTURE20_ARB = 0x84D4, + GL_TEXTURE21 = 0x84D5, + GL_TEXTURE21_ARB = 0x84D5, + GL_TEXTURE22 = 0x84D6, + GL_TEXTURE22_ARB = 0x84D6, + GL_TEXTURE23 = 0x84D7, + GL_TEXTURE23_ARB = 0x84D7, + GL_TEXTURE24 = 0x84D8, + GL_TEXTURE24_ARB = 0x84D8, + GL_TEXTURE25 = 0x84D9, + GL_TEXTURE25_ARB = 0x84D9, + GL_TEXTURE26 = 0x84DA, + GL_TEXTURE26_ARB = 0x84DA, + GL_TEXTURE27 = 0x84DB, + GL_TEXTURE27_ARB = 0x84DB, + GL_TEXTURE28 = 0x84DC, + GL_TEXTURE28_ARB = 0x84DC, + GL_TEXTURE29 = 0x84DD, + GL_TEXTURE29_ARB = 0x84DD, + GL_TEXTURE30 = 0x84DE, + GL_TEXTURE30_ARB = 0x84DE, + GL_TEXTURE31 = 0x84DF, + GL_TEXTURE31_ARB = 0x84DF, + GL_ACTIVE_TEXTURE = 0x84E0, + GL_ACTIVE_TEXTURE_ARB = 0x84E0, + GL_CLIENT_ACTIVE_TEXTURE = 0x84E1, + GL_CLIENT_ACTIVE_TEXTURE_ARB = 0x84E1, + GL_MAX_TEXTURE_UNITS = 0x84E2, + GL_MAX_TEXTURE_UNITS_ARB = 0x84E2, + GL_TRANSPOSE_MODELVIEW_MATRIX = 0x84E3, + GL_TRANSPOSE_MODELVIEW_MATRIX_ARB = 0x84E3, + GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV = 0x84E3, + GL_TRANSPOSE_PROJECTION_MATRIX = 0x84E4, + GL_TRANSPOSE_PROJECTION_MATRIX_ARB = 0x84E4, + GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV = 0x84E4, + GL_TRANSPOSE_TEXTURE_MATRIX = 0x84E5, + GL_TRANSPOSE_TEXTURE_MATRIX_ARB = 0x84E5, + GL_TRANSPOSE_COLOR_MATRIX = 0x84E6, + GL_TRANSPOSE_COLOR_MATRIX_ARB = 0x84E6, + GL_SUBTRACT = 0x84E7, + GL_SUBTRACT_ARB = 0x84E7, + GL_MAX_RENDERBUFFER_SIZE = 0x84E8, + GL_MAX_RENDERBUFFER_SIZE_EXT = 0x84E8, + GL_MAX_RENDERBUFFER_SIZE_OES = 0x84E8, + GL_COMPRESSED_ALPHA = 0x84E9, + GL_COMPRESSED_ALPHA_ARB = 0x84E9, + GL_COMPRESSED_LUMINANCE = 0x84EA, + GL_COMPRESSED_LUMINANCE_ARB = 0x84EA, + GL_COMPRESSED_LUMINANCE_ALPHA = 0x84EB, + GL_COMPRESSED_LUMINANCE_ALPHA_ARB = 0x84EB, + GL_COMPRESSED_INTENSITY = 0x84EC, + GL_COMPRESSED_INTENSITY_ARB = 0x84EC, + GL_COMPRESSED_RGB = 0x84ED, + GL_COMPRESSED_RGB_ARB = 0x84ED, + GL_COMPRESSED_RGBA = 0x84EE, + GL_COMPRESSED_RGBA_ARB = 0x84EE, + GL_TEXTURE_COMPRESSION_HINT = 0x84EF, + GL_TEXTURE_COMPRESSION_HINT_ARB = 0x84EF, + GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = 0x84F0, + GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x84F1, + GL_ALL_COMPLETED_NV = 0x84F2, + GL_FENCE_STATUS_NV = 0x84F3, + GL_FENCE_CONDITION_NV = 0x84F4, + GL_TEXTURE_RECTANGLE = 0x84F5, + GL_TEXTURE_RECTANGLE_ARB = 0x84F5, + GL_TEXTURE_RECTANGLE_NV = 0x84F5, + GL_TEXTURE_BINDING_RECTANGLE = 0x84F6, + GL_TEXTURE_BINDING_RECTANGLE_ARB = 0x84F6, + GL_TEXTURE_BINDING_RECTANGLE_NV = 0x84F6, + GL_PROXY_TEXTURE_RECTANGLE = 0x84F7, + GL_PROXY_TEXTURE_RECTANGLE_ARB = 0x84F7, + GL_PROXY_TEXTURE_RECTANGLE_NV = 0x84F7, + GL_MAX_RECTANGLE_TEXTURE_SIZE = 0x84F8, + GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = 0x84F8, + GL_MAX_RECTANGLE_TEXTURE_SIZE_NV = 0x84F8, + GL_DEPTH_STENCIL = 0x84F9, + GL_DEPTH_STENCIL_EXT = 0x84F9, + GL_DEPTH_STENCIL_NV = 0x84F9, + GL_DEPTH_STENCIL_OES = 0x84F9, + GL_UNSIGNED_INT_24_8 = 0x84FA, + GL_UNSIGNED_INT_24_8_EXT = 0x84FA, + GL_UNSIGNED_INT_24_8_NV = 0x84FA, + GL_UNSIGNED_INT_24_8_OES = 0x84FA, + GL_MAX_TEXTURE_LOD_BIAS = 0x84FD, + GL_MAX_TEXTURE_LOD_BIAS_EXT = 0x84FD, + GL_TEXTURE_MAX_ANISOTROPY = 0x84FE, + GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE, + GL_MAX_TEXTURE_MAX_ANISOTROPY = 0x84FF, + GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF, + GL_TEXTURE_FILTER_CONTROL = 0x8500, + GL_TEXTURE_FILTER_CONTROL_EXT = 0x8500, + GL_TEXTURE_LOD_BIAS = 0x8501, + GL_TEXTURE_LOD_BIAS_EXT = 0x8501, + GL_MODELVIEW1_STACK_DEPTH_EXT = 0x8502, + GL_COMBINE4_NV = 0x8503, + GL_MAX_SHININESS_NV = 0x8504, + GL_MAX_SPOT_EXPONENT_NV = 0x8505, + GL_MODELVIEW1_MATRIX_EXT = 0x8506, + GL_INCR_WRAP = 0x8507, + GL_INCR_WRAP_EXT = 0x8507, + GL_INCR_WRAP_OES = 0x8507, + GL_DECR_WRAP = 0x8508, + GL_DECR_WRAP_EXT = 0x8508, + GL_DECR_WRAP_OES = 0x8508, + GL_VERTEX_WEIGHTING_EXT = 0x8509, + GL_MODELVIEW1_ARB = 0x850A, + GL_MODELVIEW1_EXT = 0x850A, + GL_CURRENT_VERTEX_WEIGHT_EXT = 0x850B, + GL_VERTEX_WEIGHT_ARRAY_EXT = 0x850C, + GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = 0x850D, + GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = 0x850E, + GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = 0x850F, + GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = 0x8510, + GL_NORMAL_MAP = 0x8511, + GL_NORMAL_MAP_ARB = 0x8511, + GL_NORMAL_MAP_EXT = 0x8511, + GL_NORMAL_MAP_NV = 0x8511, + GL_NORMAL_MAP_OES = 0x8511, + GL_REFLECTION_MAP = 0x8512, + GL_REFLECTION_MAP_ARB = 0x8512, + GL_REFLECTION_MAP_EXT = 0x8512, + GL_REFLECTION_MAP_NV = 0x8512, + GL_REFLECTION_MAP_OES = 0x8512, + GL_TEXTURE_CUBE_MAP = 0x8513, + GL_TEXTURE_CUBE_MAP_ARB = 0x8513, + GL_TEXTURE_CUBE_MAP_EXT = 0x8513, + GL_TEXTURE_CUBE_MAP_OES = 0x8513, + GL_TEXTURE_BINDING_CUBE_MAP = 0x8514, + GL_TEXTURE_BINDING_CUBE_MAP_ARB = 0x8514, + GL_TEXTURE_BINDING_CUBE_MAP_EXT = 0x8514, + GL_TEXTURE_BINDING_CUBE_MAP_OES = 0x8514, + GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515, + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 0x8515, + GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT = 0x8515, + GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES = 0x8515, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 0x8516, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT = 0x8516, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES = 0x8516, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 0x8517, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT = 0x8517, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES = 0x8517, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 0x8518, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT = 0x8518, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES = 0x8518, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 0x8519, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT = 0x8519, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES = 0x8519, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 0x851A, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT = 0x851A, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES = 0x851A, + GL_PROXY_TEXTURE_CUBE_MAP = 0x851B, + GL_PROXY_TEXTURE_CUBE_MAP_ARB = 0x851B, + GL_PROXY_TEXTURE_CUBE_MAP_EXT = 0x851B, + GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C, + GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = 0x851C, + GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT = 0x851C, + GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES = 0x851C, + GL_VERTEX_ARRAY_RANGE_APPLE = 0x851D, + GL_VERTEX_ARRAY_RANGE_NV = 0x851D, + GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = 0x851E, + GL_VERTEX_ARRAY_RANGE_LENGTH_NV = 0x851E, + GL_VERTEX_ARRAY_RANGE_VALID_NV = 0x851F, + GL_VERTEX_ARRAY_STORAGE_HINT_APPLE = 0x851F, + GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = 0x8520, + GL_VERTEX_ARRAY_RANGE_POINTER_APPLE = 0x8521, + GL_VERTEX_ARRAY_RANGE_POINTER_NV = 0x8521, + GL_REGISTER_COMBINERS_NV = 0x8522, + GL_VARIABLE_A_NV = 0x8523, + GL_VARIABLE_B_NV = 0x8524, + GL_VARIABLE_C_NV = 0x8525, + GL_VARIABLE_D_NV = 0x8526, + GL_VARIABLE_E_NV = 0x8527, + GL_VARIABLE_F_NV = 0x8528, + GL_VARIABLE_G_NV = 0x8529, + GL_CONSTANT_COLOR0_NV = 0x852A, + GL_CONSTANT_COLOR1_NV = 0x852B, + GL_PRIMARY_COLOR_NV = 0x852C, + GL_SECONDARY_COLOR_NV = 0x852D, + GL_SPARE0_NV = 0x852E, + GL_SPARE1_NV = 0x852F, + GL_DISCARD_NV = 0x8530, + GL_E_TIMES_F_NV = 0x8531, + GL_SPARE0_PLUS_SECONDARY_COLOR_NV = 0x8532, + GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = 0x8533, + GL_MULTISAMPLE_FILTER_HINT_NV = 0x8534, + GL_PER_STAGE_CONSTANTS_NV = 0x8535, + GL_UNSIGNED_IDENTITY_NV = 0x8536, + GL_UNSIGNED_INVERT_NV = 0x8537, + GL_EXPAND_NORMAL_NV = 0x8538, + GL_EXPAND_NEGATE_NV = 0x8539, + GL_HALF_BIAS_NORMAL_NV = 0x853A, + GL_HALF_BIAS_NEGATE_NV = 0x853B, + GL_SIGNED_IDENTITY_NV = 0x853C, + GL_SIGNED_NEGATE_NV = 0x853D, + GL_SCALE_BY_TWO_NV = 0x853E, + GL_SCALE_BY_FOUR_NV = 0x853F, + GL_SCALE_BY_ONE_HALF_NV = 0x8540, + GL_BIAS_BY_NEGATIVE_ONE_HALF_NV = 0x8541, + GL_COMBINER_INPUT_NV = 0x8542, + GL_COMBINER_MAPPING_NV = 0x8543, + GL_COMBINER_COMPONENT_USAGE_NV = 0x8544, + GL_COMBINER_AB_DOT_PRODUCT_NV = 0x8545, + GL_COMBINER_CD_DOT_PRODUCT_NV = 0x8546, + GL_COMBINER_MUX_SUM_NV = 0x8547, + GL_COMBINER_SCALE_NV = 0x8548, + GL_COMBINER_BIAS_NV = 0x8549, + GL_COMBINER_AB_OUTPUT_NV = 0x854A, + GL_COMBINER_CD_OUTPUT_NV = 0x854B, + GL_COMBINER_SUM_OUTPUT_NV = 0x854C, + GL_MAX_GENERAL_COMBINERS_NV = 0x854D, + GL_NUM_GENERAL_COMBINERS_NV = 0x854E, + GL_COLOR_SUM_CLAMP_NV = 0x854F, + GL_COMBINER0_NV = 0x8550, + GL_COMBINER1_NV = 0x8551, + GL_COMBINER2_NV = 0x8552, + GL_COMBINER3_NV = 0x8553, + GL_COMBINER4_NV = 0x8554, + GL_COMBINER5_NV = 0x8555, + GL_COMBINER6_NV = 0x8556, + GL_COMBINER7_NV = 0x8557, + GL_PRIMITIVE_RESTART_NV = 0x8558, + GL_PRIMITIVE_RESTART_INDEX_NV = 0x8559, + GL_FOG_DISTANCE_MODE_NV = 0x855A, + GL_EYE_RADIAL_NV = 0x855B, + GL_EYE_PLANE_ABSOLUTE_NV = 0x855C, + GL_EMBOSS_LIGHT_NV = 0x855D, + GL_EMBOSS_CONSTANT_NV = 0x855E, + GL_EMBOSS_MAP_NV = 0x855F, + GL_RED_MIN_CLAMP_INGR = 0x8560, + GL_GREEN_MIN_CLAMP_INGR = 0x8561, + GL_BLUE_MIN_CLAMP_INGR = 0x8562, + GL_ALPHA_MIN_CLAMP_INGR = 0x8563, + GL_RED_MAX_CLAMP_INGR = 0x8564, + GL_GREEN_MAX_CLAMP_INGR = 0x8565, + GL_BLUE_MAX_CLAMP_INGR = 0x8566, + GL_ALPHA_MAX_CLAMP_INGR = 0x8567, + GL_INTERLACE_READ_INGR = 0x8568, + GL_PACK_SUBSAMPLE_RATE_SGIX = 0x85A0, + GL_UNPACK_SUBSAMPLE_RATE_SGIX = 0x85A1, + GL_PIXEL_SUBSAMPLE_4444_SGIX = 0x85A2, + GL_PIXEL_SUBSAMPLE_2424_SGIX = 0x85A3, + GL_PIXEL_SUBSAMPLE_4242_SGIX = 0x85A4, + GL_PERTURB_EXT = 0x85AE, + GL_TEXTURE_NORMAL_EXT = 0x85AF, + GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE = 0x85B0, + GL_TRANSFORM_HINT_APPLE = 0x85B1, + GL_UNPACK_CLIENT_STORAGE_APPLE = 0x85B2, + GL_BUFFER_OBJECT_APPLE = 0x85B3, + GL_STORAGE_CLIENT_APPLE = 0x85B4, + GL_VERTEX_ARRAY_BINDING = 0x85B5, + GL_VERTEX_ARRAY_BINDING_APPLE = 0x85B5, + GL_VERTEX_ARRAY_BINDING_OES = 0x85B5, + GL_TEXTURE_RANGE_LENGTH_APPLE = 0x85B7, + GL_TEXTURE_RANGE_POINTER_APPLE = 0x85B8, + GL_YCBCR_422_APPLE = 0x85B9, + GL_UNSIGNED_SHORT_8_8_APPLE = 0x85BA, + GL_UNSIGNED_SHORT_8_8_MESA = 0x85BA, + GL_UNSIGNED_SHORT_8_8_REV_APPLE = 0x85BB, + GL_UNSIGNED_SHORT_8_8_REV_MESA = 0x85BB, + GL_TEXTURE_STORAGE_HINT_APPLE = 0x85BC, + GL_STORAGE_PRIVATE_APPLE = 0x85BD, + GL_STORAGE_CACHED_APPLE = 0x85BE, + GL_STORAGE_SHARED_APPLE = 0x85BF, + GL_REPLACEMENT_CODE_ARRAY_SUN = 0x85C0, + GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN = 0x85C1, + GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN = 0x85C2, + GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN = 0x85C3, + GL_R1UI_V3F_SUN = 0x85C4, + GL_R1UI_C4UB_V3F_SUN = 0x85C5, + GL_R1UI_C3F_V3F_SUN = 0x85C6, + GL_R1UI_N3F_V3F_SUN = 0x85C7, + GL_R1UI_C4F_N3F_V3F_SUN = 0x85C8, + GL_R1UI_T2F_V3F_SUN = 0x85C9, + GL_R1UI_T2F_N3F_V3F_SUN = 0x85CA, + GL_R1UI_T2F_C4F_N3F_V3F_SUN = 0x85CB, + GL_SLICE_ACCUM_SUN = 0x85CC, + GL_QUAD_MESH_SUN = 0x8614, + GL_TRIANGLE_MESH_SUN = 0x8615, + GL_VERTEX_PROGRAM_ARB = 0x8620, + GL_VERTEX_PROGRAM_NV = 0x8620, + GL_VERTEX_STATE_PROGRAM_NV = 0x8621, + GL_VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622, + GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = 0x8622, + GL_ATTRIB_ARRAY_SIZE_NV = 0x8623, + GL_VERTEX_ATTRIB_ARRAY_SIZE = 0x8623, + GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = 0x8623, + GL_ATTRIB_ARRAY_STRIDE_NV = 0x8624, + GL_VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624, + GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = 0x8624, + GL_ATTRIB_ARRAY_TYPE_NV = 0x8625, + GL_VERTEX_ATTRIB_ARRAY_TYPE = 0x8625, + GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = 0x8625, + GL_CURRENT_ATTRIB_NV = 0x8626, + GL_CURRENT_VERTEX_ATTRIB = 0x8626, + GL_CURRENT_VERTEX_ATTRIB_ARB = 0x8626, + GL_PROGRAM_LENGTH_ARB = 0x8627, + GL_PROGRAM_LENGTH_NV = 0x8627, + GL_PROGRAM_STRING_ARB = 0x8628, + GL_PROGRAM_STRING_NV = 0x8628, + GL_MODELVIEW_PROJECTION_NV = 0x8629, + GL_IDENTITY_NV = 0x862A, + GL_INVERSE_NV = 0x862B, + GL_TRANSPOSE_NV = 0x862C, + GL_INVERSE_TRANSPOSE_NV = 0x862D, + GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = 0x862E, + GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = 0x862E, + GL_MAX_PROGRAM_MATRICES_ARB = 0x862F, + GL_MAX_TRACK_MATRICES_NV = 0x862F, + GL_MATRIX0_NV = 0x8630, + GL_MATRIX1_NV = 0x8631, + GL_MATRIX2_NV = 0x8632, + GL_MATRIX3_NV = 0x8633, + GL_MATRIX4_NV = 0x8634, + GL_MATRIX5_NV = 0x8635, + GL_MATRIX6_NV = 0x8636, + GL_MATRIX7_NV = 0x8637, + GL_CURRENT_MATRIX_STACK_DEPTH_ARB = 0x8640, + GL_CURRENT_MATRIX_STACK_DEPTH_NV = 0x8640, + GL_CURRENT_MATRIX_ARB = 0x8641, + GL_CURRENT_MATRIX_NV = 0x8641, + GL_VERTEX_PROGRAM_POINT_SIZE = 0x8642, + GL_VERTEX_PROGRAM_POINT_SIZE_ARB = 0x8642, + GL_VERTEX_PROGRAM_POINT_SIZE_NV = 0x8642, + GL_PROGRAM_POINT_SIZE = 0x8642, + GL_PROGRAM_POINT_SIZE_ARB = 0x8642, + GL_PROGRAM_POINT_SIZE_EXT = 0x8642, + GL_VERTEX_PROGRAM_TWO_SIDE = 0x8643, + GL_VERTEX_PROGRAM_TWO_SIDE_ARB = 0x8643, + GL_VERTEX_PROGRAM_TWO_SIDE_NV = 0x8643, + GL_PROGRAM_PARAMETER_NV = 0x8644, + GL_ATTRIB_ARRAY_POINTER_NV = 0x8645, + GL_VERTEX_ATTRIB_ARRAY_POINTER = 0x8645, + GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = 0x8645, + GL_PROGRAM_TARGET_NV = 0x8646, + GL_PROGRAM_RESIDENT_NV = 0x8647, + GL_TRACK_MATRIX_NV = 0x8648, + GL_TRACK_MATRIX_TRANSFORM_NV = 0x8649, + GL_VERTEX_PROGRAM_BINDING_NV = 0x864A, + GL_PROGRAM_ERROR_POSITION_ARB = 0x864B, + GL_PROGRAM_ERROR_POSITION_NV = 0x864B, + GL_OFFSET_TEXTURE_RECTANGLE_NV = 0x864C, + GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = 0x864D, + GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = 0x864E, + GL_DEPTH_CLAMP = 0x864F, + GL_DEPTH_CLAMP_NV = 0x864F, + GL_DEPTH_CLAMP_EXT = 0x864F, + GL_VERTEX_ATTRIB_ARRAY0_NV = 0x8650, + GL_VERTEX_ATTRIB_ARRAY1_NV = 0x8651, + GL_VERTEX_ATTRIB_ARRAY2_NV = 0x8652, + GL_VERTEX_ATTRIB_ARRAY3_NV = 0x8653, + GL_VERTEX_ATTRIB_ARRAY4_NV = 0x8654, + GL_VERTEX_ATTRIB_ARRAY5_NV = 0x8655, + GL_VERTEX_ATTRIB_ARRAY6_NV = 0x8656, + GL_VERTEX_ATTRIB_ARRAY7_NV = 0x8657, + GL_VERTEX_ATTRIB_ARRAY8_NV = 0x8658, + GL_VERTEX_ATTRIB_ARRAY9_NV = 0x8659, + GL_VERTEX_ATTRIB_ARRAY10_NV = 0x865A, + GL_VERTEX_ATTRIB_ARRAY11_NV = 0x865B, + GL_VERTEX_ATTRIB_ARRAY12_NV = 0x865C, + GL_VERTEX_ATTRIB_ARRAY13_NV = 0x865D, + GL_VERTEX_ATTRIB_ARRAY14_NV = 0x865E, + GL_VERTEX_ATTRIB_ARRAY15_NV = 0x865F, + GL_MAP1_VERTEX_ATTRIB0_4_NV = 0x8660, + GL_MAP1_VERTEX_ATTRIB1_4_NV = 0x8661, + GL_MAP1_VERTEX_ATTRIB2_4_NV = 0x8662, + GL_MAP1_VERTEX_ATTRIB3_4_NV = 0x8663, + GL_MAP1_VERTEX_ATTRIB4_4_NV = 0x8664, + GL_MAP1_VERTEX_ATTRIB5_4_NV = 0x8665, + GL_MAP1_VERTEX_ATTRIB6_4_NV = 0x8666, + GL_MAP1_VERTEX_ATTRIB7_4_NV = 0x8667, + GL_MAP1_VERTEX_ATTRIB8_4_NV = 0x8668, + GL_MAP1_VERTEX_ATTRIB9_4_NV = 0x8669, + GL_MAP1_VERTEX_ATTRIB10_4_NV = 0x866A, + GL_MAP1_VERTEX_ATTRIB11_4_NV = 0x866B, + GL_MAP1_VERTEX_ATTRIB12_4_NV = 0x866C, + GL_MAP1_VERTEX_ATTRIB13_4_NV = 0x866D, + GL_MAP1_VERTEX_ATTRIB14_4_NV = 0x866E, + GL_MAP1_VERTEX_ATTRIB15_4_NV = 0x866F, + GL_MAP2_VERTEX_ATTRIB0_4_NV = 0x8670, + GL_MAP2_VERTEX_ATTRIB1_4_NV = 0x8671, + GL_MAP2_VERTEX_ATTRIB2_4_NV = 0x8672, + GL_MAP2_VERTEX_ATTRIB3_4_NV = 0x8673, + GL_MAP2_VERTEX_ATTRIB4_4_NV = 0x8674, + GL_MAP2_VERTEX_ATTRIB5_4_NV = 0x8675, + GL_MAP2_VERTEX_ATTRIB6_4_NV = 0x8676, + GL_MAP2_VERTEX_ATTRIB7_4_NV = 0x8677, + GL_PROGRAM_BINDING_ARB = 0x8677, + GL_MAP2_VERTEX_ATTRIB8_4_NV = 0x8678, + GL_MAP2_VERTEX_ATTRIB9_4_NV = 0x8679, + GL_MAP2_VERTEX_ATTRIB10_4_NV = 0x867A, + GL_MAP2_VERTEX_ATTRIB11_4_NV = 0x867B, + GL_MAP2_VERTEX_ATTRIB12_4_NV = 0x867C, + GL_MAP2_VERTEX_ATTRIB13_4_NV = 0x867D, + GL_MAP2_VERTEX_ATTRIB14_4_NV = 0x867E, + GL_MAP2_VERTEX_ATTRIB15_4_NV = 0x867F, + GL_TEXTURE_COMPRESSED_IMAGE_SIZE = 0x86A0, + GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = 0x86A0, + GL_TEXTURE_COMPRESSED = 0x86A1, + GL_TEXTURE_COMPRESSED_ARB = 0x86A1, + GL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2, + GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = 0x86A2, + GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3, + GL_COMPRESSED_TEXTURE_FORMATS_ARB = 0x86A3, + GL_MAX_VERTEX_UNITS_ARB = 0x86A4, + GL_MAX_VERTEX_UNITS_OES = 0x86A4, + GL_ACTIVE_VERTEX_UNITS_ARB = 0x86A5, + GL_WEIGHT_SUM_UNITY_ARB = 0x86A6, + GL_VERTEX_BLEND_ARB = 0x86A7, + GL_CURRENT_WEIGHT_ARB = 0x86A8, + GL_WEIGHT_ARRAY_TYPE_ARB = 0x86A9, + GL_WEIGHT_ARRAY_TYPE_OES = 0x86A9, + GL_WEIGHT_ARRAY_STRIDE_ARB = 0x86AA, + GL_WEIGHT_ARRAY_STRIDE_OES = 0x86AA, + GL_WEIGHT_ARRAY_SIZE_ARB = 0x86AB, + GL_WEIGHT_ARRAY_SIZE_OES = 0x86AB, + GL_WEIGHT_ARRAY_POINTER_ARB = 0x86AC, + GL_WEIGHT_ARRAY_POINTER_OES = 0x86AC, + GL_WEIGHT_ARRAY_ARB = 0x86AD, + GL_WEIGHT_ARRAY_OES = 0x86AD, + GL_DOT3_RGB = 0x86AE, + GL_DOT3_RGB_ARB = 0x86AE, + GL_DOT3_RGBA = 0x86AF, + GL_DOT3_RGBA_ARB = 0x86AF, + GL_DOT3_RGBA_IMG = 0x86AF, + GL_COMPRESSED_RGB_FXT1_3DFX = 0x86B0, + GL_COMPRESSED_RGBA_FXT1_3DFX = 0x86B1, + GL_MULTISAMPLE_3DFX = 0x86B2, + GL_SAMPLE_BUFFERS_3DFX = 0x86B3, + GL_SAMPLES_3DFX = 0x86B4, + GL_EVAL_2D_NV = 0x86C0, + GL_EVAL_TRIANGULAR_2D_NV = 0x86C1, + GL_MAP_TESSELLATION_NV = 0x86C2, + GL_MAP_ATTRIB_U_ORDER_NV = 0x86C3, + GL_MAP_ATTRIB_V_ORDER_NV = 0x86C4, + GL_EVAL_FRACTIONAL_TESSELLATION_NV = 0x86C5, + GL_EVAL_VERTEX_ATTRIB0_NV = 0x86C6, + GL_EVAL_VERTEX_ATTRIB1_NV = 0x86C7, + GL_EVAL_VERTEX_ATTRIB2_NV = 0x86C8, + GL_EVAL_VERTEX_ATTRIB3_NV = 0x86C9, + GL_EVAL_VERTEX_ATTRIB4_NV = 0x86CA, + GL_EVAL_VERTEX_ATTRIB5_NV = 0x86CB, + GL_EVAL_VERTEX_ATTRIB6_NV = 0x86CC, + GL_EVAL_VERTEX_ATTRIB7_NV = 0x86CD, + GL_EVAL_VERTEX_ATTRIB8_NV = 0x86CE, + GL_EVAL_VERTEX_ATTRIB9_NV = 0x86CF, + GL_EVAL_VERTEX_ATTRIB10_NV = 0x86D0, + GL_EVAL_VERTEX_ATTRIB11_NV = 0x86D1, + GL_EVAL_VERTEX_ATTRIB12_NV = 0x86D2, + GL_EVAL_VERTEX_ATTRIB13_NV = 0x86D3, + GL_EVAL_VERTEX_ATTRIB14_NV = 0x86D4, + GL_EVAL_VERTEX_ATTRIB15_NV = 0x86D5, + GL_MAX_MAP_TESSELLATION_NV = 0x86D6, + GL_MAX_RATIONAL_EVAL_ORDER_NV = 0x86D7, + GL_MAX_PROGRAM_PATCH_ATTRIBS_NV = 0x86D8, + GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = 0x86D9, + GL_UNSIGNED_INT_S8_S8_8_8_NV = 0x86DA, + GL_UNSIGNED_INT_8_8_S8_S8_REV_NV = 0x86DB, + GL_DSDT_MAG_INTENSITY_NV = 0x86DC, + GL_SHADER_CONSISTENT_NV = 0x86DD, + GL_TEXTURE_SHADER_NV = 0x86DE, + GL_SHADER_OPERATION_NV = 0x86DF, + GL_CULL_MODES_NV = 0x86E0, + GL_OFFSET_TEXTURE_MATRIX_NV = 0x86E1, + GL_OFFSET_TEXTURE_2D_MATRIX_NV = 0x86E1, + GL_OFFSET_TEXTURE_SCALE_NV = 0x86E2, + GL_OFFSET_TEXTURE_2D_SCALE_NV = 0x86E2, + GL_OFFSET_TEXTURE_BIAS_NV = 0x86E3, + GL_OFFSET_TEXTURE_2D_BIAS_NV = 0x86E3, + GL_PREVIOUS_TEXTURE_INPUT_NV = 0x86E4, + GL_CONST_EYE_NV = 0x86E5, + GL_PASS_THROUGH_NV = 0x86E6, + GL_CULL_FRAGMENT_NV = 0x86E7, + GL_OFFSET_TEXTURE_2D_NV = 0x86E8, + GL_DEPENDENT_AR_TEXTURE_2D_NV = 0x86E9, + GL_DEPENDENT_GB_TEXTURE_2D_NV = 0x86EA, + GL_SURFACE_STATE_NV = 0x86EB, + GL_DOT_PRODUCT_NV = 0x86EC, + GL_DOT_PRODUCT_DEPTH_REPLACE_NV = 0x86ED, + GL_DOT_PRODUCT_TEXTURE_2D_NV = 0x86EE, + GL_DOT_PRODUCT_TEXTURE_3D_NV = 0x86EF, + GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = 0x86F0, + GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = 0x86F1, + GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = 0x86F2, + GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = 0x86F3, + GL_HILO_NV = 0x86F4, + GL_DSDT_NV = 0x86F5, + GL_DSDT_MAG_NV = 0x86F6, + GL_DSDT_MAG_VIB_NV = 0x86F7, + GL_HILO16_NV = 0x86F8, + GL_SIGNED_HILO_NV = 0x86F9, + GL_SIGNED_HILO16_NV = 0x86FA, + GL_SIGNED_RGBA_NV = 0x86FB, + GL_SIGNED_RGBA8_NV = 0x86FC, + GL_SURFACE_REGISTERED_NV = 0x86FD, + GL_SIGNED_RGB_NV = 0x86FE, + GL_SIGNED_RGB8_NV = 0x86FF, + GL_SURFACE_MAPPED_NV = 0x8700, + GL_SIGNED_LUMINANCE_NV = 0x8701, + GL_SIGNED_LUMINANCE8_NV = 0x8702, + GL_SIGNED_LUMINANCE_ALPHA_NV = 0x8703, + GL_SIGNED_LUMINANCE8_ALPHA8_NV = 0x8704, + GL_SIGNED_ALPHA_NV = 0x8705, + GL_SIGNED_ALPHA8_NV = 0x8706, + GL_SIGNED_INTENSITY_NV = 0x8707, + GL_SIGNED_INTENSITY8_NV = 0x8708, + GL_DSDT8_NV = 0x8709, + GL_DSDT8_MAG8_NV = 0x870A, + GL_DSDT8_MAG8_INTENSITY8_NV = 0x870B, + GL_SIGNED_RGB_UNSIGNED_ALPHA_NV = 0x870C, + GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = 0x870D, + GL_HI_SCALE_NV = 0x870E, + GL_LO_SCALE_NV = 0x870F, + GL_DS_SCALE_NV = 0x8710, + GL_DT_SCALE_NV = 0x8711, + GL_MAGNITUDE_SCALE_NV = 0x8712, + GL_VIBRANCE_SCALE_NV = 0x8713, + GL_HI_BIAS_NV = 0x8714, + GL_LO_BIAS_NV = 0x8715, + GL_DS_BIAS_NV = 0x8716, + GL_DT_BIAS_NV = 0x8717, + GL_MAGNITUDE_BIAS_NV = 0x8718, + GL_VIBRANCE_BIAS_NV = 0x8719, + GL_TEXTURE_BORDER_VALUES_NV = 0x871A, + GL_TEXTURE_HI_SIZE_NV = 0x871B, + GL_TEXTURE_LO_SIZE_NV = 0x871C, + GL_TEXTURE_DS_SIZE_NV = 0x871D, + GL_TEXTURE_DT_SIZE_NV = 0x871E, + GL_TEXTURE_MAG_SIZE_NV = 0x871F, + GL_MODELVIEW2_ARB = 0x8722, + GL_MODELVIEW3_ARB = 0x8723, + GL_MODELVIEW4_ARB = 0x8724, + GL_MODELVIEW5_ARB = 0x8725, + GL_MODELVIEW6_ARB = 0x8726, + GL_MODELVIEW7_ARB = 0x8727, + GL_MODELVIEW8_ARB = 0x8728, + GL_MODELVIEW9_ARB = 0x8729, + GL_MODELVIEW10_ARB = 0x872A, + GL_MODELVIEW11_ARB = 0x872B, + GL_MODELVIEW12_ARB = 0x872C, + GL_MODELVIEW13_ARB = 0x872D, + GL_MODELVIEW14_ARB = 0x872E, + GL_MODELVIEW15_ARB = 0x872F, + GL_MODELVIEW16_ARB = 0x8730, + GL_MODELVIEW17_ARB = 0x8731, + GL_MODELVIEW18_ARB = 0x8732, + GL_MODELVIEW19_ARB = 0x8733, + GL_MODELVIEW20_ARB = 0x8734, + GL_MODELVIEW21_ARB = 0x8735, + GL_MODELVIEW22_ARB = 0x8736, + GL_MODELVIEW23_ARB = 0x8737, + GL_MODELVIEW24_ARB = 0x8738, + GL_MODELVIEW25_ARB = 0x8739, + GL_MODELVIEW26_ARB = 0x873A, + GL_MODELVIEW27_ARB = 0x873B, + GL_MODELVIEW28_ARB = 0x873C, + GL_MODELVIEW29_ARB = 0x873D, + GL_MODELVIEW30_ARB = 0x873E, + GL_MODELVIEW31_ARB = 0x873F, + GL_DOT3_RGB_EXT = 0x8740, + GL_Z400_BINARY_AMD = 0x8740, + GL_DOT3_RGBA_EXT = 0x8741, + GL_PROGRAM_BINARY_LENGTH_OES = 0x8741, + GL_PROGRAM_BINARY_LENGTH = 0x8741, + GL_MIRROR_CLAMP_ATI = 0x8742, + GL_MIRROR_CLAMP_EXT = 0x8742, + GL_MIRROR_CLAMP_TO_EDGE = 0x8743, + GL_MIRROR_CLAMP_TO_EDGE_ATI = 0x8743, + GL_MIRROR_CLAMP_TO_EDGE_EXT = 0x8743, + GL_MODULATE_ADD_ATI = 0x8744, + GL_MODULATE_SIGNED_ADD_ATI = 0x8745, + GL_MODULATE_SUBTRACT_ATI = 0x8746, + GL_SET_AMD = 0x874A, + GL_REPLACE_VALUE_AMD = 0x874B, + GL_STENCIL_OP_VALUE_AMD = 0x874C, + GL_STENCIL_BACK_OP_VALUE_AMD = 0x874D, + GL_VERTEX_ATTRIB_ARRAY_LONG = 0x874E, + GL_OCCLUSION_QUERY_EVENT_MASK_AMD = 0x874F, + GL_DEPTH_STENCIL_MESA = 0x8750, + GL_UNSIGNED_INT_24_8_MESA = 0x8751, + GL_UNSIGNED_INT_8_24_REV_MESA = 0x8752, + GL_UNSIGNED_SHORT_15_1_MESA = 0x8753, + GL_UNSIGNED_SHORT_1_15_REV_MESA = 0x8754, + GL_TRACE_MASK_MESA = 0x8755, + GL_TRACE_NAME_MESA = 0x8756, + GL_YCBCR_MESA = 0x8757, + GL_PACK_INVERT_MESA = 0x8758, + GL_DEBUG_OBJECT_MESA = 0x8759, + GL_TEXTURE_1D_STACK_MESAX = 0x8759, + GL_DEBUG_PRINT_MESA = 0x875A, + GL_TEXTURE_2D_STACK_MESAX = 0x875A, + GL_DEBUG_ASSERT_MESA = 0x875B, + GL_PROXY_TEXTURE_1D_STACK_MESAX = 0x875B, + GL_PROXY_TEXTURE_2D_STACK_MESAX = 0x875C, + GL_TEXTURE_1D_STACK_BINDING_MESAX = 0x875D, + GL_TEXTURE_2D_STACK_BINDING_MESAX = 0x875E, + GL_PROGRAM_BINARY_FORMAT_MESA = 0x875F, + GL_STATIC_ATI = 0x8760, + GL_DYNAMIC_ATI = 0x8761, + GL_PRESERVE_ATI = 0x8762, + GL_DISCARD_ATI = 0x8763, + GL_BUFFER_SIZE = 0x8764, + GL_BUFFER_SIZE_ARB = 0x8764, + GL_OBJECT_BUFFER_SIZE_ATI = 0x8764, + GL_BUFFER_USAGE = 0x8765, + GL_BUFFER_USAGE_ARB = 0x8765, + GL_OBJECT_BUFFER_USAGE_ATI = 0x8765, + GL_ARRAY_OBJECT_BUFFER_ATI = 0x8766, + GL_ARRAY_OBJECT_OFFSET_ATI = 0x8767, + GL_ELEMENT_ARRAY_ATI = 0x8768, + GL_ELEMENT_ARRAY_TYPE_ATI = 0x8769, + GL_ELEMENT_ARRAY_POINTER_ATI = 0x876A, + GL_MAX_VERTEX_STREAMS_ATI = 0x876B, + GL_VERTEX_STREAM0_ATI = 0x876C, + GL_VERTEX_STREAM1_ATI = 0x876D, + GL_VERTEX_STREAM2_ATI = 0x876E, + GL_VERTEX_STREAM3_ATI = 0x876F, + GL_VERTEX_STREAM4_ATI = 0x8770, + GL_VERTEX_STREAM5_ATI = 0x8771, + GL_VERTEX_STREAM6_ATI = 0x8772, + GL_VERTEX_STREAM7_ATI = 0x8773, + GL_VERTEX_SOURCE_ATI = 0x8774, + GL_BUMP_ROT_MATRIX_ATI = 0x8775, + GL_BUMP_ROT_MATRIX_SIZE_ATI = 0x8776, + GL_BUMP_NUM_TEX_UNITS_ATI = 0x8777, + GL_BUMP_TEX_UNITS_ATI = 0x8778, + GL_DUDV_ATI = 0x8779, + GL_DU8DV8_ATI = 0x877A, + GL_BUMP_ENVMAP_ATI = 0x877B, + GL_BUMP_TARGET_ATI = 0x877C, + GL_VERTEX_SHADER_EXT = 0x8780, + GL_VERTEX_SHADER_BINDING_EXT = 0x8781, + GL_OP_INDEX_EXT = 0x8782, + GL_OP_NEGATE_EXT = 0x8783, + GL_OP_DOT3_EXT = 0x8784, + GL_OP_DOT4_EXT = 0x8785, + GL_OP_MUL_EXT = 0x8786, + GL_OP_ADD_EXT = 0x8787, + GL_OP_MADD_EXT = 0x8788, + GL_OP_FRAC_EXT = 0x8789, + GL_OP_MAX_EXT = 0x878A, + GL_OP_MIN_EXT = 0x878B, + GL_OP_SET_GE_EXT = 0x878C, + GL_OP_SET_LT_EXT = 0x878D, + GL_OP_CLAMP_EXT = 0x878E, + GL_OP_FLOOR_EXT = 0x878F, + GL_OP_ROUND_EXT = 0x8790, + GL_OP_EXP_BASE_2_EXT = 0x8791, + GL_OP_LOG_BASE_2_EXT = 0x8792, + GL_OP_POWER_EXT = 0x8793, + GL_OP_RECIP_EXT = 0x8794, + GL_OP_RECIP_SQRT_EXT = 0x8795, + GL_OP_SUB_EXT = 0x8796, + GL_OP_CROSS_PRODUCT_EXT = 0x8797, + GL_OP_MULTIPLY_MATRIX_EXT = 0x8798, + GL_OP_MOV_EXT = 0x8799, + GL_OUTPUT_VERTEX_EXT = 0x879A, + GL_OUTPUT_COLOR0_EXT = 0x879B, + GL_OUTPUT_COLOR1_EXT = 0x879C, + GL_OUTPUT_TEXTURE_COORD0_EXT = 0x879D, + GL_OUTPUT_TEXTURE_COORD1_EXT = 0x879E, + GL_OUTPUT_TEXTURE_COORD2_EXT = 0x879F, + GL_OUTPUT_TEXTURE_COORD3_EXT = 0x87A0, + GL_OUTPUT_TEXTURE_COORD4_EXT = 0x87A1, + GL_OUTPUT_TEXTURE_COORD5_EXT = 0x87A2, + GL_OUTPUT_TEXTURE_COORD6_EXT = 0x87A3, + GL_OUTPUT_TEXTURE_COORD7_EXT = 0x87A4, + GL_OUTPUT_TEXTURE_COORD8_EXT = 0x87A5, + GL_OUTPUT_TEXTURE_COORD9_EXT = 0x87A6, + GL_OUTPUT_TEXTURE_COORD10_EXT = 0x87A7, + GL_OUTPUT_TEXTURE_COORD11_EXT = 0x87A8, + GL_OUTPUT_TEXTURE_COORD12_EXT = 0x87A9, + GL_OUTPUT_TEXTURE_COORD13_EXT = 0x87AA, + GL_OUTPUT_TEXTURE_COORD14_EXT = 0x87AB, + GL_OUTPUT_TEXTURE_COORD15_EXT = 0x87AC, + GL_OUTPUT_TEXTURE_COORD16_EXT = 0x87AD, + GL_OUTPUT_TEXTURE_COORD17_EXT = 0x87AE, + GL_OUTPUT_TEXTURE_COORD18_EXT = 0x87AF, + GL_OUTPUT_TEXTURE_COORD19_EXT = 0x87B0, + GL_OUTPUT_TEXTURE_COORD20_EXT = 0x87B1, + GL_OUTPUT_TEXTURE_COORD21_EXT = 0x87B2, + GL_OUTPUT_TEXTURE_COORD22_EXT = 0x87B3, + GL_OUTPUT_TEXTURE_COORD23_EXT = 0x87B4, + GL_OUTPUT_TEXTURE_COORD24_EXT = 0x87B5, + GL_OUTPUT_TEXTURE_COORD25_EXT = 0x87B6, + GL_OUTPUT_TEXTURE_COORD26_EXT = 0x87B7, + GL_OUTPUT_TEXTURE_COORD27_EXT = 0x87B8, + GL_OUTPUT_TEXTURE_COORD28_EXT = 0x87B9, + GL_OUTPUT_TEXTURE_COORD29_EXT = 0x87BA, + GL_OUTPUT_TEXTURE_COORD30_EXT = 0x87BB, + GL_OUTPUT_TEXTURE_COORD31_EXT = 0x87BC, + GL_OUTPUT_FOG_EXT = 0x87BD, + GL_SCALAR_EXT = 0x87BE, + GL_VECTOR_EXT = 0x87BF, + GL_MATRIX_EXT = 0x87C0, + GL_VARIANT_EXT = 0x87C1, + GL_INVARIANT_EXT = 0x87C2, + GL_LOCAL_CONSTANT_EXT = 0x87C3, + GL_LOCAL_EXT = 0x87C4, + GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87C5, + GL_MAX_VERTEX_SHADER_VARIANTS_EXT = 0x87C6, + GL_MAX_VERTEX_SHADER_INVARIANTS_EXT = 0x87C7, + GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87C8, + GL_MAX_VERTEX_SHADER_LOCALS_EXT = 0x87C9, + GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87CA, + GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = 0x87CB, + GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87CC, + GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = 0x87CD, + GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = 0x87CE, + GL_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87CF, + GL_VERTEX_SHADER_VARIANTS_EXT = 0x87D0, + GL_VERTEX_SHADER_INVARIANTS_EXT = 0x87D1, + GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87D2, + GL_VERTEX_SHADER_LOCALS_EXT = 0x87D3, + GL_VERTEX_SHADER_OPTIMIZED_EXT = 0x87D4, + GL_X_EXT = 0x87D5, + GL_Y_EXT = 0x87D6, + GL_Z_EXT = 0x87D7, + GL_W_EXT = 0x87D8, + GL_NEGATIVE_X_EXT = 0x87D9, + GL_NEGATIVE_Y_EXT = 0x87DA, + GL_NEGATIVE_Z_EXT = 0x87DB, + GL_NEGATIVE_W_EXT = 0x87DC, + GL_ZERO_EXT = 0x87DD, + GL_ONE_EXT = 0x87DE, + GL_NEGATIVE_ONE_EXT = 0x87DF, + GL_NORMALIZED_RANGE_EXT = 0x87E0, + GL_FULL_RANGE_EXT = 0x87E1, + GL_CURRENT_VERTEX_EXT = 0x87E2, + GL_MVP_MATRIX_EXT = 0x87E3, + GL_VARIANT_VALUE_EXT = 0x87E4, + GL_VARIANT_DATATYPE_EXT = 0x87E5, + GL_VARIANT_ARRAY_STRIDE_EXT = 0x87E6, + GL_VARIANT_ARRAY_TYPE_EXT = 0x87E7, + GL_VARIANT_ARRAY_EXT = 0x87E8, + GL_VARIANT_ARRAY_POINTER_EXT = 0x87E9, + GL_INVARIANT_VALUE_EXT = 0x87EA, + GL_INVARIANT_DATATYPE_EXT = 0x87EB, + GL_LOCAL_CONSTANT_VALUE_EXT = 0x87EC, + GL_LOCAL_CONSTANT_DATATYPE_EXT = 0x87ED, + GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD = 0x87EE, + GL_PN_TRIANGLES_ATI = 0x87F0, + GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F1, + GL_PN_TRIANGLES_POINT_MODE_ATI = 0x87F2, + GL_PN_TRIANGLES_NORMAL_MODE_ATI = 0x87F3, + GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F4, + GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = 0x87F5, + GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = 0x87F6, + GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = 0x87F7, + GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = 0x87F8, + GL_3DC_X_AMD = 0x87F9, + GL_3DC_XY_AMD = 0x87FA, + GL_VBO_FREE_MEMORY_ATI = 0x87FB, + GL_TEXTURE_FREE_MEMORY_ATI = 0x87FC, + GL_RENDERBUFFER_FREE_MEMORY_ATI = 0x87FD, + GL_NUM_PROGRAM_BINARY_FORMATS = 0x87FE, + GL_NUM_PROGRAM_BINARY_FORMATS_OES = 0x87FE, + GL_PROGRAM_BINARY_FORMATS = 0x87FF, + GL_PROGRAM_BINARY_FORMATS_OES = 0x87FF, + GL_STENCIL_BACK_FUNC = 0x8800, + GL_STENCIL_BACK_FUNC_ATI = 0x8800, + GL_STENCIL_BACK_FAIL = 0x8801, + GL_STENCIL_BACK_FAIL_ATI = 0x8801, + GL_STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802, + GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = 0x8802, + GL_STENCIL_BACK_PASS_DEPTH_PASS = 0x8803, + GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = 0x8803, + GL_FRAGMENT_PROGRAM_ARB = 0x8804, + GL_PROGRAM_ALU_INSTRUCTIONS_ARB = 0x8805, + GL_PROGRAM_TEX_INSTRUCTIONS_ARB = 0x8806, + GL_PROGRAM_TEX_INDIRECTIONS_ARB = 0x8807, + GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = 0x8808, + GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = 0x8809, + GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = 0x880A, + GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = 0x880B, + GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = 0x880C, + GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = 0x880D, + GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = 0x880E, + GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = 0x880F, + GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = 0x8810, + GL_RGBA32F = 0x8814, + GL_RGBA32F_ARB = 0x8814, + GL_RGBA32F_EXT = 0x8814, + GL_RGBA_FLOAT32_APPLE = 0x8814, + GL_RGBA_FLOAT32_ATI = 0x8814, + GL_RGB32F = 0x8815, + GL_RGB32F_ARB = 0x8815, + GL_RGB32F_EXT = 0x8815, + GL_RGB_FLOAT32_APPLE = 0x8815, + GL_RGB_FLOAT32_ATI = 0x8815, + GL_ALPHA32F_ARB = 0x8816, + GL_ALPHA32F_EXT = 0x8816, + GL_ALPHA_FLOAT32_APPLE = 0x8816, + GL_ALPHA_FLOAT32_ATI = 0x8816, + GL_INTENSITY32F_ARB = 0x8817, + GL_INTENSITY_FLOAT32_APPLE = 0x8817, + GL_INTENSITY_FLOAT32_ATI = 0x8817, + GL_LUMINANCE32F_ARB = 0x8818, + GL_LUMINANCE32F_EXT = 0x8818, + GL_LUMINANCE_FLOAT32_APPLE = 0x8818, + GL_LUMINANCE_FLOAT32_ATI = 0x8818, + GL_LUMINANCE_ALPHA32F_ARB = 0x8819, + GL_LUMINANCE_ALPHA32F_EXT = 0x8819, + GL_LUMINANCE_ALPHA_FLOAT32_APPLE = 0x8819, + GL_LUMINANCE_ALPHA_FLOAT32_ATI = 0x8819, + GL_RGBA16F = 0x881A, + GL_RGBA16F_ARB = 0x881A, + GL_RGBA16F_EXT = 0x881A, + GL_RGBA_FLOAT16_APPLE = 0x881A, + GL_RGBA_FLOAT16_ATI = 0x881A, + GL_RGB16F = 0x881B, + GL_RGB16F_ARB = 0x881B, + GL_RGB16F_EXT = 0x881B, + GL_RGB_FLOAT16_APPLE = 0x881B, + GL_RGB_FLOAT16_ATI = 0x881B, + GL_ALPHA16F_ARB = 0x881C, + GL_ALPHA16F_EXT = 0x881C, + GL_ALPHA_FLOAT16_APPLE = 0x881C, + GL_ALPHA_FLOAT16_ATI = 0x881C, + GL_INTENSITY16F_ARB = 0x881D, + GL_INTENSITY_FLOAT16_APPLE = 0x881D, + GL_INTENSITY_FLOAT16_ATI = 0x881D, + GL_LUMINANCE16F_ARB = 0x881E, + GL_LUMINANCE16F_EXT = 0x881E, + GL_LUMINANCE_FLOAT16_APPLE = 0x881E, + GL_LUMINANCE_FLOAT16_ATI = 0x881E, + GL_LUMINANCE_ALPHA16F_ARB = 0x881F, + GL_LUMINANCE_ALPHA16F_EXT = 0x881F, + GL_LUMINANCE_ALPHA_FLOAT16_APPLE = 0x881F, + GL_LUMINANCE_ALPHA_FLOAT16_ATI = 0x881F, + GL_RGBA_FLOAT_MODE_ARB = 0x8820, + GL_RGBA_FLOAT_MODE_ATI = 0x8820, + GL_WRITEONLY_RENDERING_QCOM = 0x8823, + GL_MAX_DRAW_BUFFERS = 0x8824, + GL_MAX_DRAW_BUFFERS_ARB = 0x8824, + GL_MAX_DRAW_BUFFERS_ATI = 0x8824, + GL_MAX_DRAW_BUFFERS_EXT = 0x8824, + GL_MAX_DRAW_BUFFERS_NV = 0x8824, + GL_DRAW_BUFFER0 = 0x8825, + GL_DRAW_BUFFER0_ARB = 0x8825, + GL_DRAW_BUFFER0_ATI = 0x8825, + GL_DRAW_BUFFER0_EXT = 0x8825, + GL_DRAW_BUFFER0_NV = 0x8825, + GL_DRAW_BUFFER1 = 0x8826, + GL_DRAW_BUFFER1_ARB = 0x8826, + GL_DRAW_BUFFER1_ATI = 0x8826, + GL_DRAW_BUFFER1_EXT = 0x8826, + GL_DRAW_BUFFER1_NV = 0x8826, + GL_DRAW_BUFFER2 = 0x8827, + GL_DRAW_BUFFER2_ARB = 0x8827, + GL_DRAW_BUFFER2_ATI = 0x8827, + GL_DRAW_BUFFER2_EXT = 0x8827, + GL_DRAW_BUFFER2_NV = 0x8827, + GL_DRAW_BUFFER3 = 0x8828, + GL_DRAW_BUFFER3_ARB = 0x8828, + GL_DRAW_BUFFER3_ATI = 0x8828, + GL_DRAW_BUFFER3_EXT = 0x8828, + GL_DRAW_BUFFER3_NV = 0x8828, + GL_DRAW_BUFFER4 = 0x8829, + GL_DRAW_BUFFER4_ARB = 0x8829, + GL_DRAW_BUFFER4_ATI = 0x8829, + GL_DRAW_BUFFER4_EXT = 0x8829, + GL_DRAW_BUFFER4_NV = 0x8829, + GL_DRAW_BUFFER5 = 0x882A, + GL_DRAW_BUFFER5_ARB = 0x882A, + GL_DRAW_BUFFER5_ATI = 0x882A, + GL_DRAW_BUFFER5_EXT = 0x882A, + GL_DRAW_BUFFER5_NV = 0x882A, + GL_DRAW_BUFFER6 = 0x882B, + GL_DRAW_BUFFER6_ARB = 0x882B, + GL_DRAW_BUFFER6_ATI = 0x882B, + GL_DRAW_BUFFER6_EXT = 0x882B, + GL_DRAW_BUFFER6_NV = 0x882B, + GL_DRAW_BUFFER7 = 0x882C, + GL_DRAW_BUFFER7_ARB = 0x882C, + GL_DRAW_BUFFER7_ATI = 0x882C, + GL_DRAW_BUFFER7_EXT = 0x882C, + GL_DRAW_BUFFER7_NV = 0x882C, + GL_DRAW_BUFFER8 = 0x882D, + GL_DRAW_BUFFER8_ARB = 0x882D, + GL_DRAW_BUFFER8_ATI = 0x882D, + GL_DRAW_BUFFER8_EXT = 0x882D, + GL_DRAW_BUFFER8_NV = 0x882D, + GL_DRAW_BUFFER9 = 0x882E, + GL_DRAW_BUFFER9_ARB = 0x882E, + GL_DRAW_BUFFER9_ATI = 0x882E, + GL_DRAW_BUFFER9_EXT = 0x882E, + GL_DRAW_BUFFER9_NV = 0x882E, + GL_DRAW_BUFFER10 = 0x882F, + GL_DRAW_BUFFER10_ARB = 0x882F, + GL_DRAW_BUFFER10_ATI = 0x882F, + GL_DRAW_BUFFER10_EXT = 0x882F, + GL_DRAW_BUFFER10_NV = 0x882F, + GL_DRAW_BUFFER11 = 0x8830, + GL_DRAW_BUFFER11_ARB = 0x8830, + GL_DRAW_BUFFER11_ATI = 0x8830, + GL_DRAW_BUFFER11_EXT = 0x8830, + GL_DRAW_BUFFER11_NV = 0x8830, + GL_DRAW_BUFFER12 = 0x8831, + GL_DRAW_BUFFER12_ARB = 0x8831, + GL_DRAW_BUFFER12_ATI = 0x8831, + GL_DRAW_BUFFER12_EXT = 0x8831, + GL_DRAW_BUFFER12_NV = 0x8831, + GL_DRAW_BUFFER13 = 0x8832, + GL_DRAW_BUFFER13_ARB = 0x8832, + GL_DRAW_BUFFER13_ATI = 0x8832, + GL_DRAW_BUFFER13_EXT = 0x8832, + GL_DRAW_BUFFER13_NV = 0x8832, + GL_DRAW_BUFFER14 = 0x8833, + GL_DRAW_BUFFER14_ARB = 0x8833, + GL_DRAW_BUFFER14_ATI = 0x8833, + GL_DRAW_BUFFER14_EXT = 0x8833, + GL_DRAW_BUFFER14_NV = 0x8833, + GL_DRAW_BUFFER15 = 0x8834, + GL_DRAW_BUFFER15_ARB = 0x8834, + GL_DRAW_BUFFER15_ATI = 0x8834, + GL_DRAW_BUFFER15_EXT = 0x8834, + GL_DRAW_BUFFER15_NV = 0x8834, + GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = 0x8835, + GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI = 0x8837, + GL_BLEND_EQUATION_ALPHA = 0x883D, + GL_BLEND_EQUATION_ALPHA_EXT = 0x883D, + GL_BLEND_EQUATION_ALPHA_OES = 0x883D, + GL_SUBSAMPLE_DISTANCE_AMD = 0x883F, + GL_MATRIX_PALETTE_ARB = 0x8840, + GL_MATRIX_PALETTE_OES = 0x8840, + GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = 0x8841, + GL_MAX_PALETTE_MATRICES_ARB = 0x8842, + GL_MAX_PALETTE_MATRICES_OES = 0x8842, + GL_CURRENT_PALETTE_MATRIX_ARB = 0x8843, + GL_CURRENT_PALETTE_MATRIX_OES = 0x8843, + GL_MATRIX_INDEX_ARRAY_ARB = 0x8844, + GL_MATRIX_INDEX_ARRAY_OES = 0x8844, + GL_CURRENT_MATRIX_INDEX_ARB = 0x8845, + GL_MATRIX_INDEX_ARRAY_SIZE_ARB = 0x8846, + GL_MATRIX_INDEX_ARRAY_SIZE_OES = 0x8846, + GL_MATRIX_INDEX_ARRAY_TYPE_ARB = 0x8847, + GL_MATRIX_INDEX_ARRAY_TYPE_OES = 0x8847, + GL_MATRIX_INDEX_ARRAY_STRIDE_ARB = 0x8848, + GL_MATRIX_INDEX_ARRAY_STRIDE_OES = 0x8848, + GL_MATRIX_INDEX_ARRAY_POINTER_ARB = 0x8849, + GL_MATRIX_INDEX_ARRAY_POINTER_OES = 0x8849, + GL_TEXTURE_DEPTH_SIZE = 0x884A, + GL_TEXTURE_DEPTH_SIZE_ARB = 0x884A, + GL_DEPTH_TEXTURE_MODE = 0x884B, + GL_DEPTH_TEXTURE_MODE_ARB = 0x884B, + GL_TEXTURE_COMPARE_MODE = 0x884C, + GL_TEXTURE_COMPARE_MODE_ARB = 0x884C, + GL_TEXTURE_COMPARE_MODE_EXT = 0x884C, + GL_TEXTURE_COMPARE_FUNC = 0x884D, + GL_TEXTURE_COMPARE_FUNC_ARB = 0x884D, + GL_TEXTURE_COMPARE_FUNC_EXT = 0x884D, + GL_COMPARE_R_TO_TEXTURE = 0x884E, + GL_COMPARE_R_TO_TEXTURE_ARB = 0x884E, + GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT = 0x884E, + GL_COMPARE_REF_TO_TEXTURE = 0x884E, + GL_COMPARE_REF_TO_TEXTURE_EXT = 0x884E, + GL_TEXTURE_CUBE_MAP_SEAMLESS = 0x884F, + GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = 0x8850, + GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = 0x8851, + GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = 0x8852, + GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = 0x8853, + GL_OFFSET_HILO_TEXTURE_2D_NV = 0x8854, + GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = 0x8855, + GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = 0x8856, + GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = 0x8857, + GL_DEPENDENT_HILO_TEXTURE_2D_NV = 0x8858, + GL_DEPENDENT_RGB_TEXTURE_3D_NV = 0x8859, + GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = 0x885A, + GL_DOT_PRODUCT_PASS_THROUGH_NV = 0x885B, + GL_DOT_PRODUCT_TEXTURE_1D_NV = 0x885C, + GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = 0x885D, + GL_HILO8_NV = 0x885E, + GL_SIGNED_HILO8_NV = 0x885F, + GL_FORCE_BLUE_TO_ONE_NV = 0x8860, + GL_POINT_SPRITE = 0x8861, + GL_POINT_SPRITE_ARB = 0x8861, + GL_POINT_SPRITE_NV = 0x8861, + GL_POINT_SPRITE_OES = 0x8861, + GL_COORD_REPLACE = 0x8862, + GL_COORD_REPLACE_ARB = 0x8862, + GL_COORD_REPLACE_NV = 0x8862, + GL_COORD_REPLACE_OES = 0x8862, + GL_POINT_SPRITE_R_MODE_NV = 0x8863, + GL_PIXEL_COUNTER_BITS_NV = 0x8864, + GL_QUERY_COUNTER_BITS = 0x8864, + GL_QUERY_COUNTER_BITS_ARB = 0x8864, + GL_QUERY_COUNTER_BITS_EXT = 0x8864, + GL_CURRENT_OCCLUSION_QUERY_ID_NV = 0x8865, + GL_CURRENT_QUERY = 0x8865, + GL_CURRENT_QUERY_ARB = 0x8865, + GL_CURRENT_QUERY_EXT = 0x8865, + GL_PIXEL_COUNT_NV = 0x8866, + GL_QUERY_RESULT = 0x8866, + GL_QUERY_RESULT_ARB = 0x8866, + GL_QUERY_RESULT_EXT = 0x8866, + GL_PIXEL_COUNT_AVAILABLE_NV = 0x8867, + GL_QUERY_RESULT_AVAILABLE = 0x8867, + GL_QUERY_RESULT_AVAILABLE_ARB = 0x8867, + GL_QUERY_RESULT_AVAILABLE_EXT = 0x8867, + GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = 0x8868, + GL_MAX_VERTEX_ATTRIBS = 0x8869, + GL_MAX_VERTEX_ATTRIBS_ARB = 0x8869, + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A, + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = 0x886A, + GL_MAX_TESS_CONTROL_INPUT_COMPONENTS = 0x886C, + GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT = 0x886C, + GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES = 0x886C, + GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS = 0x886D, + GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT = 0x886D, + GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES = 0x886D, + GL_DEPTH_STENCIL_TO_RGBA_NV = 0x886E, + GL_DEPTH_STENCIL_TO_BGRA_NV = 0x886F, + GL_FRAGMENT_PROGRAM_NV = 0x8870, + GL_MAX_TEXTURE_COORDS = 0x8871, + GL_MAX_TEXTURE_COORDS_ARB = 0x8871, + GL_MAX_TEXTURE_COORDS_NV = 0x8871, + GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872, + GL_MAX_TEXTURE_IMAGE_UNITS_ARB = 0x8872, + GL_MAX_TEXTURE_IMAGE_UNITS_NV = 0x8872, + GL_FRAGMENT_PROGRAM_BINDING_NV = 0x8873, + GL_PROGRAM_ERROR_STRING_ARB = 0x8874, + GL_PROGRAM_ERROR_STRING_NV = 0x8874, + GL_PROGRAM_FORMAT_ASCII_ARB = 0x8875, + GL_PROGRAM_FORMAT_ARB = 0x8876, + GL_WRITE_PIXEL_DATA_RANGE_NV = 0x8878, + GL_READ_PIXEL_DATA_RANGE_NV = 0x8879, + GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = 0x887A, + GL_READ_PIXEL_DATA_RANGE_LENGTH_NV = 0x887B, + GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = 0x887C, + GL_READ_PIXEL_DATA_RANGE_POINTER_NV = 0x887D, + GL_GEOMETRY_SHADER_INVOCATIONS = 0x887F, + GL_GEOMETRY_SHADER_INVOCATIONS_EXT = 0x887F, + GL_GEOMETRY_SHADER_INVOCATIONS_OES = 0x887F, + GL_FLOAT_R_NV = 0x8880, + GL_FLOAT_RG_NV = 0x8881, + GL_FLOAT_RGB_NV = 0x8882, + GL_FLOAT_RGBA_NV = 0x8883, + GL_FLOAT_R16_NV = 0x8884, + GL_FLOAT_R32_NV = 0x8885, + GL_FLOAT_RG16_NV = 0x8886, + GL_FLOAT_RG32_NV = 0x8887, + GL_FLOAT_RGB16_NV = 0x8888, + GL_FLOAT_RGB32_NV = 0x8889, + GL_FLOAT_RGBA16_NV = 0x888A, + GL_FLOAT_RGBA32_NV = 0x888B, + GL_TEXTURE_FLOAT_COMPONENTS_NV = 0x888C, + GL_FLOAT_CLEAR_COLOR_VALUE_NV = 0x888D, + GL_FLOAT_RGBA_MODE_NV = 0x888E, + GL_TEXTURE_UNSIGNED_REMAP_MODE_NV = 0x888F, + GL_DEPTH_BOUNDS_TEST_EXT = 0x8890, + GL_DEPTH_BOUNDS_EXT = 0x8891, + GL_ARRAY_BUFFER = 0x8892, + GL_ARRAY_BUFFER_ARB = 0x8892, + GL_ELEMENT_ARRAY_BUFFER = 0x8893, + GL_ELEMENT_ARRAY_BUFFER_ARB = 0x8893, + GL_ARRAY_BUFFER_BINDING = 0x8894, + GL_ARRAY_BUFFER_BINDING_ARB = 0x8894, + GL_ELEMENT_ARRAY_BUFFER_BINDING = 0x8895, + GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = 0x8895, + GL_VERTEX_ARRAY_BUFFER_BINDING = 0x8896, + GL_VERTEX_ARRAY_BUFFER_BINDING_ARB = 0x8896, + GL_NORMAL_ARRAY_BUFFER_BINDING = 0x8897, + GL_NORMAL_ARRAY_BUFFER_BINDING_ARB = 0x8897, + GL_COLOR_ARRAY_BUFFER_BINDING = 0x8898, + GL_COLOR_ARRAY_BUFFER_BINDING_ARB = 0x8898, + GL_INDEX_ARRAY_BUFFER_BINDING = 0x8899, + GL_INDEX_ARRAY_BUFFER_BINDING_ARB = 0x8899, + GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = 0x889A, + GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = 0x889A, + GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = 0x889B, + GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = 0x889B, + GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = 0x889C, + GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = 0x889C, + GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = 0x889D, + GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = 0x889D, + GL_FOG_COORD_ARRAY_BUFFER_BINDING = 0x889D, + GL_WEIGHT_ARRAY_BUFFER_BINDING = 0x889E, + GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = 0x889E, + GL_WEIGHT_ARRAY_BUFFER_BINDING_OES = 0x889E, + GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F, + GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = 0x889F, + GL_PROGRAM_INSTRUCTIONS_ARB = 0x88A0, + GL_MAX_PROGRAM_INSTRUCTIONS_ARB = 0x88A1, + GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = 0x88A2, + GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = 0x88A3, + GL_PROGRAM_TEMPORARIES_ARB = 0x88A4, + GL_MAX_PROGRAM_TEMPORARIES_ARB = 0x88A5, + GL_PROGRAM_NATIVE_TEMPORARIES_ARB = 0x88A6, + GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = 0x88A7, + GL_PROGRAM_PARAMETERS_ARB = 0x88A8, + GL_MAX_PROGRAM_PARAMETERS_ARB = 0x88A9, + GL_PROGRAM_NATIVE_PARAMETERS_ARB = 0x88AA, + GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = 0x88AB, + GL_PROGRAM_ATTRIBS_ARB = 0x88AC, + GL_MAX_PROGRAM_ATTRIBS_ARB = 0x88AD, + GL_PROGRAM_NATIVE_ATTRIBS_ARB = 0x88AE, + GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = 0x88AF, + GL_PROGRAM_ADDRESS_REGISTERS_ARB = 0x88B0, + GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = 0x88B1, + GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = 0x88B2, + GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = 0x88B3, + GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = 0x88B4, + GL_MAX_PROGRAM_ENV_PARAMETERS_ARB = 0x88B5, + GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = 0x88B6, + GL_TRANSPOSE_CURRENT_MATRIX_ARB = 0x88B7, + GL_READ_ONLY = 0x88B8, + GL_READ_ONLY_ARB = 0x88B8, + GL_WRITE_ONLY = 0x88B9, + GL_WRITE_ONLY_ARB = 0x88B9, + GL_WRITE_ONLY_OES = 0x88B9, + GL_READ_WRITE = 0x88BA, + GL_READ_WRITE_ARB = 0x88BA, + GL_BUFFER_ACCESS = 0x88BB, + GL_BUFFER_ACCESS_ARB = 0x88BB, + GL_BUFFER_ACCESS_OES = 0x88BB, + GL_BUFFER_MAPPED = 0x88BC, + GL_BUFFER_MAPPED_ARB = 0x88BC, + GL_BUFFER_MAPPED_OES = 0x88BC, + GL_BUFFER_MAP_POINTER = 0x88BD, + GL_BUFFER_MAP_POINTER_ARB = 0x88BD, + GL_BUFFER_MAP_POINTER_OES = 0x88BD, + GL_WRITE_DISCARD_NV = 0x88BE, + GL_TIME_ELAPSED = 0x88BF, + GL_TIME_ELAPSED_EXT = 0x88BF, + GL_MATRIX0_ARB = 0x88C0, + GL_MATRIX1_ARB = 0x88C1, + GL_MATRIX2_ARB = 0x88C2, + GL_MATRIX3_ARB = 0x88C3, + GL_MATRIX4_ARB = 0x88C4, + GL_MATRIX5_ARB = 0x88C5, + GL_MATRIX6_ARB = 0x88C6, + GL_MATRIX7_ARB = 0x88C7, + GL_MATRIX8_ARB = 0x88C8, + GL_MATRIX9_ARB = 0x88C9, + GL_MATRIX10_ARB = 0x88CA, + GL_MATRIX11_ARB = 0x88CB, + GL_MATRIX12_ARB = 0x88CC, + GL_MATRIX13_ARB = 0x88CD, + GL_MATRIX14_ARB = 0x88CE, + GL_MATRIX15_ARB = 0x88CF, + GL_MATRIX16_ARB = 0x88D0, + GL_MATRIX17_ARB = 0x88D1, + GL_MATRIX18_ARB = 0x88D2, + GL_MATRIX19_ARB = 0x88D3, + GL_MATRIX20_ARB = 0x88D4, + GL_MATRIX21_ARB = 0x88D5, + GL_MATRIX22_ARB = 0x88D6, + GL_MATRIX23_ARB = 0x88D7, + GL_MATRIX24_ARB = 0x88D8, + GL_MATRIX25_ARB = 0x88D9, + GL_MATRIX26_ARB = 0x88DA, + GL_MATRIX27_ARB = 0x88DB, + GL_MATRIX28_ARB = 0x88DC, + GL_MATRIX29_ARB = 0x88DD, + GL_MATRIX30_ARB = 0x88DE, + GL_MATRIX31_ARB = 0x88DF, + GL_STREAM_DRAW = 0x88E0, + GL_STREAM_DRAW_ARB = 0x88E0, + GL_STREAM_READ = 0x88E1, + GL_STREAM_READ_ARB = 0x88E1, + GL_STREAM_COPY = 0x88E2, + GL_STREAM_COPY_ARB = 0x88E2, + GL_STATIC_DRAW = 0x88E4, + GL_STATIC_DRAW_ARB = 0x88E4, + GL_STATIC_READ = 0x88E5, + GL_STATIC_READ_ARB = 0x88E5, + GL_STATIC_COPY = 0x88E6, + GL_STATIC_COPY_ARB = 0x88E6, + GL_DYNAMIC_DRAW = 0x88E8, + GL_DYNAMIC_DRAW_ARB = 0x88E8, + GL_DYNAMIC_READ = 0x88E9, + GL_DYNAMIC_READ_ARB = 0x88E9, + GL_DYNAMIC_COPY = 0x88EA, + GL_DYNAMIC_COPY_ARB = 0x88EA, + GL_PIXEL_PACK_BUFFER = 0x88EB, + GL_PIXEL_PACK_BUFFER_ARB = 0x88EB, + GL_PIXEL_PACK_BUFFER_EXT = 0x88EB, + GL_PIXEL_PACK_BUFFER_NV = 0x88EB, + GL_PIXEL_UNPACK_BUFFER = 0x88EC, + GL_PIXEL_UNPACK_BUFFER_ARB = 0x88EC, + GL_PIXEL_UNPACK_BUFFER_EXT = 0x88EC, + GL_PIXEL_UNPACK_BUFFER_NV = 0x88EC, + GL_PIXEL_PACK_BUFFER_BINDING = 0x88ED, + GL_PIXEL_PACK_BUFFER_BINDING_ARB = 0x88ED, + GL_PIXEL_PACK_BUFFER_BINDING_EXT = 0x88ED, + GL_PIXEL_PACK_BUFFER_BINDING_NV = 0x88ED, + GL_ETC1_SRGB8_NV = 0x88EE, + GL_PIXEL_UNPACK_BUFFER_BINDING = 0x88EF, + GL_PIXEL_UNPACK_BUFFER_BINDING_ARB = 0x88EF, + GL_PIXEL_UNPACK_BUFFER_BINDING_EXT = 0x88EF, + GL_PIXEL_UNPACK_BUFFER_BINDING_NV = 0x88EF, + GL_DEPTH24_STENCIL8 = 0x88F0, + GL_DEPTH24_STENCIL8_EXT = 0x88F0, + GL_DEPTH24_STENCIL8_OES = 0x88F0, + GL_TEXTURE_STENCIL_SIZE = 0x88F1, + GL_TEXTURE_STENCIL_SIZE_EXT = 0x88F1, + GL_STENCIL_TAG_BITS_EXT = 0x88F2, + GL_STENCIL_CLEAR_TAG_VALUE_EXT = 0x88F3, + GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = 0x88F4, + GL_MAX_PROGRAM_CALL_DEPTH_NV = 0x88F5, + GL_MAX_PROGRAM_IF_DEPTH_NV = 0x88F6, + GL_MAX_PROGRAM_LOOP_DEPTH_NV = 0x88F7, + GL_MAX_PROGRAM_LOOP_COUNT_NV = 0x88F8, + GL_SRC1_COLOR = 0x88F9, + GL_SRC1_COLOR_EXT = 0x88F9, + GL_ONE_MINUS_SRC1_COLOR = 0x88FA, + GL_ONE_MINUS_SRC1_COLOR_EXT = 0x88FA, + GL_ONE_MINUS_SRC1_ALPHA = 0x88FB, + GL_ONE_MINUS_SRC1_ALPHA_EXT = 0x88FB, + GL_MAX_DUAL_SOURCE_DRAW_BUFFERS = 0x88FC, + GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT = 0x88FC, + GL_VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD, + GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT = 0x88FD, + GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV = 0x88FD, + GL_VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE, + GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE, + GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB = 0x88FE, + GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT = 0x88FE, + GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV = 0x88FE, + GL_MAX_ARRAY_TEXTURE_LAYERS = 0x88FF, + GL_MAX_ARRAY_TEXTURE_LAYERS_EXT = 0x88FF, + GL_MIN_PROGRAM_TEXEL_OFFSET = 0x8904, + GL_MIN_PROGRAM_TEXEL_OFFSET_EXT = 0x8904, + GL_MIN_PROGRAM_TEXEL_OFFSET_NV = 0x8904, + GL_MAX_PROGRAM_TEXEL_OFFSET = 0x8905, + GL_MAX_PROGRAM_TEXEL_OFFSET_EXT = 0x8905, + GL_MAX_PROGRAM_TEXEL_OFFSET_NV = 0x8905, + GL_PROGRAM_ATTRIB_COMPONENTS_NV = 0x8906, + GL_PROGRAM_RESULT_COMPONENTS_NV = 0x8907, + GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV = 0x8908, + GL_MAX_PROGRAM_RESULT_COMPONENTS_NV = 0x8909, + GL_STENCIL_TEST_TWO_SIDE_EXT = 0x8910, + GL_ACTIVE_STENCIL_FACE_EXT = 0x8911, + GL_MIRROR_CLAMP_TO_BORDER_EXT = 0x8912, + GL_SAMPLES_PASSED = 0x8914, + GL_SAMPLES_PASSED_ARB = 0x8914, + GL_GEOMETRY_VERTICES_OUT = 0x8916, + GL_GEOMETRY_LINKED_VERTICES_OUT_EXT = 0x8916, + GL_GEOMETRY_LINKED_VERTICES_OUT_OES = 0x8916, + GL_GEOMETRY_INPUT_TYPE = 0x8917, + GL_GEOMETRY_LINKED_INPUT_TYPE_EXT = 0x8917, + GL_GEOMETRY_LINKED_INPUT_TYPE_OES = 0x8917, + GL_GEOMETRY_OUTPUT_TYPE = 0x8918, + GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT = 0x8918, + GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES = 0x8918, + GL_SAMPLER_BINDING = 0x8919, + GL_CLAMP_VERTEX_COLOR = 0x891A, + GL_CLAMP_VERTEX_COLOR_ARB = 0x891A, + GL_CLAMP_FRAGMENT_COLOR = 0x891B, + GL_CLAMP_FRAGMENT_COLOR_ARB = 0x891B, + GL_CLAMP_READ_COLOR = 0x891C, + GL_CLAMP_READ_COLOR_ARB = 0x891C, + GL_FIXED_ONLY = 0x891D, + GL_FIXED_ONLY_ARB = 0x891D, + GL_TESS_CONTROL_PROGRAM_NV = 0x891E, + GL_TESS_EVALUATION_PROGRAM_NV = 0x891F, + GL_FRAGMENT_SHADER_ATI = 0x8920, + GL_REG_0_ATI = 0x8921, + GL_REG_1_ATI = 0x8922, + GL_REG_2_ATI = 0x8923, + GL_REG_3_ATI = 0x8924, + GL_REG_4_ATI = 0x8925, + GL_REG_5_ATI = 0x8926, + GL_REG_6_ATI = 0x8927, + GL_REG_7_ATI = 0x8928, + GL_REG_8_ATI = 0x8929, + GL_REG_9_ATI = 0x892A, + GL_REG_10_ATI = 0x892B, + GL_REG_11_ATI = 0x892C, + GL_REG_12_ATI = 0x892D, + GL_REG_13_ATI = 0x892E, + GL_REG_14_ATI = 0x892F, + GL_REG_15_ATI = 0x8930, + GL_REG_16_ATI = 0x8931, + GL_REG_17_ATI = 0x8932, + GL_REG_18_ATI = 0x8933, + GL_REG_19_ATI = 0x8934, + GL_REG_20_ATI = 0x8935, + GL_REG_21_ATI = 0x8936, + GL_REG_22_ATI = 0x8937, + GL_REG_23_ATI = 0x8938, + GL_REG_24_ATI = 0x8939, + GL_REG_25_ATI = 0x893A, + GL_REG_26_ATI = 0x893B, + GL_REG_27_ATI = 0x893C, + GL_REG_28_ATI = 0x893D, + GL_REG_29_ATI = 0x893E, + GL_REG_30_ATI = 0x893F, + GL_REG_31_ATI = 0x8940, + GL_CON_0_ATI = 0x8941, + GL_CON_1_ATI = 0x8942, + GL_CON_2_ATI = 0x8943, + GL_CON_3_ATI = 0x8944, + GL_CON_4_ATI = 0x8945, + GL_CON_5_ATI = 0x8946, + GL_CON_6_ATI = 0x8947, + GL_CON_7_ATI = 0x8948, + GL_CON_8_ATI = 0x8949, + GL_CON_9_ATI = 0x894A, + GL_CON_10_ATI = 0x894B, + GL_CON_11_ATI = 0x894C, + GL_CON_12_ATI = 0x894D, + GL_CON_13_ATI = 0x894E, + GL_CON_14_ATI = 0x894F, + GL_CON_15_ATI = 0x8950, + GL_CON_16_ATI = 0x8951, + GL_CON_17_ATI = 0x8952, + GL_CON_18_ATI = 0x8953, + GL_CON_19_ATI = 0x8954, + GL_CON_20_ATI = 0x8955, + GL_CON_21_ATI = 0x8956, + GL_CON_22_ATI = 0x8957, + GL_CON_23_ATI = 0x8958, + GL_CON_24_ATI = 0x8959, + GL_CON_25_ATI = 0x895A, + GL_CON_26_ATI = 0x895B, + GL_CON_27_ATI = 0x895C, + GL_CON_28_ATI = 0x895D, + GL_CON_29_ATI = 0x895E, + GL_CON_30_ATI = 0x895F, + GL_CON_31_ATI = 0x8960, + GL_MOV_ATI = 0x8961, + GL_ADD_ATI = 0x8963, + GL_MUL_ATI = 0x8964, + GL_SUB_ATI = 0x8965, + GL_DOT3_ATI = 0x8966, + GL_DOT4_ATI = 0x8967, + GL_MAD_ATI = 0x8968, + GL_LERP_ATI = 0x8969, + GL_CND_ATI = 0x896A, + GL_CND0_ATI = 0x896B, + GL_DOT2_ADD_ATI = 0x896C, + GL_SECONDARY_INTERPOLATOR_ATI = 0x896D, + GL_NUM_FRAGMENT_REGISTERS_ATI = 0x896E, + GL_NUM_FRAGMENT_CONSTANTS_ATI = 0x896F, + GL_NUM_PASSES_ATI = 0x8970, + GL_NUM_INSTRUCTIONS_PER_PASS_ATI = 0x8971, + GL_NUM_INSTRUCTIONS_TOTAL_ATI = 0x8972, + GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI = 0x8973, + GL_NUM_LOOPBACK_COMPONENTS_ATI = 0x8974, + GL_COLOR_ALPHA_PAIRING_ATI = 0x8975, + GL_SWIZZLE_STR_ATI = 0x8976, + GL_SWIZZLE_STQ_ATI = 0x8977, + GL_SWIZZLE_STR_DR_ATI = 0x8978, + GL_SWIZZLE_STQ_DQ_ATI = 0x8979, + GL_SWIZZLE_STRQ_ATI = 0x897A, + GL_SWIZZLE_STRQ_DQ_ATI = 0x897B, + GL_INTERLACE_OML = 0x8980, + GL_INTERLACE_READ_OML = 0x8981, + GL_FORMAT_SUBSAMPLE_24_24_OML = 0x8982, + GL_FORMAT_SUBSAMPLE_244_244_OML = 0x8983, + GL_PACK_RESAMPLE_OML = 0x8984, + GL_UNPACK_RESAMPLE_OML = 0x8985, + GL_RESAMPLE_REPLICATE_OML = 0x8986, + GL_RESAMPLE_ZERO_FILL_OML = 0x8987, + GL_RESAMPLE_AVERAGE_OML = 0x8988, + GL_RESAMPLE_DECIMATE_OML = 0x8989, + GL_POINT_SIZE_ARRAY_TYPE_OES = 0x898A, + GL_POINT_SIZE_ARRAY_STRIDE_OES = 0x898B, + GL_POINT_SIZE_ARRAY_POINTER_OES = 0x898C, + GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES = 0x898D, + GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES = 0x898E, + GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES = 0x898F, + GL_VERTEX_ATTRIB_MAP1_APPLE = 0x8A00, + GL_VERTEX_ATTRIB_MAP2_APPLE = 0x8A01, + GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE = 0x8A02, + GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE = 0x8A03, + GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE = 0x8A04, + GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE = 0x8A05, + GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE = 0x8A06, + GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE = 0x8A07, + GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE = 0x8A08, + GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE = 0x8A09, + GL_DRAW_PIXELS_APPLE = 0x8A0A, + GL_FENCE_APPLE = 0x8A0B, + GL_ELEMENT_ARRAY_APPLE = 0x8A0C, + GL_ELEMENT_ARRAY_TYPE_APPLE = 0x8A0D, + GL_ELEMENT_ARRAY_POINTER_APPLE = 0x8A0E, + GL_COLOR_FLOAT_APPLE = 0x8A0F, + GL_UNIFORM_BUFFER = 0x8A11, + GL_BUFFER_SERIALIZED_MODIFY_APPLE = 0x8A12, + GL_BUFFER_FLUSHING_UNMAP_APPLE = 0x8A13, + GL_AUX_DEPTH_STENCIL_APPLE = 0x8A14, + GL_PACK_ROW_BYTES_APPLE = 0x8A15, + GL_UNPACK_ROW_BYTES_APPLE = 0x8A16, + GL_RELEASED_APPLE = 0x8A19, + GL_VOLATILE_APPLE = 0x8A1A, + GL_RETAINED_APPLE = 0x8A1B, + GL_UNDEFINED_APPLE = 0x8A1C, + GL_PURGEABLE_APPLE = 0x8A1D, + GL_RGB_422_APPLE = 0x8A1F, + GL_UNIFORM_BUFFER_BINDING = 0x8A28, + GL_UNIFORM_BUFFER_START = 0x8A29, + GL_UNIFORM_BUFFER_SIZE = 0x8A2A, + GL_MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B, + GL_MAX_GEOMETRY_UNIFORM_BLOCKS = 0x8A2C, + GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT = 0x8A2C, + GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES = 0x8A2C, + GL_MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D, + GL_MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E, + GL_MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F, + GL_MAX_UNIFORM_BLOCK_SIZE = 0x8A30, + GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31, + GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = 0x8A32, + GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT = 0x8A32, + GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES = 0x8A32, + GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33, + GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34, + GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = 0x8A35, + GL_ACTIVE_UNIFORM_BLOCKS = 0x8A36, + GL_UNIFORM_TYPE = 0x8A37, + GL_UNIFORM_SIZE = 0x8A38, + GL_UNIFORM_NAME_LENGTH = 0x8A39, + GL_UNIFORM_BLOCK_INDEX = 0x8A3A, + GL_UNIFORM_OFFSET = 0x8A3B, + GL_UNIFORM_ARRAY_STRIDE = 0x8A3C, + GL_UNIFORM_MATRIX_STRIDE = 0x8A3D, + GL_UNIFORM_IS_ROW_MAJOR = 0x8A3E, + GL_UNIFORM_BLOCK_BINDING = 0x8A3F, + GL_UNIFORM_BLOCK_DATA_SIZE = 0x8A40, + GL_UNIFORM_BLOCK_NAME_LENGTH = 0x8A41, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42, + GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43, + GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44, + GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45, + GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46, + GL_TEXTURE_SRGB_DECODE_EXT = 0x8A48, + GL_DECODE_EXT = 0x8A49, + GL_SKIP_DECODE_EXT = 0x8A4A, + GL_PROGRAM_PIPELINE_OBJECT_EXT = 0x8A4F, + GL_RGB_RAW_422_APPLE = 0x8A51, + GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT = 0x8A52, + GL_SYNC_OBJECT_APPLE = 0x8A53, + GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT = 0x8A54, + GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT = 0x8A55, + GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT = 0x8A56, + GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT = 0x8A57, + GL_SHADER_OBJECT_ARB = 0x8B48, + GL_SHADER_OBJECT_EXT = 0x8B48, + GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49, + GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = 0x8B49, + GL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A, + GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = 0x8B4A, + GL_MAX_VARYING_FLOATS = 0x8B4B, + GL_MAX_VARYING_COMPONENTS = 0x8B4B, + GL_MAX_VARYING_COMPONENTS_EXT = 0x8B4B, + GL_MAX_VARYING_FLOATS_ARB = 0x8B4B, + GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C, + GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = 0x8B4C, + GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D, + GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = 0x8B4D, + GL_OBJECT_TYPE_ARB = 0x8B4E, + GL_SHADER_TYPE = 0x8B4F, + GL_OBJECT_SUBTYPE_ARB = 0x8B4F, + GL_DELETE_STATUS = 0x8B80, + GL_OBJECT_DELETE_STATUS_ARB = 0x8B80, + GL_COMPILE_STATUS = 0x8B81, + GL_OBJECT_COMPILE_STATUS_ARB = 0x8B81, + GL_LINK_STATUS = 0x8B82, + GL_OBJECT_LINK_STATUS_ARB = 0x8B82, + GL_VALIDATE_STATUS = 0x8B83, + GL_OBJECT_VALIDATE_STATUS_ARB = 0x8B83, + GL_INFO_LOG_LENGTH = 0x8B84, + GL_OBJECT_INFO_LOG_LENGTH_ARB = 0x8B84, + GL_ATTACHED_SHADERS = 0x8B85, + GL_OBJECT_ATTACHED_OBJECTS_ARB = 0x8B85, + GL_ACTIVE_UNIFORMS = 0x8B86, + GL_OBJECT_ACTIVE_UNIFORMS_ARB = 0x8B86, + GL_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, + GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = 0x8B87, + GL_SHADER_SOURCE_LENGTH = 0x8B88, + GL_OBJECT_SHADER_SOURCE_LENGTH_ARB = 0x8B88, + GL_ACTIVE_ATTRIBUTES = 0x8B89, + GL_OBJECT_ACTIVE_ATTRIBUTES_ARB = 0x8B89, + GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, + GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = 0x8B8A, + GL_FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B, + GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB = 0x8B8B, + GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B, + GL_SHADING_LANGUAGE_VERSION = 0x8B8C, + GL_SHADING_LANGUAGE_VERSION_ARB = 0x8B8C, + GL_CURRENT_PROGRAM = 0x8B8D, + GL_PALETTE4_RGB8_OES = 0x8B90, + GL_PALETTE4_RGBA8_OES = 0x8B91, + GL_PALETTE4_R5_G6_B5_OES = 0x8B92, + GL_PALETTE4_RGBA4_OES = 0x8B93, + GL_PALETTE4_RGB5_A1_OES = 0x8B94, + GL_PALETTE8_RGB8_OES = 0x8B95, + GL_PALETTE8_RGBA8_OES = 0x8B96, + GL_PALETTE8_R5_G6_B5_OES = 0x8B97, + GL_PALETTE8_RGBA4_OES = 0x8B98, + GL_PALETTE8_RGB5_A1_OES = 0x8B99, + GL_IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A, + GL_IMPLEMENTATION_COLOR_READ_TYPE_OES = 0x8B9A, + GL_IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B, + GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES = 0x8B9B, + GL_POINT_SIZE_ARRAY_OES = 0x8B9C, + GL_TEXTURE_CROP_RECT_OES = 0x8B9D, + GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES = 0x8B9E, + GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES = 0x8B9F, + GL_FRAGMENT_PROGRAM_POSITION_MESA = 0x8BB0, + GL_FRAGMENT_PROGRAM_CALLBACK_MESA = 0x8BB1, + GL_FRAGMENT_PROGRAM_CALLBACK_FUNC_MESA = 0x8BB2, + GL_FRAGMENT_PROGRAM_CALLBACK_DATA_MESA = 0x8BB3, + GL_VERTEX_PROGRAM_POSITION_MESA = 0x8BB4, + GL_VERTEX_PROGRAM_CALLBACK_MESA = 0x8BB5, + GL_VERTEX_PROGRAM_CALLBACK_FUNC_MESA = 0x8BB6, + GL_VERTEX_PROGRAM_CALLBACK_DATA_MESA = 0x8BB7, + GL_TILE_RASTER_ORDER_FIXED_MESA = 0x8BB8, + GL_TILE_RASTER_ORDER_INCREASING_X_MESA = 0x8BB9, + GL_TILE_RASTER_ORDER_INCREASING_Y_MESA = 0x8BBA, + GL_FRAMEBUFFER_FLIP_Y_MESA = 0x8BBB, + GL_FRAMEBUFFER_FLIP_X_MESA = 0x8BBC, + GL_FRAMEBUFFER_SWAP_XY_MESA = 0x8BBD, + GL_COUNTER_TYPE_AMD = 0x8BC0, + GL_COUNTER_RANGE_AMD = 0x8BC1, + GL_UNSIGNED_INT64_AMD = 0x8BC2, + GL_PERCENTAGE_AMD = 0x8BC3, + GL_PERFMON_RESULT_AVAILABLE_AMD = 0x8BC4, + GL_PERFMON_RESULT_SIZE_AMD = 0x8BC5, + GL_PERFMON_RESULT_AMD = 0x8BC6, + GL_TEXTURE_WIDTH_QCOM = 0x8BD2, + GL_TEXTURE_HEIGHT_QCOM = 0x8BD3, + GL_TEXTURE_DEPTH_QCOM = 0x8BD4, + GL_TEXTURE_INTERNAL_FORMAT_QCOM = 0x8BD5, + GL_TEXTURE_FORMAT_QCOM = 0x8BD6, + GL_TEXTURE_TYPE_QCOM = 0x8BD7, + GL_TEXTURE_IMAGE_VALID_QCOM = 0x8BD8, + GL_TEXTURE_NUM_LEVELS_QCOM = 0x8BD9, + GL_TEXTURE_TARGET_QCOM = 0x8BDA, + GL_TEXTURE_OBJECT_VALID_QCOM = 0x8BDB, + GL_STATE_RESTORE = 0x8BDC, + GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT = 0x8BE7, + GL_TEXTURE_PROTECTED_EXT = 0x8BFA, + GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM = 0x8BFB, + GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM = 0x8BFC, + GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM = 0x8BFD, + GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM = 0x8BFE, + GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM = 0x8BFF, + GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00, + GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01, + GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02, + GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03, + GL_MODULATE_COLOR_IMG = 0x8C04, + GL_RECIP_ADD_SIGNED_ALPHA_IMG = 0x8C05, + GL_TEXTURE_ALPHA_MODULATE_IMG = 0x8C06, + GL_FACTOR_ALPHA_MODULATE_IMG = 0x8C07, + GL_FRAGMENT_ALPHA_MODULATE_IMG = 0x8C08, + GL_ADD_BLEND_IMG = 0x8C09, + GL_SGX_BINARY_IMG = 0x8C0A, + GL_TEXTURE_RED_TYPE = 0x8C10, + GL_TEXTURE_RED_TYPE_ARB = 0x8C10, + GL_TEXTURE_GREEN_TYPE = 0x8C11, + GL_TEXTURE_GREEN_TYPE_ARB = 0x8C11, + GL_TEXTURE_BLUE_TYPE = 0x8C12, + GL_TEXTURE_BLUE_TYPE_ARB = 0x8C12, + GL_TEXTURE_ALPHA_TYPE = 0x8C13, + GL_TEXTURE_ALPHA_TYPE_ARB = 0x8C13, + GL_TEXTURE_LUMINANCE_TYPE = 0x8C14, + GL_TEXTURE_LUMINANCE_TYPE_ARB = 0x8C14, + GL_TEXTURE_INTENSITY_TYPE = 0x8C15, + GL_TEXTURE_INTENSITY_TYPE_ARB = 0x8C15, + GL_TEXTURE_DEPTH_TYPE = 0x8C16, + GL_TEXTURE_DEPTH_TYPE_ARB = 0x8C16, + GL_UNSIGNED_NORMALIZED = 0x8C17, + GL_UNSIGNED_NORMALIZED_ARB = 0x8C17, + GL_UNSIGNED_NORMALIZED_EXT = 0x8C17, + GL_TEXTURE_1D_ARRAY = 0x8C18, + GL_TEXTURE_1D_ARRAY_EXT = 0x8C18, + GL_PROXY_TEXTURE_1D_ARRAY = 0x8C19, + GL_PROXY_TEXTURE_1D_ARRAY_EXT = 0x8C19, + GL_TEXTURE_2D_ARRAY = 0x8C1A, + GL_TEXTURE_2D_ARRAY_EXT = 0x8C1A, + GL_PROXY_TEXTURE_2D_ARRAY = 0x8C1B, + GL_PROXY_TEXTURE_2D_ARRAY_EXT = 0x8C1B, + GL_TEXTURE_BINDING_1D_ARRAY = 0x8C1C, + GL_TEXTURE_BINDING_1D_ARRAY_EXT = 0x8C1C, + GL_TEXTURE_BINDING_2D_ARRAY = 0x8C1D, + GL_TEXTURE_BINDING_2D_ARRAY_EXT = 0x8C1D, + GL_GEOMETRY_PROGRAM_NV = 0x8C26, + GL_MAX_PROGRAM_OUTPUT_VERTICES_NV = 0x8C27, + GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV = 0x8C28, + GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = 0x8C29, + GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB = 0x8C29, + GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT = 0x8C29, + GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES = 0x8C29, + GL_TEXTURE_BUFFER = 0x8C2A, + GL_TEXTURE_BUFFER_ARB = 0x8C2A, + GL_TEXTURE_BUFFER_EXT = 0x8C2A, + GL_TEXTURE_BUFFER_OES = 0x8C2A, + GL_TEXTURE_BUFFER_BINDING = 0x8C2A, + GL_TEXTURE_BUFFER_BINDING_EXT = 0x8C2A, + GL_TEXTURE_BUFFER_BINDING_OES = 0x8C2A, + GL_MAX_TEXTURE_BUFFER_SIZE = 0x8C2B, + GL_MAX_TEXTURE_BUFFER_SIZE_ARB = 0x8C2B, + GL_MAX_TEXTURE_BUFFER_SIZE_EXT = 0x8C2B, + GL_MAX_TEXTURE_BUFFER_SIZE_OES = 0x8C2B, + GL_TEXTURE_BINDING_BUFFER = 0x8C2C, + GL_TEXTURE_BINDING_BUFFER_ARB = 0x8C2C, + GL_TEXTURE_BINDING_BUFFER_EXT = 0x8C2C, + GL_TEXTURE_BINDING_BUFFER_OES = 0x8C2C, + GL_TEXTURE_BUFFER_DATA_STORE_BINDING = 0x8C2D, + GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB = 0x8C2D, + GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT = 0x8C2D, + GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES = 0x8C2D, + GL_TEXTURE_BUFFER_FORMAT_ARB = 0x8C2E, + GL_TEXTURE_BUFFER_FORMAT_EXT = 0x8C2E, + GL_ANY_SAMPLES_PASSED = 0x8C2F, + GL_ANY_SAMPLES_PASSED_EXT = 0x8C2F, + GL_SAMPLE_SHADING = 0x8C36, + GL_SAMPLE_SHADING_ARB = 0x8C36, + GL_SAMPLE_SHADING_OES = 0x8C36, + GL_MIN_SAMPLE_SHADING_VALUE = 0x8C37, + GL_MIN_SAMPLE_SHADING_VALUE_ARB = 0x8C37, + GL_MIN_SAMPLE_SHADING_VALUE_OES = 0x8C37, + GL_R11F_G11F_B10F = 0x8C3A, + GL_R11F_G11F_B10F_APPLE = 0x8C3A, + GL_R11F_G11F_B10F_EXT = 0x8C3A, + GL_UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B, + GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE = 0x8C3B, + GL_UNSIGNED_INT_10F_11F_11F_REV_EXT = 0x8C3B, + GL_RGBA_SIGNED_COMPONENTS_EXT = 0x8C3C, + GL_RGB9_E5 = 0x8C3D, + GL_RGB9_E5_APPLE = 0x8C3D, + GL_RGB9_E5_EXT = 0x8C3D, + GL_UNSIGNED_INT_5_9_9_9_REV = 0x8C3E, + GL_UNSIGNED_INT_5_9_9_9_REV_APPLE = 0x8C3E, + GL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E, + GL_TEXTURE_SHARED_SIZE = 0x8C3F, + GL_TEXTURE_SHARED_SIZE_EXT = 0x8C3F, + GL_SRGB = 0x8C40, + GL_SRGB_EXT = 0x8C40, + GL_SRGB8 = 0x8C41, + GL_SRGB8_EXT = 0x8C41, + GL_SRGB8_NV = 0x8C41, + GL_SRGB_ALPHA = 0x8C42, + GL_SRGB_ALPHA_EXT = 0x8C42, + GL_SRGB8_ALPHA8 = 0x8C43, + GL_SRGB8_ALPHA8_EXT = 0x8C43, + GL_SLUMINANCE_ALPHA = 0x8C44, + GL_SLUMINANCE_ALPHA_EXT = 0x8C44, + GL_SLUMINANCE_ALPHA_NV = 0x8C44, + GL_SLUMINANCE8_ALPHA8 = 0x8C45, + GL_SLUMINANCE8_ALPHA8_EXT = 0x8C45, + GL_SLUMINANCE8_ALPHA8_NV = 0x8C45, + GL_SLUMINANCE = 0x8C46, + GL_SLUMINANCE_EXT = 0x8C46, + GL_SLUMINANCE_NV = 0x8C46, + GL_SLUMINANCE8 = 0x8C47, + GL_SLUMINANCE8_EXT = 0x8C47, + GL_SLUMINANCE8_NV = 0x8C47, + GL_COMPRESSED_SRGB = 0x8C48, + GL_COMPRESSED_SRGB_EXT = 0x8C48, + GL_COMPRESSED_SRGB_ALPHA = 0x8C49, + GL_COMPRESSED_SRGB_ALPHA_EXT = 0x8C49, + GL_COMPRESSED_SLUMINANCE = 0x8C4A, + GL_COMPRESSED_SLUMINANCE_EXT = 0x8C4A, + GL_COMPRESSED_SLUMINANCE_ALPHA = 0x8C4B, + GL_COMPRESSED_SLUMINANCE_ALPHA_EXT = 0x8C4B, + GL_COMPRESSED_SRGB_S3TC_DXT1_EXT = 0x8C4C, + GL_COMPRESSED_SRGB_S3TC_DXT1_NV = 0x8C4C, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 0x8C4D, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV = 0x8C4D, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 0x8C4E, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV = 0x8C4E, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 0x8C4F, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV = 0x8C4F, + GL_COMPRESSED_LUMINANCE_LATC1_EXT = 0x8C70, + GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT = 0x8C71, + GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT = 0x8C72, + GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT = 0x8C73, + GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV = 0x8C74, + GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV = 0x8C75, + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = 0x8C76, + GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT = 0x8C76, + GL_BACK_PRIMARY_COLOR_NV = 0x8C77, + GL_BACK_SECONDARY_COLOR_NV = 0x8C78, + GL_TEXTURE_COORD_NV = 0x8C79, + GL_CLIP_DISTANCE_NV = 0x8C7A, + GL_VERTEX_ID_NV = 0x8C7B, + GL_PRIMITIVE_ID_NV = 0x8C7C, + GL_GENERIC_ATTRIB_NV = 0x8C7D, + GL_TRANSFORM_FEEDBACK_ATTRIBS_NV = 0x8C7E, + GL_TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F, + GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT = 0x8C7F, + GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV = 0x8C7F, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT = 0x8C80, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV = 0x8C80, + GL_ACTIVE_VARYINGS_NV = 0x8C81, + GL_ACTIVE_VARYING_MAX_LENGTH_NV = 0x8C82, + GL_TRANSFORM_FEEDBACK_VARYINGS = 0x8C83, + GL_TRANSFORM_FEEDBACK_VARYINGS_EXT = 0x8C83, + GL_TRANSFORM_FEEDBACK_VARYINGS_NV = 0x8C83, + GL_TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84, + GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT = 0x8C84, + GL_TRANSFORM_FEEDBACK_BUFFER_START_NV = 0x8C84, + GL_TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85, + GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT = 0x8C85, + GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV = 0x8C85, + GL_TRANSFORM_FEEDBACK_RECORD_NV = 0x8C86, + GL_PRIMITIVES_GENERATED = 0x8C87, + GL_PRIMITIVES_GENERATED_EXT = 0x8C87, + GL_PRIMITIVES_GENERATED_NV = 0x8C87, + GL_PRIMITIVES_GENERATED_OES = 0x8C87, + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88, + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT = 0x8C88, + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV = 0x8C88, + GL_RASTERIZER_DISCARD = 0x8C89, + GL_RASTERIZER_DISCARD_EXT = 0x8C89, + GL_RASTERIZER_DISCARD_NV = 0x8C89, + GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A, + GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT = 0x8C8A, + GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV = 0x8C8A, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT = 0x8C8B, + GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV = 0x8C8B, + GL_INTERLEAVED_ATTRIBS = 0x8C8C, + GL_INTERLEAVED_ATTRIBS_EXT = 0x8C8C, + GL_INTERLEAVED_ATTRIBS_NV = 0x8C8C, + GL_SEPARATE_ATTRIBS = 0x8C8D, + GL_SEPARATE_ATTRIBS_EXT = 0x8C8D, + GL_SEPARATE_ATTRIBS_NV = 0x8C8D, + GL_TRANSFORM_FEEDBACK_BUFFER = 0x8C8E, + GL_TRANSFORM_FEEDBACK_BUFFER_EXT = 0x8C8E, + GL_TRANSFORM_FEEDBACK_BUFFER_NV = 0x8C8E, + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F, + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT = 0x8C8F, + GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV = 0x8C8F, + GL_MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM = 0x8C90, + GL_MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM = 0x8C91, + GL_ATC_RGB_AMD = 0x8C92, + GL_ATC_RGBA_EXPLICIT_ALPHA_AMD = 0x8C93, + GL_POINT_SPRITE_COORD_ORIGIN = 0x8CA0, + GL_LOWER_LEFT = 0x8CA1, + GL_LOWER_LEFT_EXT = 0x8CA1, + GL_UPPER_LEFT = 0x8CA2, + GL_UPPER_LEFT_EXT = 0x8CA2, + GL_STENCIL_BACK_REF = 0x8CA3, + GL_STENCIL_BACK_VALUE_MASK = 0x8CA4, + GL_STENCIL_BACK_WRITEMASK = 0x8CA5, + GL_DRAW_FRAMEBUFFER_BINDING = 0x8CA6, + GL_DRAW_FRAMEBUFFER_BINDING_ANGLE = 0x8CA6, + GL_DRAW_FRAMEBUFFER_BINDING_APPLE = 0x8CA6, + GL_DRAW_FRAMEBUFFER_BINDING_EXT = 0x8CA6, + GL_DRAW_FRAMEBUFFER_BINDING_NV = 0x8CA6, + GL_FRAMEBUFFER_BINDING = 0x8CA6, + GL_FRAMEBUFFER_BINDING_ANGLE = 0x8CA6, + GL_FRAMEBUFFER_BINDING_EXT = 0x8CA6, + GL_FRAMEBUFFER_BINDING_OES = 0x8CA6, + GL_RENDERBUFFER_BINDING = 0x8CA7, + GL_RENDERBUFFER_BINDING_ANGLE = 0x8CA7, + GL_RENDERBUFFER_BINDING_EXT = 0x8CA7, + GL_RENDERBUFFER_BINDING_OES = 0x8CA7, + GL_READ_FRAMEBUFFER = 0x8CA8, + GL_READ_FRAMEBUFFER_ANGLE = 0x8CA8, + GL_READ_FRAMEBUFFER_APPLE = 0x8CA8, + GL_READ_FRAMEBUFFER_EXT = 0x8CA8, + GL_READ_FRAMEBUFFER_NV = 0x8CA8, + GL_DRAW_FRAMEBUFFER = 0x8CA9, + GL_DRAW_FRAMEBUFFER_ANGLE = 0x8CA9, + GL_DRAW_FRAMEBUFFER_APPLE = 0x8CA9, + GL_DRAW_FRAMEBUFFER_EXT = 0x8CA9, + GL_DRAW_FRAMEBUFFER_NV = 0x8CA9, + GL_READ_FRAMEBUFFER_BINDING = 0x8CAA, + GL_READ_FRAMEBUFFER_BINDING_ANGLE = 0x8CAA, + GL_READ_FRAMEBUFFER_BINDING_APPLE = 0x8CAA, + GL_READ_FRAMEBUFFER_BINDING_EXT = 0x8CAA, + GL_READ_FRAMEBUFFER_BINDING_NV = 0x8CAA, + GL_RENDERBUFFER_COVERAGE_SAMPLES_NV = 0x8CAB, + GL_RENDERBUFFER_SAMPLES = 0x8CAB, + GL_RENDERBUFFER_SAMPLES_ANGLE = 0x8CAB, + GL_RENDERBUFFER_SAMPLES_APPLE = 0x8CAB, + GL_RENDERBUFFER_SAMPLES_EXT = 0x8CAB, + GL_RENDERBUFFER_SAMPLES_NV = 0x8CAB, + GL_DEPTH_COMPONENT32F = 0x8CAC, + GL_DEPTH32F_STENCIL8 = 0x8CAD, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = 0x8CD0, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES = 0x8CD0, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = 0x8CD1, + GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES = 0x8CD1, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = 0x8CD2, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES = 0x8CD2, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = 0x8CD3, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES = 0x8CD3, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = 0x8CD4, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES = 0x8CD4, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT = 0x8CD4, + GL_FRAMEBUFFER_COMPLETE = 0x8CD5, + GL_FRAMEBUFFER_COMPLETE_EXT = 0x8CD5, + GL_FRAMEBUFFER_COMPLETE_OES = 0x8CD5, + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6, + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = 0x8CD6, + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES = 0x8CD6, + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7, + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = 0x8CD7, + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES = 0x8CD7, + GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9, + GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = 0x8CD9, + GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES = 0x8CD9, + GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = 0x8CDA, + GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES = 0x8CDA, + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = 0x8CDB, + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = 0x8CDB, + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES = 0x8CDB, + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = 0x8CDC, + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = 0x8CDC, + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES = 0x8CDC, + GL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD, + GL_FRAMEBUFFER_UNSUPPORTED_EXT = 0x8CDD, + GL_FRAMEBUFFER_UNSUPPORTED_OES = 0x8CDD, + GL_MAX_COLOR_ATTACHMENTS = 0x8CDF, + GL_MAX_COLOR_ATTACHMENTS_EXT = 0x8CDF, + GL_MAX_COLOR_ATTACHMENTS_NV = 0x8CDF, + GL_COLOR_ATTACHMENT0 = 0x8CE0, + GL_COLOR_ATTACHMENT0_EXT = 0x8CE0, + GL_COLOR_ATTACHMENT0_NV = 0x8CE0, + GL_COLOR_ATTACHMENT0_OES = 0x8CE0, + GL_COLOR_ATTACHMENT1 = 0x8CE1, + GL_COLOR_ATTACHMENT1_EXT = 0x8CE1, + GL_COLOR_ATTACHMENT1_NV = 0x8CE1, + GL_COLOR_ATTACHMENT2 = 0x8CE2, + GL_COLOR_ATTACHMENT2_EXT = 0x8CE2, + GL_COLOR_ATTACHMENT2_NV = 0x8CE2, + GL_COLOR_ATTACHMENT3 = 0x8CE3, + GL_COLOR_ATTACHMENT3_EXT = 0x8CE3, + GL_COLOR_ATTACHMENT3_NV = 0x8CE3, + GL_COLOR_ATTACHMENT4 = 0x8CE4, + GL_COLOR_ATTACHMENT4_EXT = 0x8CE4, + GL_COLOR_ATTACHMENT4_NV = 0x8CE4, + GL_COLOR_ATTACHMENT5 = 0x8CE5, + GL_COLOR_ATTACHMENT5_EXT = 0x8CE5, + GL_COLOR_ATTACHMENT5_NV = 0x8CE5, + GL_COLOR_ATTACHMENT6 = 0x8CE6, + GL_COLOR_ATTACHMENT6_EXT = 0x8CE6, + GL_COLOR_ATTACHMENT6_NV = 0x8CE6, + GL_COLOR_ATTACHMENT7 = 0x8CE7, + GL_COLOR_ATTACHMENT7_EXT = 0x8CE7, + GL_COLOR_ATTACHMENT7_NV = 0x8CE7, + GL_COLOR_ATTACHMENT8 = 0x8CE8, + GL_COLOR_ATTACHMENT8_EXT = 0x8CE8, + GL_COLOR_ATTACHMENT8_NV = 0x8CE8, + GL_COLOR_ATTACHMENT9 = 0x8CE9, + GL_COLOR_ATTACHMENT9_EXT = 0x8CE9, + GL_COLOR_ATTACHMENT9_NV = 0x8CE9, + GL_COLOR_ATTACHMENT10 = 0x8CEA, + GL_COLOR_ATTACHMENT10_EXT = 0x8CEA, + GL_COLOR_ATTACHMENT10_NV = 0x8CEA, + GL_COLOR_ATTACHMENT11 = 0x8CEB, + GL_COLOR_ATTACHMENT11_EXT = 0x8CEB, + GL_COLOR_ATTACHMENT11_NV = 0x8CEB, + GL_COLOR_ATTACHMENT12 = 0x8CEC, + GL_COLOR_ATTACHMENT12_EXT = 0x8CEC, + GL_COLOR_ATTACHMENT12_NV = 0x8CEC, + GL_COLOR_ATTACHMENT13 = 0x8CED, + GL_COLOR_ATTACHMENT13_EXT = 0x8CED, + GL_COLOR_ATTACHMENT13_NV = 0x8CED, + GL_COLOR_ATTACHMENT14 = 0x8CEE, + GL_COLOR_ATTACHMENT14_EXT = 0x8CEE, + GL_COLOR_ATTACHMENT14_NV = 0x8CEE, + GL_COLOR_ATTACHMENT15 = 0x8CEF, + GL_COLOR_ATTACHMENT15_EXT = 0x8CEF, + GL_COLOR_ATTACHMENT15_NV = 0x8CEF, + GL_COLOR_ATTACHMENT16 = 0x8CF0, + GL_COLOR_ATTACHMENT17 = 0x8CF1, + GL_COLOR_ATTACHMENT18 = 0x8CF2, + GL_COLOR_ATTACHMENT19 = 0x8CF3, + GL_COLOR_ATTACHMENT20 = 0x8CF4, + GL_COLOR_ATTACHMENT21 = 0x8CF5, + GL_COLOR_ATTACHMENT22 = 0x8CF6, + GL_COLOR_ATTACHMENT23 = 0x8CF7, + GL_COLOR_ATTACHMENT24 = 0x8CF8, + GL_COLOR_ATTACHMENT25 = 0x8CF9, + GL_COLOR_ATTACHMENT26 = 0x8CFA, + GL_COLOR_ATTACHMENT27 = 0x8CFB, + GL_COLOR_ATTACHMENT28 = 0x8CFC, + GL_COLOR_ATTACHMENT29 = 0x8CFD, + GL_COLOR_ATTACHMENT30 = 0x8CFE, + GL_COLOR_ATTACHMENT31 = 0x8CFF, + GL_DEPTH_ATTACHMENT = 0x8D00, + GL_DEPTH_ATTACHMENT_EXT = 0x8D00, + GL_DEPTH_ATTACHMENT_OES = 0x8D00, + GL_STENCIL_ATTACHMENT = 0x8D20, + GL_STENCIL_ATTACHMENT_EXT = 0x8D20, + GL_STENCIL_ATTACHMENT_OES = 0x8D20, + GL_FRAMEBUFFER = 0x8D40, + GL_FRAMEBUFFER_EXT = 0x8D40, + GL_FRAMEBUFFER_OES = 0x8D40, + GL_RENDERBUFFER = 0x8D41, + GL_RENDERBUFFER_EXT = 0x8D41, + GL_RENDERBUFFER_OES = 0x8D41, + GL_RENDERBUFFER_WIDTH = 0x8D42, + GL_RENDERBUFFER_WIDTH_EXT = 0x8D42, + GL_RENDERBUFFER_WIDTH_OES = 0x8D42, + GL_RENDERBUFFER_HEIGHT = 0x8D43, + GL_RENDERBUFFER_HEIGHT_EXT = 0x8D43, + GL_RENDERBUFFER_HEIGHT_OES = 0x8D43, + GL_RENDERBUFFER_INTERNAL_FORMAT = 0x8D44, + GL_RENDERBUFFER_INTERNAL_FORMAT_EXT = 0x8D44, + GL_RENDERBUFFER_INTERNAL_FORMAT_OES = 0x8D44, + GL_STENCIL_INDEX1 = 0x8D46, + GL_STENCIL_INDEX1_EXT = 0x8D46, + GL_STENCIL_INDEX1_OES = 0x8D46, + GL_STENCIL_INDEX4 = 0x8D47, + GL_STENCIL_INDEX4_EXT = 0x8D47, + GL_STENCIL_INDEX4_OES = 0x8D47, + GL_STENCIL_INDEX8 = 0x8D48, + GL_STENCIL_INDEX8_EXT = 0x8D48, + GL_STENCIL_INDEX8_OES = 0x8D48, + GL_STENCIL_INDEX16 = 0x8D49, + GL_STENCIL_INDEX16_EXT = 0x8D49, + GL_RENDERBUFFER_RED_SIZE = 0x8D50, + GL_RENDERBUFFER_RED_SIZE_EXT = 0x8D50, + GL_RENDERBUFFER_RED_SIZE_OES = 0x8D50, + GL_RENDERBUFFER_GREEN_SIZE = 0x8D51, + GL_RENDERBUFFER_GREEN_SIZE_EXT = 0x8D51, + GL_RENDERBUFFER_GREEN_SIZE_OES = 0x8D51, + GL_RENDERBUFFER_BLUE_SIZE = 0x8D52, + GL_RENDERBUFFER_BLUE_SIZE_EXT = 0x8D52, + GL_RENDERBUFFER_BLUE_SIZE_OES = 0x8D52, + GL_RENDERBUFFER_ALPHA_SIZE = 0x8D53, + GL_RENDERBUFFER_ALPHA_SIZE_EXT = 0x8D53, + GL_RENDERBUFFER_ALPHA_SIZE_OES = 0x8D53, + GL_RENDERBUFFER_DEPTH_SIZE = 0x8D54, + GL_RENDERBUFFER_DEPTH_SIZE_EXT = 0x8D54, + GL_RENDERBUFFER_DEPTH_SIZE_OES = 0x8D54, + GL_RENDERBUFFER_STENCIL_SIZE = 0x8D55, + GL_RENDERBUFFER_STENCIL_SIZE_EXT = 0x8D55, + GL_RENDERBUFFER_STENCIL_SIZE_OES = 0x8D55, + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56, + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE = 0x8D56, + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE = 0x8D56, + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT = 0x8D56, + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV = 0x8D56, + GL_MAX_SAMPLES = 0x8D57, + GL_MAX_SAMPLES_ANGLE = 0x8D57, + GL_MAX_SAMPLES_APPLE = 0x8D57, + GL_MAX_SAMPLES_EXT = 0x8D57, + GL_MAX_SAMPLES_NV = 0x8D57, + GL_TEXTURE_GEN_STR_OES = 0x8D60, + GL_HALF_FLOAT_OES = 0x8D61, + GL_RGB565_OES = 0x8D62, + GL_RGB565 = 0x8D62, + GL_ETC1_RGB8_OES = 0x8D64, + GL_TEXTURE_EXTERNAL_OES = 0x8D65, + GL_SAMPLER_EXTERNAL_OES = 0x8D66, + GL_TEXTURE_BINDING_EXTERNAL_OES = 0x8D67, + GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES = 0x8D68, + GL_PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69, + GL_ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A, + GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT = 0x8D6A, + GL_MAX_ELEMENT_INDEX = 0x8D6B, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT = 0x8D6C, + GL_RGBA32UI = 0x8D70, + GL_RGBA32UI_EXT = 0x8D70, + GL_RGB32UI = 0x8D71, + GL_RGB32UI_EXT = 0x8D71, + GL_ALPHA32UI_EXT = 0x8D72, + GL_INTENSITY32UI_EXT = 0x8D73, + GL_LUMINANCE32UI_EXT = 0x8D74, + GL_LUMINANCE_ALPHA32UI_EXT = 0x8D75, + GL_RGBA16UI = 0x8D76, + GL_RGBA16UI_EXT = 0x8D76, + GL_RGB16UI = 0x8D77, + GL_RGB16UI_EXT = 0x8D77, + GL_ALPHA16UI_EXT = 0x8D78, + GL_INTENSITY16UI_EXT = 0x8D79, + GL_LUMINANCE16UI_EXT = 0x8D7A, + GL_LUMINANCE_ALPHA16UI_EXT = 0x8D7B, + GL_RGBA8UI = 0x8D7C, + GL_RGBA8UI_EXT = 0x8D7C, + GL_RGB8UI = 0x8D7D, + GL_RGB8UI_EXT = 0x8D7D, + GL_ALPHA8UI_EXT = 0x8D7E, + GL_INTENSITY8UI_EXT = 0x8D7F, + GL_LUMINANCE8UI_EXT = 0x8D80, + GL_LUMINANCE_ALPHA8UI_EXT = 0x8D81, + GL_RGBA32I = 0x8D82, + GL_RGBA32I_EXT = 0x8D82, + GL_RGB32I = 0x8D83, + GL_RGB32I_EXT = 0x8D83, + GL_ALPHA32I_EXT = 0x8D84, + GL_INTENSITY32I_EXT = 0x8D85, + GL_LUMINANCE32I_EXT = 0x8D86, + GL_LUMINANCE_ALPHA32I_EXT = 0x8D87, + GL_RGBA16I = 0x8D88, + GL_RGBA16I_EXT = 0x8D88, + GL_RGB16I = 0x8D89, + GL_RGB16I_EXT = 0x8D89, + GL_ALPHA16I_EXT = 0x8D8A, + GL_INTENSITY16I_EXT = 0x8D8B, + GL_LUMINANCE16I_EXT = 0x8D8C, + GL_LUMINANCE_ALPHA16I_EXT = 0x8D8D, + GL_RGBA8I = 0x8D8E, + GL_RGBA8I_EXT = 0x8D8E, + GL_RGB8I = 0x8D8F, + GL_RGB8I_EXT = 0x8D8F, + GL_ALPHA8I_EXT = 0x8D90, + GL_INTENSITY8I_EXT = 0x8D91, + GL_LUMINANCE8I_EXT = 0x8D92, + GL_LUMINANCE_ALPHA8I_EXT = 0x8D93, + GL_RED_INTEGER = 0x8D94, + GL_RED_INTEGER_EXT = 0x8D94, + GL_GREEN_INTEGER = 0x8D95, + GL_GREEN_INTEGER_EXT = 0x8D95, + GL_BLUE_INTEGER = 0x8D96, + GL_BLUE_INTEGER_EXT = 0x8D96, + GL_ALPHA_INTEGER = 0x8D97, + GL_ALPHA_INTEGER_EXT = 0x8D97, + GL_RGB_INTEGER = 0x8D98, + GL_RGB_INTEGER_EXT = 0x8D98, + GL_RGBA_INTEGER = 0x8D99, + GL_RGBA_INTEGER_EXT = 0x8D99, + GL_BGR_INTEGER = 0x8D9A, + GL_BGR_INTEGER_EXT = 0x8D9A, + GL_BGRA_INTEGER = 0x8D9B, + GL_BGRA_INTEGER_EXT = 0x8D9B, + GL_LUMINANCE_INTEGER_EXT = 0x8D9C, + GL_LUMINANCE_ALPHA_INTEGER_EXT = 0x8D9D, + GL_RGBA_INTEGER_MODE_EXT = 0x8D9E, + GL_INT_2_10_10_10_REV = 0x8D9F, + GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV = 0x8DA0, + GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV = 0x8DA1, + GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA2, + GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA3, + GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA4, + GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV = 0x8DA5, + GL_MAX_PROGRAM_GENERIC_RESULTS_NV = 0x8DA6, + GL_FRAMEBUFFER_ATTACHMENT_LAYERED = 0x8DA7, + GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB = 0x8DA7, + GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT = 0x8DA7, + GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES = 0x8DA7, + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = 0x8DA8, + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB = 0x8DA8, + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT = 0x8DA8, + GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES = 0x8DA8, + GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB = 0x8DA9, + GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT = 0x8DA9, + GL_LAYER_NV = 0x8DAA, + GL_DEPTH_COMPONENT32F_NV = 0x8DAB, + GL_DEPTH32F_STENCIL8_NV = 0x8DAC, + GL_FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD, + GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV = 0x8DAD, + GL_SHADER_INCLUDE_ARB = 0x8DAE, + GL_DEPTH_BUFFER_FLOAT_MODE_NV = 0x8DAF, + GL_FRAMEBUFFER_SRGB = 0x8DB9, + GL_FRAMEBUFFER_SRGB_EXT = 0x8DB9, + GL_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x8DBA, + GL_COMPRESSED_RED_RGTC1 = 0x8DBB, + GL_COMPRESSED_RED_RGTC1_EXT = 0x8DBB, + GL_COMPRESSED_SIGNED_RED_RGTC1 = 0x8DBC, + GL_COMPRESSED_SIGNED_RED_RGTC1_EXT = 0x8DBC, + GL_COMPRESSED_RED_GREEN_RGTC2_EXT = 0x8DBD, + GL_COMPRESSED_RG_RGTC2 = 0x8DBD, + GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 0x8DBE, + GL_COMPRESSED_SIGNED_RG_RGTC2 = 0x8DBE, + GL_SAMPLER_1D_ARRAY = 0x8DC0, + GL_SAMPLER_1D_ARRAY_EXT = 0x8DC0, + GL_SAMPLER_2D_ARRAY = 0x8DC1, + GL_SAMPLER_2D_ARRAY_EXT = 0x8DC1, + GL_SAMPLER_BUFFER = 0x8DC2, + GL_SAMPLER_BUFFER_EXT = 0x8DC2, + GL_SAMPLER_BUFFER_OES = 0x8DC2, + GL_SAMPLER_1D_ARRAY_SHADOW = 0x8DC3, + GL_SAMPLER_1D_ARRAY_SHADOW_EXT = 0x8DC3, + GL_SAMPLER_2D_ARRAY_SHADOW = 0x8DC4, + GL_SAMPLER_2D_ARRAY_SHADOW_EXT = 0x8DC4, + GL_SAMPLER_2D_ARRAY_SHADOW_NV = 0x8DC4, + GL_SAMPLER_CUBE_SHADOW = 0x8DC5, + GL_SAMPLER_CUBE_SHADOW_EXT = 0x8DC5, + GL_SAMPLER_CUBE_SHADOW_NV = 0x8DC5, + GL_UNSIGNED_INT_VEC2 = 0x8DC6, + GL_UNSIGNED_INT_VEC2_EXT = 0x8DC6, + GL_UNSIGNED_INT_VEC3 = 0x8DC7, + GL_UNSIGNED_INT_VEC3_EXT = 0x8DC7, + GL_UNSIGNED_INT_VEC4 = 0x8DC8, + GL_UNSIGNED_INT_VEC4_EXT = 0x8DC8, + GL_INT_SAMPLER_1D = 0x8DC9, + GL_INT_SAMPLER_1D_EXT = 0x8DC9, + GL_INT_SAMPLER_2D = 0x8DCA, + GL_INT_SAMPLER_2D_EXT = 0x8DCA, + GL_INT_SAMPLER_3D = 0x8DCB, + GL_INT_SAMPLER_3D_EXT = 0x8DCB, + GL_INT_SAMPLER_CUBE = 0x8DCC, + GL_INT_SAMPLER_CUBE_EXT = 0x8DCC, + GL_INT_SAMPLER_2D_RECT = 0x8DCD, + GL_INT_SAMPLER_2D_RECT_EXT = 0x8DCD, + GL_INT_SAMPLER_1D_ARRAY = 0x8DCE, + GL_INT_SAMPLER_1D_ARRAY_EXT = 0x8DCE, + GL_INT_SAMPLER_2D_ARRAY = 0x8DCF, + GL_INT_SAMPLER_2D_ARRAY_EXT = 0x8DCF, + GL_INT_SAMPLER_BUFFER = 0x8DD0, + GL_INT_SAMPLER_BUFFER_EXT = 0x8DD0, + GL_INT_SAMPLER_BUFFER_OES = 0x8DD0, + GL_UNSIGNED_INT_SAMPLER_1D = 0x8DD1, + GL_UNSIGNED_INT_SAMPLER_1D_EXT = 0x8DD1, + GL_UNSIGNED_INT_SAMPLER_2D = 0x8DD2, + GL_UNSIGNED_INT_SAMPLER_2D_EXT = 0x8DD2, + GL_UNSIGNED_INT_SAMPLER_3D = 0x8DD3, + GL_UNSIGNED_INT_SAMPLER_3D_EXT = 0x8DD3, + GL_UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4, + GL_UNSIGNED_INT_SAMPLER_CUBE_EXT = 0x8DD4, + GL_UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5, + GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT = 0x8DD5, + GL_UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6, + GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT = 0x8DD6, + GL_UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7, + GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT = 0x8DD7, + GL_UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8, + GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT = 0x8DD8, + GL_UNSIGNED_INT_SAMPLER_BUFFER_OES = 0x8DD8, + GL_GEOMETRY_SHADER = 0x8DD9, + GL_GEOMETRY_SHADER_ARB = 0x8DD9, + GL_GEOMETRY_SHADER_EXT = 0x8DD9, + GL_GEOMETRY_SHADER_OES = 0x8DD9, + GL_GEOMETRY_VERTICES_OUT_ARB = 0x8DDA, + GL_GEOMETRY_VERTICES_OUT_EXT = 0x8DDA, + GL_GEOMETRY_INPUT_TYPE_ARB = 0x8DDB, + GL_GEOMETRY_INPUT_TYPE_EXT = 0x8DDB, + GL_GEOMETRY_OUTPUT_TYPE_ARB = 0x8DDC, + GL_GEOMETRY_OUTPUT_TYPE_EXT = 0x8DDC, + GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB = 0x8DDD, + GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT = 0x8DDD, + GL_MAX_VERTEX_VARYING_COMPONENTS_ARB = 0x8DDE, + GL_MAX_VERTEX_VARYING_COMPONENTS_EXT = 0x8DDE, + GL_MAX_GEOMETRY_UNIFORM_COMPONENTS = 0x8DDF, + GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB = 0x8DDF, + GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT = 0x8DDF, + GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES = 0x8DDF, + GL_MAX_GEOMETRY_OUTPUT_VERTICES = 0x8DE0, + GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB = 0x8DE0, + GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT = 0x8DE0, + GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES = 0x8DE0, + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 0x8DE1, + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB = 0x8DE1, + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT = 0x8DE1, + GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES = 0x8DE1, + GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT = 0x8DE2, + GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT = 0x8DE3, + GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT = 0x8DE4, + GL_ACTIVE_SUBROUTINES = 0x8DE5, + GL_ACTIVE_SUBROUTINE_UNIFORMS = 0x8DE6, + GL_MAX_SUBROUTINES = 0x8DE7, + GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS = 0x8DE8, + GL_NAMED_STRING_LENGTH_ARB = 0x8DE9, + GL_NAMED_STRING_TYPE_ARB = 0x8DEA, + GL_MAX_BINDABLE_UNIFORM_SIZE_EXT = 0x8DED, + GL_UNIFORM_BUFFER_EXT = 0x8DEE, + GL_UNIFORM_BUFFER_BINDING_EXT = 0x8DEF, + GL_LOW_FLOAT = 0x8DF0, + GL_MEDIUM_FLOAT = 0x8DF1, + GL_HIGH_FLOAT = 0x8DF2, + GL_LOW_INT = 0x8DF3, + GL_MEDIUM_INT = 0x8DF4, + GL_HIGH_INT = 0x8DF5, + GL_UNSIGNED_INT_10_10_10_2_OES = 0x8DF6, + GL_INT_10_10_10_2_OES = 0x8DF7, + GL_SHADER_BINARY_FORMATS = 0x8DF8, + GL_NUM_SHADER_BINARY_FORMATS = 0x8DF9, + GL_SHADER_COMPILER = 0x8DFA, + GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, + GL_MAX_VARYING_VECTORS = 0x8DFC, + GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD, + GL_RENDERBUFFER_COLOR_SAMPLES_NV = 0x8E10, + GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV = 0x8E11, + GL_MULTISAMPLE_COVERAGE_MODES_NV = 0x8E12, + GL_QUERY_WAIT = 0x8E13, + GL_QUERY_WAIT_NV = 0x8E13, + GL_QUERY_NO_WAIT = 0x8E14, + GL_QUERY_NO_WAIT_NV = 0x8E14, + GL_QUERY_BY_REGION_WAIT = 0x8E15, + GL_QUERY_BY_REGION_WAIT_NV = 0x8E15, + GL_QUERY_BY_REGION_NO_WAIT = 0x8E16, + GL_QUERY_BY_REGION_NO_WAIT_NV = 0x8E16, + GL_QUERY_WAIT_INVERTED = 0x8E17, + GL_QUERY_NO_WAIT_INVERTED = 0x8E18, + GL_QUERY_BY_REGION_WAIT_INVERTED = 0x8E19, + GL_QUERY_BY_REGION_NO_WAIT_INVERTED = 0x8E1A, + GL_POLYGON_OFFSET_CLAMP = 0x8E1B, + GL_POLYGON_OFFSET_CLAMP_EXT = 0x8E1B, + GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E1E, + GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT = 0x8E1E, + GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES = 0x8E1E, + GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E1F, + GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT = 0x8E1F, + GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES = 0x8E1F, + GL_COLOR_SAMPLES_NV = 0x8E20, + GL_TRANSFORM_FEEDBACK = 0x8E22, + GL_TRANSFORM_FEEDBACK_NV = 0x8E22, + GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED = 0x8E23, + GL_TRANSFORM_FEEDBACK_PAUSED = 0x8E23, + GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV = 0x8E23, + GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE = 0x8E24, + GL_TRANSFORM_FEEDBACK_ACTIVE = 0x8E24, + GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV = 0x8E24, + GL_TRANSFORM_FEEDBACK_BINDING = 0x8E25, + GL_TRANSFORM_FEEDBACK_BINDING_NV = 0x8E25, + GL_FRAME_NV = 0x8E26, + GL_FIELDS_NV = 0x8E27, + GL_CURRENT_TIME_NV = 0x8E28, + GL_TIMESTAMP = 0x8E28, + GL_TIMESTAMP_EXT = 0x8E28, + GL_NUM_FILL_STREAMS_NV = 0x8E29, + GL_PRESENT_TIME_NV = 0x8E2A, + GL_PRESENT_DURATION_NV = 0x8E2B, + GL_DEPTH_COMPONENT16_NONLINEAR_NV = 0x8E2C, + GL_PROGRAM_MATRIX_EXT = 0x8E2D, + GL_TRANSPOSE_PROGRAM_MATRIX_EXT = 0x8E2E, + GL_PROGRAM_MATRIX_STACK_DEPTH_EXT = 0x8E2F, + GL_TEXTURE_SWIZZLE_R = 0x8E42, + GL_TEXTURE_SWIZZLE_R_EXT = 0x8E42, + GL_TEXTURE_SWIZZLE_G = 0x8E43, + GL_TEXTURE_SWIZZLE_G_EXT = 0x8E43, + GL_TEXTURE_SWIZZLE_B = 0x8E44, + GL_TEXTURE_SWIZZLE_B_EXT = 0x8E44, + GL_TEXTURE_SWIZZLE_A = 0x8E45, + GL_TEXTURE_SWIZZLE_A_EXT = 0x8E45, + GL_TEXTURE_SWIZZLE_RGBA = 0x8E46, + GL_TEXTURE_SWIZZLE_RGBA_EXT = 0x8E46, + GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS = 0x8E47, + GL_ACTIVE_SUBROUTINE_MAX_LENGTH = 0x8E48, + GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH = 0x8E49, + GL_NUM_COMPATIBLE_SUBROUTINES = 0x8E4A, + GL_COMPATIBLE_SUBROUTINES = 0x8E4B, + GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 0x8E4C, + GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT = 0x8E4C, + GL_FIRST_VERTEX_CONVENTION = 0x8E4D, + GL_FIRST_VERTEX_CONVENTION_EXT = 0x8E4D, + GL_FIRST_VERTEX_CONVENTION_OES = 0x8E4D, + GL_LAST_VERTEX_CONVENTION = 0x8E4E, + GL_LAST_VERTEX_CONVENTION_EXT = 0x8E4E, + GL_LAST_VERTEX_CONVENTION_OES = 0x8E4E, + GL_PROVOKING_VERTEX = 0x8E4F, + GL_PROVOKING_VERTEX_EXT = 0x8E4F, + GL_SAMPLE_POSITION = 0x8E50, + GL_SAMPLE_POSITION_NV = 0x8E50, + GL_SAMPLE_LOCATION_ARB = 0x8E50, + GL_SAMPLE_LOCATION_NV = 0x8E50, + GL_SAMPLE_MASK = 0x8E51, + GL_SAMPLE_MASK_NV = 0x8E51, + GL_SAMPLE_MASK_VALUE = 0x8E52, + GL_SAMPLE_MASK_VALUE_NV = 0x8E52, + GL_TEXTURE_BINDING_RENDERBUFFER_NV = 0x8E53, + GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV = 0x8E54, + GL_TEXTURE_RENDERBUFFER_NV = 0x8E55, + GL_SAMPLER_RENDERBUFFER_NV = 0x8E56, + GL_INT_SAMPLER_RENDERBUFFER_NV = 0x8E57, + GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV = 0x8E58, + GL_MAX_SAMPLE_MASK_WORDS = 0x8E59, + GL_MAX_SAMPLE_MASK_WORDS_NV = 0x8E59, + GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV = 0x8E5A, + GL_MAX_GEOMETRY_SHADER_INVOCATIONS = 0x8E5A, + GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT = 0x8E5A, + GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES = 0x8E5A, + GL_MIN_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5B, + GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES = 0x8E5B, + GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV = 0x8E5B, + GL_MAX_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5C, + GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES = 0x8E5C, + GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV = 0x8E5C, + GL_FRAGMENT_INTERPOLATION_OFFSET_BITS = 0x8E5D, + GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES = 0x8E5D, + GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV = 0x8E5D, + GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET = 0x8E5E, + GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = 0x8E5E, + GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV = 0x8E5E, + GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET = 0x8E5F, + GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = 0x8E5F, + GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV = 0x8E5F, + GL_MAX_MESH_UNIFORM_BLOCKS_NV = 0x8E60, + GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV = 0x8E61, + GL_MAX_MESH_IMAGE_UNIFORMS_NV = 0x8E62, + GL_MAX_MESH_UNIFORM_COMPONENTS_NV = 0x8E63, + GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV = 0x8E64, + GL_MAX_MESH_ATOMIC_COUNTERS_NV = 0x8E65, + GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV = 0x8E66, + GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV = 0x8E67, + GL_MAX_TASK_UNIFORM_BLOCKS_NV = 0x8E68, + GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV = 0x8E69, + GL_MAX_TASK_IMAGE_UNIFORMS_NV = 0x8E6A, + GL_MAX_TASK_UNIFORM_COMPONENTS_NV = 0x8E6B, + GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV = 0x8E6C, + GL_MAX_TASK_ATOMIC_COUNTERS_NV = 0x8E6D, + GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV = 0x8E6E, + GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV = 0x8E6F, + GL_MAX_TRANSFORM_FEEDBACK_BUFFERS = 0x8E70, + GL_MAX_VERTEX_STREAMS = 0x8E71, + GL_PATCH_VERTICES = 0x8E72, + GL_PATCH_VERTICES_EXT = 0x8E72, + GL_PATCH_VERTICES_OES = 0x8E72, + GL_PATCH_DEFAULT_INNER_LEVEL = 0x8E73, + GL_PATCH_DEFAULT_INNER_LEVEL_EXT = 0x8E73, + GL_PATCH_DEFAULT_OUTER_LEVEL = 0x8E74, + GL_PATCH_DEFAULT_OUTER_LEVEL_EXT = 0x8E74, + GL_TESS_CONTROL_OUTPUT_VERTICES = 0x8E75, + GL_TESS_CONTROL_OUTPUT_VERTICES_EXT = 0x8E75, + GL_TESS_CONTROL_OUTPUT_VERTICES_OES = 0x8E75, + GL_TESS_GEN_MODE = 0x8E76, + GL_TESS_GEN_MODE_EXT = 0x8E76, + GL_TESS_GEN_MODE_OES = 0x8E76, + GL_TESS_GEN_SPACING = 0x8E77, + GL_TESS_GEN_SPACING_EXT = 0x8E77, + GL_TESS_GEN_SPACING_OES = 0x8E77, + GL_TESS_GEN_VERTEX_ORDER = 0x8E78, + GL_TESS_GEN_VERTEX_ORDER_EXT = 0x8E78, + GL_TESS_GEN_VERTEX_ORDER_OES = 0x8E78, + GL_TESS_GEN_POINT_MODE = 0x8E79, + GL_TESS_GEN_POINT_MODE_EXT = 0x8E79, + GL_TESS_GEN_POINT_MODE_OES = 0x8E79, + GL_ISOLINES = 0x8E7A, + GL_ISOLINES_EXT = 0x8E7A, + GL_ISOLINES_OES = 0x8E7A, + GL_FRACTIONAL_ODD = 0x8E7B, + GL_FRACTIONAL_ODD_EXT = 0x8E7B, + GL_FRACTIONAL_ODD_OES = 0x8E7B, + GL_FRACTIONAL_EVEN = 0x8E7C, + GL_FRACTIONAL_EVEN_EXT = 0x8E7C, + GL_FRACTIONAL_EVEN_OES = 0x8E7C, + GL_MAX_PATCH_VERTICES = 0x8E7D, + GL_MAX_PATCH_VERTICES_EXT = 0x8E7D, + GL_MAX_PATCH_VERTICES_OES = 0x8E7D, + GL_MAX_TESS_GEN_LEVEL = 0x8E7E, + GL_MAX_TESS_GEN_LEVEL_EXT = 0x8E7E, + GL_MAX_TESS_GEN_LEVEL_OES = 0x8E7E, + GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E7F, + GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT = 0x8E7F, + GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES = 0x8E7F, + GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E80, + GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT = 0x8E80, + GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES = 0x8E80, + GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS = 0x8E81, + GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT = 0x8E81, + GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES = 0x8E81, + GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS = 0x8E82, + GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT = 0x8E82, + GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES = 0x8E82, + GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS = 0x8E83, + GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT = 0x8E83, + GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES = 0x8E83, + GL_MAX_TESS_PATCH_COMPONENTS = 0x8E84, + GL_MAX_TESS_PATCH_COMPONENTS_EXT = 0x8E84, + GL_MAX_TESS_PATCH_COMPONENTS_OES = 0x8E84, + GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS = 0x8E85, + GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT = 0x8E85, + GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES = 0x8E85, + GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS = 0x8E86, + GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT = 0x8E86, + GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES = 0x8E86, + GL_TESS_EVALUATION_SHADER = 0x8E87, + GL_TESS_EVALUATION_SHADER_EXT = 0x8E87, + GL_TESS_EVALUATION_SHADER_OES = 0x8E87, + GL_TESS_CONTROL_SHADER = 0x8E88, + GL_TESS_CONTROL_SHADER_EXT = 0x8E88, + GL_TESS_CONTROL_SHADER_OES = 0x8E88, + GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS = 0x8E89, + GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT = 0x8E89, + GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES = 0x8E89, + GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS = 0x8E8A, + GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT = 0x8E8A, + GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES = 0x8E8A, + GL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C, + GL_COMPRESSED_RGBA_BPTC_UNORM_ARB = 0x8E8C, + GL_COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8E8C, + GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 0x8E8D, + GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB = 0x8E8D, + GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT = 0x8E8D, + GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 0x8E8E, + GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB = 0x8E8E, + GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT = 0x8E8E, + GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F, + GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB = 0x8E8F, + GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT = 0x8E8F, + GL_COVERAGE_COMPONENT_NV = 0x8ED0, + GL_COVERAGE_COMPONENT4_NV = 0x8ED1, + GL_COVERAGE_ATTACHMENT_NV = 0x8ED2, + GL_COVERAGE_BUFFERS_NV = 0x8ED3, + GL_COVERAGE_SAMPLES_NV = 0x8ED4, + GL_COVERAGE_ALL_FRAGMENTS_NV = 0x8ED5, + GL_COVERAGE_EDGE_FRAGMENTS_NV = 0x8ED6, + GL_COVERAGE_AUTOMATIC_NV = 0x8ED7, + GL_INCLUSIVE_EXT = 0x8F10, + GL_EXCLUSIVE_EXT = 0x8F11, + GL_WINDOW_RECTANGLE_EXT = 0x8F12, + GL_WINDOW_RECTANGLE_MODE_EXT = 0x8F13, + GL_MAX_WINDOW_RECTANGLES_EXT = 0x8F14, + GL_NUM_WINDOW_RECTANGLES_EXT = 0x8F15, + GL_BUFFER_GPU_ADDRESS_NV = 0x8F1D, + GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV = 0x8F1E, + GL_ELEMENT_ARRAY_UNIFIED_NV = 0x8F1F, + GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV = 0x8F20, + GL_VERTEX_ARRAY_ADDRESS_NV = 0x8F21, + GL_NORMAL_ARRAY_ADDRESS_NV = 0x8F22, + GL_COLOR_ARRAY_ADDRESS_NV = 0x8F23, + GL_INDEX_ARRAY_ADDRESS_NV = 0x8F24, + GL_TEXTURE_COORD_ARRAY_ADDRESS_NV = 0x8F25, + GL_EDGE_FLAG_ARRAY_ADDRESS_NV = 0x8F26, + GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV = 0x8F27, + GL_FOG_COORD_ARRAY_ADDRESS_NV = 0x8F28, + GL_ELEMENT_ARRAY_ADDRESS_NV = 0x8F29, + GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV = 0x8F2A, + GL_VERTEX_ARRAY_LENGTH_NV = 0x8F2B, + GL_NORMAL_ARRAY_LENGTH_NV = 0x8F2C, + GL_COLOR_ARRAY_LENGTH_NV = 0x8F2D, + GL_INDEX_ARRAY_LENGTH_NV = 0x8F2E, + GL_TEXTURE_COORD_ARRAY_LENGTH_NV = 0x8F2F, + GL_EDGE_FLAG_ARRAY_LENGTH_NV = 0x8F30, + GL_SECONDARY_COLOR_ARRAY_LENGTH_NV = 0x8F31, + GL_FOG_COORD_ARRAY_LENGTH_NV = 0x8F32, + GL_ELEMENT_ARRAY_LENGTH_NV = 0x8F33, + GL_GPU_ADDRESS_NV = 0x8F34, + GL_MAX_SHADER_BUFFER_ADDRESS_NV = 0x8F35, + GL_COPY_READ_BUFFER = 0x8F36, + GL_COPY_READ_BUFFER_NV = 0x8F36, + GL_COPY_READ_BUFFER_BINDING = 0x8F36, + GL_COPY_WRITE_BUFFER = 0x8F37, + GL_COPY_WRITE_BUFFER_NV = 0x8F37, + GL_COPY_WRITE_BUFFER_BINDING = 0x8F37, + GL_MAX_IMAGE_UNITS = 0x8F38, + GL_MAX_IMAGE_UNITS_EXT = 0x8F38, + GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS = 0x8F39, + GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT = 0x8F39, + GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES = 0x8F39, + GL_IMAGE_BINDING_NAME = 0x8F3A, + GL_IMAGE_BINDING_NAME_EXT = 0x8F3A, + GL_IMAGE_BINDING_LEVEL = 0x8F3B, + GL_IMAGE_BINDING_LEVEL_EXT = 0x8F3B, + GL_IMAGE_BINDING_LAYERED = 0x8F3C, + GL_IMAGE_BINDING_LAYERED_EXT = 0x8F3C, + GL_IMAGE_BINDING_LAYER = 0x8F3D, + GL_IMAGE_BINDING_LAYER_EXT = 0x8F3D, + GL_IMAGE_BINDING_ACCESS = 0x8F3E, + GL_IMAGE_BINDING_ACCESS_EXT = 0x8F3E, + GL_DRAW_INDIRECT_BUFFER = 0x8F3F, + GL_DRAW_INDIRECT_UNIFIED_NV = 0x8F40, + GL_DRAW_INDIRECT_ADDRESS_NV = 0x8F41, + GL_DRAW_INDIRECT_LENGTH_NV = 0x8F42, + GL_DRAW_INDIRECT_BUFFER_BINDING = 0x8F43, + GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV = 0x8F44, + GL_MAX_PROGRAM_SUBROUTINE_NUM_NV = 0x8F45, + GL_DOUBLE_MAT2 = 0x8F46, + GL_DOUBLE_MAT2_EXT = 0x8F46, + GL_DOUBLE_MAT3 = 0x8F47, + GL_DOUBLE_MAT3_EXT = 0x8F47, + GL_DOUBLE_MAT4 = 0x8F48, + GL_DOUBLE_MAT4_EXT = 0x8F48, + GL_DOUBLE_MAT2x3 = 0x8F49, + GL_DOUBLE_MAT2x3_EXT = 0x8F49, + GL_DOUBLE_MAT2x4 = 0x8F4A, + GL_DOUBLE_MAT2x4_EXT = 0x8F4A, + GL_DOUBLE_MAT3x2 = 0x8F4B, + GL_DOUBLE_MAT3x2_EXT = 0x8F4B, + GL_DOUBLE_MAT3x4 = 0x8F4C, + GL_DOUBLE_MAT3x4_EXT = 0x8F4C, + GL_DOUBLE_MAT4x2 = 0x8F4D, + GL_DOUBLE_MAT4x2_EXT = 0x8F4D, + GL_DOUBLE_MAT4x3 = 0x8F4E, + GL_DOUBLE_MAT4x3_EXT = 0x8F4E, + GL_VERTEX_BINDING_BUFFER = 0x8F4F, + GL_MALI_SHADER_BINARY_ARM = 0x8F60, + GL_MALI_PROGRAM_BINARY_ARM = 0x8F61, + GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT = 0x8F63, + GL_SHADER_PIXEL_LOCAL_STORAGE_EXT = 0x8F64, + GL_FETCH_PER_SAMPLE_ARM = 0x8F65, + GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM = 0x8F66, + GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT = 0x8F67, + GL_TEXTURE_ASTC_DECODE_PRECISION_EXT = 0x8F69, + GL_TEXTURE_UNNORMALIZED_COORDINATES_ARM = 0x8F6A, + GL_RED_SNORM = 0x8F90, + GL_RG_SNORM = 0x8F91, + GL_RGB_SNORM = 0x8F92, + GL_RGBA_SNORM = 0x8F93, + GL_R8_SNORM = 0x8F94, + GL_RG8_SNORM = 0x8F95, + GL_RGB8_SNORM = 0x8F96, + GL_RGBA8_SNORM = 0x8F97, + GL_R16_SNORM = 0x8F98, + GL_R16_SNORM_EXT = 0x8F98, + GL_RG16_SNORM = 0x8F99, + GL_RG16_SNORM_EXT = 0x8F99, + GL_RGB16_SNORM = 0x8F9A, + GL_RGB16_SNORM_EXT = 0x8F9A, + GL_RGBA16_SNORM = 0x8F9B, + GL_RGBA16_SNORM_EXT = 0x8F9B, + GL_SIGNED_NORMALIZED = 0x8F9C, + GL_PRIMITIVE_RESTART = 0x8F9D, + GL_PRIMITIVE_RESTART_INDEX = 0x8F9E, + GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB = 0x8F9F, + GL_PERFMON_GLOBAL_MODE_QCOM = 0x8FA0, + GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM = 0x8FA1, + GL_BINNING_CONTROL_HINT_QCOM = 0x8FB0, + GL_CPU_OPTIMIZED_QCOM = 0x8FB1, + GL_GPU_OPTIMIZED_QCOM = 0x8FB2, + GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM = 0x8FB3, + GL_GPU_DISJOINT_EXT = 0x8FBB, + GL_SR8_EXT = 0x8FBD, + GL_SRG8_EXT = 0x8FBE, + GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT = 0x8FBF, + GL_SHADER_BINARY_VIV = 0x8FC4, + GL_INT8_NV = 0x8FE0, + GL_INT8_VEC2_NV = 0x8FE1, + GL_INT8_VEC3_NV = 0x8FE2, + GL_INT8_VEC4_NV = 0x8FE3, + GL_INT16_NV = 0x8FE4, + GL_INT16_VEC2_NV = 0x8FE5, + GL_INT16_VEC3_NV = 0x8FE6, + GL_INT16_VEC4_NV = 0x8FE7, + GL_INT64_VEC2_ARB = 0x8FE9, + GL_INT64_VEC2_NV = 0x8FE9, + GL_INT64_VEC3_ARB = 0x8FEA, + GL_INT64_VEC3_NV = 0x8FEA, + GL_INT64_VEC4_ARB = 0x8FEB, + GL_INT64_VEC4_NV = 0x8FEB, + GL_UNSIGNED_INT8_NV = 0x8FEC, + GL_UNSIGNED_INT8_VEC2_NV = 0x8FED, + GL_UNSIGNED_INT8_VEC3_NV = 0x8FEE, + GL_UNSIGNED_INT8_VEC4_NV = 0x8FEF, + GL_UNSIGNED_INT16_NV = 0x8FF0, + GL_UNSIGNED_INT16_VEC2_NV = 0x8FF1, + GL_UNSIGNED_INT16_VEC3_NV = 0x8FF2, + GL_UNSIGNED_INT16_VEC4_NV = 0x8FF3, + GL_UNSIGNED_INT64_VEC2_ARB = 0x8FF5, + GL_UNSIGNED_INT64_VEC2_NV = 0x8FF5, + GL_UNSIGNED_INT64_VEC3_ARB = 0x8FF6, + GL_UNSIGNED_INT64_VEC3_NV = 0x8FF6, + GL_UNSIGNED_INT64_VEC4_ARB = 0x8FF7, + GL_UNSIGNED_INT64_VEC4_NV = 0x8FF7, + GL_FLOAT16_NV = 0x8FF8, + GL_FLOAT16_VEC2_NV = 0x8FF9, + GL_FLOAT16_VEC3_NV = 0x8FFA, + GL_FLOAT16_VEC4_NV = 0x8FFB, + GL_DOUBLE_VEC2 = 0x8FFC, + GL_DOUBLE_VEC2_EXT = 0x8FFC, + GL_DOUBLE_VEC3 = 0x8FFD, + GL_DOUBLE_VEC3_EXT = 0x8FFD, + GL_DOUBLE_VEC4 = 0x8FFE, + GL_DOUBLE_VEC4_EXT = 0x8FFE, + GL_SAMPLER_BUFFER_AMD = 0x9001, + GL_INT_SAMPLER_BUFFER_AMD = 0x9002, + GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD = 0x9003, + GL_TESSELLATION_MODE_AMD = 0x9004, + GL_TESSELLATION_FACTOR_AMD = 0x9005, + GL_DISCRETE_AMD = 0x9006, + GL_CONTINUOUS_AMD = 0x9007, + GL_TEXTURE_CUBE_MAP_ARRAY = 0x9009, + GL_TEXTURE_CUBE_MAP_ARRAY_ARB = 0x9009, + GL_TEXTURE_CUBE_MAP_ARRAY_EXT = 0x9009, + GL_TEXTURE_CUBE_MAP_ARRAY_OES = 0x9009, + GL_TEXTURE_BINDING_CUBE_MAP_ARRAY = 0x900A, + GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB = 0x900A, + GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT = 0x900A, + GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES = 0x900A, + GL_PROXY_TEXTURE_CUBE_MAP_ARRAY = 0x900B, + GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB = 0x900B, + GL_SAMPLER_CUBE_MAP_ARRAY = 0x900C, + GL_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900C, + GL_SAMPLER_CUBE_MAP_ARRAY_EXT = 0x900C, + GL_SAMPLER_CUBE_MAP_ARRAY_OES = 0x900C, + GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW = 0x900D, + GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB = 0x900D, + GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT = 0x900D, + GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES = 0x900D, + GL_INT_SAMPLER_CUBE_MAP_ARRAY = 0x900E, + GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900E, + GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT = 0x900E, + GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES = 0x900E, + GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY = 0x900F, + GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900F, + GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT = 0x900F, + GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES = 0x900F, + GL_ALPHA_SNORM = 0x9010, + GL_LUMINANCE_SNORM = 0x9011, + GL_LUMINANCE_ALPHA_SNORM = 0x9012, + GL_INTENSITY_SNORM = 0x9013, + GL_ALPHA8_SNORM = 0x9014, + GL_LUMINANCE8_SNORM = 0x9015, + GL_LUMINANCE8_ALPHA8_SNORM = 0x9016, + GL_INTENSITY8_SNORM = 0x9017, + GL_ALPHA16_SNORM = 0x9018, + GL_LUMINANCE16_SNORM = 0x9019, + GL_LUMINANCE16_ALPHA16_SNORM = 0x901A, + GL_INTENSITY16_SNORM = 0x901B, + GL_FACTOR_MIN_AMD = 0x901C, + GL_FACTOR_MAX_AMD = 0x901D, + GL_DEPTH_CLAMP_NEAR_AMD = 0x901E, + GL_DEPTH_CLAMP_FAR_AMD = 0x901F, + GL_VIDEO_BUFFER_NV = 0x9020, + GL_VIDEO_BUFFER_BINDING_NV = 0x9021, + GL_FIELD_UPPER_NV = 0x9022, + GL_FIELD_LOWER_NV = 0x9023, + GL_NUM_VIDEO_CAPTURE_STREAMS_NV = 0x9024, + GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV = 0x9025, + GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV = 0x9026, + GL_LAST_VIDEO_CAPTURE_STATUS_NV = 0x9027, + GL_VIDEO_BUFFER_PITCH_NV = 0x9028, + GL_VIDEO_COLOR_CONVERSION_MATRIX_NV = 0x9029, + GL_VIDEO_COLOR_CONVERSION_MAX_NV = 0x902A, + GL_VIDEO_COLOR_CONVERSION_MIN_NV = 0x902B, + GL_VIDEO_COLOR_CONVERSION_OFFSET_NV = 0x902C, + GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV = 0x902D, + GL_PARTIAL_SUCCESS_NV = 0x902E, + GL_SUCCESS_NV = 0x902F, + GL_FAILURE_NV = 0x9030, + GL_YCBYCR8_422_NV = 0x9031, + GL_YCBAYCR8A_4224_NV = 0x9032, + GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV = 0x9033, + GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV = 0x9034, + GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV = 0x9035, + GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV = 0x9036, + GL_Z4Y12Z4CB12Z4CR12_444_NV = 0x9037, + GL_VIDEO_CAPTURE_FRAME_WIDTH_NV = 0x9038, + GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV = 0x9039, + GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV = 0x903A, + GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV = 0x903B, + GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV = 0x903C, + GL_TEXTURE_COVERAGE_SAMPLES_NV = 0x9045, + GL_TEXTURE_COLOR_SAMPLES_NV = 0x9046, + GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047, + GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048, + GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049, + GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A, + GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B, + GL_IMAGE_1D = 0x904C, + GL_IMAGE_1D_EXT = 0x904C, + GL_IMAGE_2D = 0x904D, + GL_IMAGE_2D_EXT = 0x904D, + GL_IMAGE_3D = 0x904E, + GL_IMAGE_3D_EXT = 0x904E, + GL_IMAGE_2D_RECT = 0x904F, + GL_IMAGE_2D_RECT_EXT = 0x904F, + GL_IMAGE_CUBE = 0x9050, + GL_IMAGE_CUBE_EXT = 0x9050, + GL_IMAGE_BUFFER = 0x9051, + GL_IMAGE_BUFFER_EXT = 0x9051, + GL_IMAGE_BUFFER_OES = 0x9051, + GL_IMAGE_1D_ARRAY = 0x9052, + GL_IMAGE_1D_ARRAY_EXT = 0x9052, + GL_IMAGE_2D_ARRAY = 0x9053, + GL_IMAGE_2D_ARRAY_EXT = 0x9053, + GL_IMAGE_CUBE_MAP_ARRAY = 0x9054, + GL_IMAGE_CUBE_MAP_ARRAY_EXT = 0x9054, + GL_IMAGE_CUBE_MAP_ARRAY_OES = 0x9054, + GL_IMAGE_2D_MULTISAMPLE = 0x9055, + GL_IMAGE_2D_MULTISAMPLE_EXT = 0x9055, + GL_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9056, + GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x9056, + GL_INT_IMAGE_1D = 0x9057, + GL_INT_IMAGE_1D_EXT = 0x9057, + GL_INT_IMAGE_2D = 0x9058, + GL_INT_IMAGE_2D_EXT = 0x9058, + GL_INT_IMAGE_3D = 0x9059, + GL_INT_IMAGE_3D_EXT = 0x9059, + GL_INT_IMAGE_2D_RECT = 0x905A, + GL_INT_IMAGE_2D_RECT_EXT = 0x905A, + GL_INT_IMAGE_CUBE = 0x905B, + GL_INT_IMAGE_CUBE_EXT = 0x905B, + GL_INT_IMAGE_BUFFER = 0x905C, + GL_INT_IMAGE_BUFFER_EXT = 0x905C, + GL_INT_IMAGE_BUFFER_OES = 0x905C, + GL_INT_IMAGE_1D_ARRAY = 0x905D, + GL_INT_IMAGE_1D_ARRAY_EXT = 0x905D, + GL_INT_IMAGE_2D_ARRAY = 0x905E, + GL_INT_IMAGE_2D_ARRAY_EXT = 0x905E, + GL_INT_IMAGE_CUBE_MAP_ARRAY = 0x905F, + GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 0x905F, + GL_INT_IMAGE_CUBE_MAP_ARRAY_OES = 0x905F, + GL_INT_IMAGE_2D_MULTISAMPLE = 0x9060, + GL_INT_IMAGE_2D_MULTISAMPLE_EXT = 0x9060, + GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9061, + GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x9061, + GL_UNSIGNED_INT_IMAGE_1D = 0x9062, + GL_UNSIGNED_INT_IMAGE_1D_EXT = 0x9062, + GL_UNSIGNED_INT_IMAGE_2D = 0x9063, + GL_UNSIGNED_INT_IMAGE_2D_EXT = 0x9063, + GL_UNSIGNED_INT_IMAGE_3D = 0x9064, + GL_UNSIGNED_INT_IMAGE_3D_EXT = 0x9064, + GL_UNSIGNED_INT_IMAGE_2D_RECT = 0x9065, + GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT = 0x9065, + GL_UNSIGNED_INT_IMAGE_CUBE = 0x9066, + GL_UNSIGNED_INT_IMAGE_CUBE_EXT = 0x9066, + GL_UNSIGNED_INT_IMAGE_BUFFER = 0x9067, + GL_UNSIGNED_INT_IMAGE_BUFFER_EXT = 0x9067, + GL_UNSIGNED_INT_IMAGE_BUFFER_OES = 0x9067, + GL_UNSIGNED_INT_IMAGE_1D_ARRAY = 0x9068, + GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT = 0x9068, + GL_UNSIGNED_INT_IMAGE_2D_ARRAY = 0x9069, + GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT = 0x9069, + GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY = 0x906A, + GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 0x906A, + GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES = 0x906A, + GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE = 0x906B, + GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT = 0x906B, + GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x906C, + GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x906C, + GL_MAX_IMAGE_SAMPLES = 0x906D, + GL_MAX_IMAGE_SAMPLES_EXT = 0x906D, + GL_IMAGE_BINDING_FORMAT = 0x906E, + GL_IMAGE_BINDING_FORMAT_EXT = 0x906E, + GL_RGB10_A2UI = 0x906F, + GL_PATH_FORMAT_SVG_NV = 0x9070, + GL_PATH_FORMAT_PS_NV = 0x9071, + GL_STANDARD_FONT_NAME_NV = 0x9072, + GL_SYSTEM_FONT_NAME_NV = 0x9073, + GL_FILE_NAME_NV = 0x9074, + GL_PATH_STROKE_WIDTH_NV = 0x9075, + GL_PATH_END_CAPS_NV = 0x9076, + GL_PATH_INITIAL_END_CAP_NV = 0x9077, + GL_PATH_TERMINAL_END_CAP_NV = 0x9078, + GL_PATH_JOIN_STYLE_NV = 0x9079, + GL_PATH_MITER_LIMIT_NV = 0x907A, + GL_PATH_DASH_CAPS_NV = 0x907B, + GL_PATH_INITIAL_DASH_CAP_NV = 0x907C, + GL_PATH_TERMINAL_DASH_CAP_NV = 0x907D, + GL_PATH_DASH_OFFSET_NV = 0x907E, + GL_PATH_CLIENT_LENGTH_NV = 0x907F, + GL_PATH_FILL_MODE_NV = 0x9080, + GL_PATH_FILL_MASK_NV = 0x9081, + GL_PATH_FILL_COVER_MODE_NV = 0x9082, + GL_PATH_STROKE_COVER_MODE_NV = 0x9083, + GL_PATH_STROKE_MASK_NV = 0x9084, + GL_COUNT_UP_NV = 0x9088, + GL_COUNT_DOWN_NV = 0x9089, + GL_PATH_OBJECT_BOUNDING_BOX_NV = 0x908A, + GL_CONVEX_HULL_NV = 0x908B, + GL_BOUNDING_BOX_NV = 0x908D, + GL_TRANSLATE_X_NV = 0x908E, + GL_TRANSLATE_Y_NV = 0x908F, + GL_TRANSLATE_2D_NV = 0x9090, + GL_TRANSLATE_3D_NV = 0x9091, + GL_AFFINE_2D_NV = 0x9092, + GL_AFFINE_3D_NV = 0x9094, + GL_TRANSPOSE_AFFINE_2D_NV = 0x9096, + GL_TRANSPOSE_AFFINE_3D_NV = 0x9098, + GL_UTF8_NV = 0x909A, + GL_UTF16_NV = 0x909B, + GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV = 0x909C, + GL_PATH_COMMAND_COUNT_NV = 0x909D, + GL_PATH_COORD_COUNT_NV = 0x909E, + GL_PATH_DASH_ARRAY_COUNT_NV = 0x909F, + GL_PATH_COMPUTED_LENGTH_NV = 0x90A0, + GL_PATH_FILL_BOUNDING_BOX_NV = 0x90A1, + GL_PATH_STROKE_BOUNDING_BOX_NV = 0x90A2, + GL_SQUARE_NV = 0x90A3, + GL_ROUND_NV = 0x90A4, + GL_TRIANGULAR_NV = 0x90A5, + GL_BEVEL_NV = 0x90A6, + GL_MITER_REVERT_NV = 0x90A7, + GL_MITER_TRUNCATE_NV = 0x90A8, + GL_SKIP_MISSING_GLYPH_NV = 0x90A9, + GL_USE_MISSING_GLYPH_NV = 0x90AA, + GL_PATH_ERROR_POSITION_NV = 0x90AB, + GL_PATH_FOG_GEN_MODE_NV = 0x90AC, + GL_ACCUM_ADJACENT_PAIRS_NV = 0x90AD, + GL_ADJACENT_PAIRS_NV = 0x90AE, + GL_FIRST_TO_REST_NV = 0x90AF, + GL_PATH_GEN_MODE_NV = 0x90B0, + GL_PATH_GEN_COEFF_NV = 0x90B1, + GL_PATH_GEN_COLOR_FORMAT_NV = 0x90B2, + GL_PATH_GEN_COMPONENTS_NV = 0x90B3, + GL_PATH_DASH_OFFSET_RESET_NV = 0x90B4, + GL_MOVE_TO_RESETS_NV = 0x90B5, + GL_MOVE_TO_CONTINUES_NV = 0x90B6, + GL_PATH_STENCIL_FUNC_NV = 0x90B7, + GL_PATH_STENCIL_REF_NV = 0x90B8, + GL_PATH_STENCIL_VALUE_MASK_NV = 0x90B9, + GL_SCALED_RESOLVE_FASTEST_EXT = 0x90BA, + GL_SCALED_RESOLVE_NICEST_EXT = 0x90BB, + GL_MIN_MAP_BUFFER_ALIGNMENT = 0x90BC, + GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV = 0x90BD, + GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV = 0x90BE, + GL_PATH_COVER_DEPTH_FUNC_NV = 0x90BF, + GL_IMAGE_FORMAT_COMPATIBILITY_TYPE = 0x90C7, + GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE = 0x90C8, + GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS = 0x90C9, + GL_MAX_VERTEX_IMAGE_UNIFORMS = 0x90CA, + GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS = 0x90CB, + GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT = 0x90CB, + GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES = 0x90CB, + GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS = 0x90CC, + GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT = 0x90CC, + GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES = 0x90CC, + GL_MAX_GEOMETRY_IMAGE_UNIFORMS = 0x90CD, + GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT = 0x90CD, + GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES = 0x90CD, + GL_MAX_FRAGMENT_IMAGE_UNIFORMS = 0x90CE, + GL_MAX_COMBINED_IMAGE_UNIFORMS = 0x90CF, + GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV = 0x90D0, + GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV = 0x90D1, + GL_SHADER_STORAGE_BUFFER = 0x90D2, + GL_SHADER_STORAGE_BUFFER_BINDING = 0x90D3, + GL_SHADER_STORAGE_BUFFER_START = 0x90D4, + GL_SHADER_STORAGE_BUFFER_SIZE = 0x90D5, + GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS = 0x90D6, + GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS = 0x90D7, + GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT = 0x90D7, + GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES = 0x90D7, + GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS = 0x90D8, + GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT = 0x90D8, + GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES = 0x90D8, + GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS = 0x90D9, + GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT = 0x90D9, + GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES = 0x90D9, + GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS = 0x90DA, + GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS = 0x90DB, + GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS = 0x90DC, + GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 0x90DD, + GL_MAX_SHADER_STORAGE_BLOCK_SIZE = 0x90DE, + GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = 0x90DF, + GL_SYNC_X11_FENCE_EXT = 0x90E1, + GL_DEPTH_STENCIL_TEXTURE_MODE = 0x90EA, + GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS = 0x90EB, + GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB = 0x90EB, + GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER = 0x90EC, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER = 0x90ED, + GL_DISPATCH_INDIRECT_BUFFER = 0x90EE, + GL_DISPATCH_INDIRECT_BUFFER_BINDING = 0x90EF, + GL_COLOR_ATTACHMENT_EXT = 0x90F0, + GL_MULTIVIEW_EXT = 0x90F1, + GL_MAX_MULTIVIEW_BUFFERS_EXT = 0x90F2, + GL_CONTEXT_ROBUST_ACCESS = 0x90F3, + GL_CONTEXT_ROBUST_ACCESS_EXT = 0x90F3, + GL_CONTEXT_ROBUST_ACCESS_KHR = 0x90F3, + GL_COMPUTE_PROGRAM_NV = 0x90FB, + GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV = 0x90FC, + GL_TEXTURE_2D_MULTISAMPLE = 0x9100, + GL_PROXY_TEXTURE_2D_MULTISAMPLE = 0x9101, + GL_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9102, + GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES = 0x9102, + GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9103, + GL_TEXTURE_BINDING_2D_MULTISAMPLE = 0x9104, + GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = 0x9105, + GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES = 0x9105, + GL_TEXTURE_SAMPLES = 0x9106, + GL_TEXTURE_FIXED_SAMPLE_LOCATIONS = 0x9107, + GL_SAMPLER_2D_MULTISAMPLE = 0x9108, + GL_INT_SAMPLER_2D_MULTISAMPLE = 0x9109, + GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A, + GL_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B, + GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES = 0x910B, + GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C, + GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES = 0x910C, + GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D, + GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES = 0x910D, + GL_MAX_COLOR_TEXTURE_SAMPLES = 0x910E, + GL_MAX_DEPTH_TEXTURE_SAMPLES = 0x910F, + GL_MAX_INTEGER_SAMPLES = 0x9110, + GL_MAX_SERVER_WAIT_TIMEOUT = 0x9111, + GL_MAX_SERVER_WAIT_TIMEOUT_APPLE = 0x9111, + GL_OBJECT_TYPE = 0x9112, + GL_OBJECT_TYPE_APPLE = 0x9112, + GL_SYNC_CONDITION = 0x9113, + GL_SYNC_CONDITION_APPLE = 0x9113, + GL_SYNC_STATUS = 0x9114, + GL_SYNC_STATUS_APPLE = 0x9114, + GL_SYNC_FLAGS = 0x9115, + GL_SYNC_FLAGS_APPLE = 0x9115, + GL_SYNC_FENCE = 0x9116, + GL_SYNC_FENCE_APPLE = 0x9116, + GL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117, + GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE = 0x9117, + GL_UNSIGNALED = 0x9118, + GL_UNSIGNALED_APPLE = 0x9118, + GL_SIGNALED = 0x9119, + GL_SIGNALED_APPLE = 0x9119, + GL_ALREADY_SIGNALED = 0x911A, + GL_ALREADY_SIGNALED_APPLE = 0x911A, + GL_TIMEOUT_EXPIRED = 0x911B, + GL_TIMEOUT_EXPIRED_APPLE = 0x911B, + GL_CONDITION_SATISFIED = 0x911C, + GL_CONDITION_SATISFIED_APPLE = 0x911C, + GL_WAIT_FAILED = 0x911D, + GL_WAIT_FAILED_APPLE = 0x911D, + GL_BUFFER_ACCESS_FLAGS = 0x911F, + GL_BUFFER_MAP_LENGTH = 0x9120, + GL_BUFFER_MAP_OFFSET = 0x9121, + GL_MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122, + GL_MAX_GEOMETRY_INPUT_COMPONENTS = 0x9123, + GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT = 0x9123, + GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES = 0x9123, + GL_MAX_GEOMETRY_OUTPUT_COMPONENTS = 0x9124, + GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT = 0x9124, + GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES = 0x9124, + GL_MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125, + GL_CONTEXT_PROFILE_MASK = 0x9126, + GL_UNPACK_COMPRESSED_BLOCK_WIDTH = 0x9127, + GL_UNPACK_COMPRESSED_BLOCK_HEIGHT = 0x9128, + GL_UNPACK_COMPRESSED_BLOCK_DEPTH = 0x9129, + GL_UNPACK_COMPRESSED_BLOCK_SIZE = 0x912A, + GL_PACK_COMPRESSED_BLOCK_WIDTH = 0x912B, + GL_PACK_COMPRESSED_BLOCK_HEIGHT = 0x912C, + GL_PACK_COMPRESSED_BLOCK_DEPTH = 0x912D, + GL_PACK_COMPRESSED_BLOCK_SIZE = 0x912E, + GL_TEXTURE_IMMUTABLE_FORMAT = 0x912F, + GL_TEXTURE_IMMUTABLE_FORMAT_EXT = 0x912F, + GL_SGX_PROGRAM_BINARY_IMG = 0x9130, + GL_RENDERBUFFER_SAMPLES_IMG = 0x9133, + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG = 0x9134, + GL_MAX_SAMPLES_IMG = 0x9135, + GL_TEXTURE_SAMPLES_IMG = 0x9136, + GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG = 0x9137, + GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG = 0x9138, + GL_CUBIC_IMG = 0x9139, + GL_CUBIC_MIPMAP_NEAREST_IMG = 0x913A, + GL_CUBIC_MIPMAP_LINEAR_IMG = 0x913B, + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG = 0x913C, + GL_NUM_DOWNSAMPLE_SCALES_IMG = 0x913D, + GL_DOWNSAMPLE_SCALES_IMG = 0x913E, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG = 0x913F, + GL_MAX_DEBUG_MESSAGE_LENGTH = 0x9143, + GL_MAX_DEBUG_MESSAGE_LENGTH_AMD = 0x9143, + GL_MAX_DEBUG_MESSAGE_LENGTH_ARB = 0x9143, + GL_MAX_DEBUG_MESSAGE_LENGTH_KHR = 0x9143, + GL_MAX_DEBUG_LOGGED_MESSAGES = 0x9144, + GL_MAX_DEBUG_LOGGED_MESSAGES_AMD = 0x9144, + GL_MAX_DEBUG_LOGGED_MESSAGES_ARB = 0x9144, + GL_MAX_DEBUG_LOGGED_MESSAGES_KHR = 0x9144, + GL_DEBUG_LOGGED_MESSAGES = 0x9145, + GL_DEBUG_LOGGED_MESSAGES_AMD = 0x9145, + GL_DEBUG_LOGGED_MESSAGES_ARB = 0x9145, + GL_DEBUG_LOGGED_MESSAGES_KHR = 0x9145, + GL_DEBUG_SEVERITY_HIGH = 0x9146, + GL_DEBUG_SEVERITY_HIGH_AMD = 0x9146, + GL_DEBUG_SEVERITY_HIGH_ARB = 0x9146, + GL_DEBUG_SEVERITY_HIGH_KHR = 0x9146, + GL_DEBUG_SEVERITY_MEDIUM = 0x9147, + GL_DEBUG_SEVERITY_MEDIUM_AMD = 0x9147, + GL_DEBUG_SEVERITY_MEDIUM_ARB = 0x9147, + GL_DEBUG_SEVERITY_MEDIUM_KHR = 0x9147, + GL_DEBUG_SEVERITY_LOW = 0x9148, + GL_DEBUG_SEVERITY_LOW_AMD = 0x9148, + GL_DEBUG_SEVERITY_LOW_ARB = 0x9148, + GL_DEBUG_SEVERITY_LOW_KHR = 0x9148, + GL_DEBUG_CATEGORY_API_ERROR_AMD = 0x9149, + GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD = 0x914A, + GL_DEBUG_CATEGORY_DEPRECATION_AMD = 0x914B, + GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD = 0x914C, + GL_DEBUG_CATEGORY_PERFORMANCE_AMD = 0x914D, + GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD = 0x914E, + GL_DEBUG_CATEGORY_APPLICATION_AMD = 0x914F, + GL_DEBUG_CATEGORY_OTHER_AMD = 0x9150, + GL_BUFFER_OBJECT_EXT = 0x9151, + GL_DATA_BUFFER_AMD = 0x9151, + GL_PERFORMANCE_MONITOR_AMD = 0x9152, + GL_QUERY_OBJECT_AMD = 0x9153, + GL_QUERY_OBJECT_EXT = 0x9153, + GL_VERTEX_ARRAY_OBJECT_AMD = 0x9154, + GL_VERTEX_ARRAY_OBJECT_EXT = 0x9154, + GL_SAMPLER_OBJECT_AMD = 0x9155, + GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD = 0x9160, + GL_QUERY_BUFFER = 0x9192, + GL_QUERY_BUFFER_AMD = 0x9192, + GL_QUERY_BUFFER_BINDING = 0x9193, + GL_QUERY_BUFFER_BINDING_AMD = 0x9193, + GL_QUERY_RESULT_NO_WAIT = 0x9194, + GL_QUERY_RESULT_NO_WAIT_AMD = 0x9194, + GL_VIRTUAL_PAGE_SIZE_X_ARB = 0x9195, + GL_VIRTUAL_PAGE_SIZE_X_EXT = 0x9195, + GL_VIRTUAL_PAGE_SIZE_X_AMD = 0x9195, + GL_VIRTUAL_PAGE_SIZE_Y_ARB = 0x9196, + GL_VIRTUAL_PAGE_SIZE_Y_EXT = 0x9196, + GL_VIRTUAL_PAGE_SIZE_Y_AMD = 0x9196, + GL_VIRTUAL_PAGE_SIZE_Z_ARB = 0x9197, + GL_VIRTUAL_PAGE_SIZE_Z_EXT = 0x9197, + GL_VIRTUAL_PAGE_SIZE_Z_AMD = 0x9197, + GL_MAX_SPARSE_TEXTURE_SIZE_ARB = 0x9198, + GL_MAX_SPARSE_TEXTURE_SIZE_EXT = 0x9198, + GL_MAX_SPARSE_TEXTURE_SIZE_AMD = 0x9198, + GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB = 0x9199, + GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT = 0x9199, + GL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD = 0x9199, + GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS = 0x919A, + GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB = 0x919A, + GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT = 0x919A, + GL_MIN_SPARSE_LEVEL_AMD = 0x919B, + GL_MIN_LOD_WARNING_AMD = 0x919C, + GL_TEXTURE_BUFFER_OFFSET = 0x919D, + GL_TEXTURE_BUFFER_OFFSET_EXT = 0x919D, + GL_TEXTURE_BUFFER_OFFSET_OES = 0x919D, + GL_TEXTURE_BUFFER_SIZE = 0x919E, + GL_TEXTURE_BUFFER_SIZE_EXT = 0x919E, + GL_TEXTURE_BUFFER_SIZE_OES = 0x919E, + GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 0x919F, + GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT = 0x919F, + GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES = 0x919F, + GL_STREAM_RASTERIZATION_AMD = 0x91A0, + GL_VERTEX_ELEMENT_SWIZZLE_AMD = 0x91A4, + GL_VERTEX_ID_SWIZZLE_AMD = 0x91A5, + GL_TEXTURE_SPARSE_ARB = 0x91A6, + GL_TEXTURE_SPARSE_EXT = 0x91A6, + GL_VIRTUAL_PAGE_SIZE_INDEX_ARB = 0x91A7, + GL_VIRTUAL_PAGE_SIZE_INDEX_EXT = 0x91A7, + GL_NUM_VIRTUAL_PAGE_SIZES_ARB = 0x91A8, + GL_NUM_VIRTUAL_PAGE_SIZES_EXT = 0x91A8, + GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB = 0x91A9, + GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT = 0x91A9, + GL_NUM_SPARSE_LEVELS_ARB = 0x91AA, + GL_NUM_SPARSE_LEVELS_EXT = 0x91AA, + GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD = 0x91AE, + GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD = 0x91AF, + GL_MAX_SHADER_COMPILER_THREADS_KHR = 0x91B0, + GL_MAX_SHADER_COMPILER_THREADS_ARB = 0x91B0, + GL_COMPLETION_STATUS_KHR = 0x91B1, + GL_COMPLETION_STATUS_ARB = 0x91B1, + GL_RENDERBUFFER_STORAGE_SAMPLES_AMD = 0x91B2, + GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD = 0x91B3, + GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD = 0x91B4, + GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD = 0x91B5, + GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD = 0x91B6, + GL_SUPPORTED_MULTISAMPLE_MODES_AMD = 0x91B7, + GL_COMPUTE_SHADER = 0x91B9, + GL_MAX_COMPUTE_UNIFORM_BLOCKS = 0x91BB, + GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS = 0x91BC, + GL_MAX_COMPUTE_IMAGE_UNIFORMS = 0x91BD, + GL_MAX_COMPUTE_WORK_GROUP_COUNT = 0x91BE, + GL_MAX_COMPUTE_WORK_GROUP_SIZE = 0x91BF, + GL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB = 0x91BF, + GL_FLOAT16_MAT2_AMD = 0x91C5, + GL_FLOAT16_MAT3_AMD = 0x91C6, + GL_FLOAT16_MAT4_AMD = 0x91C7, + GL_FLOAT16_MAT2x3_AMD = 0x91C8, + GL_FLOAT16_MAT2x4_AMD = 0x91C9, + GL_FLOAT16_MAT3x2_AMD = 0x91CA, + GL_FLOAT16_MAT3x4_AMD = 0x91CB, + GL_FLOAT16_MAT4x2_AMD = 0x91CC, + GL_FLOAT16_MAT4x3_AMD = 0x91CD, + GL_UNPACK_FLIP_Y_WEBGL = 0x9240, + GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241, + GL_CONTEXT_LOST_WEBGL = 0x9242, + GL_UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243, + GL_BROWSER_DEFAULT_WEBGL = 0x9244, + GL_SHADER_BINARY_DMP = 0x9250, + GL_SMAPHS30_PROGRAM_BINARY_DMP = 0x9251, + GL_SMAPHS_PROGRAM_BINARY_DMP = 0x9252, + GL_DMP_PROGRAM_BINARY_DMP = 0x9253, + GL_GCCSO_SHADER_BINARY_FJ = 0x9260, + GL_COMPRESSED_R11_EAC = 0x9270, + GL_COMPRESSED_R11_EAC_OES = 0x9270, + GL_COMPRESSED_SIGNED_R11_EAC = 0x9271, + GL_COMPRESSED_SIGNED_R11_EAC_OES = 0x9271, + GL_COMPRESSED_RG11_EAC = 0x9272, + GL_COMPRESSED_RG11_EAC_OES = 0x9272, + GL_COMPRESSED_SIGNED_RG11_EAC = 0x9273, + GL_COMPRESSED_SIGNED_RG11_EAC_OES = 0x9273, + GL_COMPRESSED_RGB8_ETC2 = 0x9274, + GL_COMPRESSED_RGB8_ETC2_OES = 0x9274, + GL_COMPRESSED_SRGB8_ETC2 = 0x9275, + GL_COMPRESSED_SRGB8_ETC2_OES = 0x9275, + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276, + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES = 0x9276, + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277, + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_OES = 0x9277, + GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278, + GL_COMPRESSED_RGBA8_ETC2_EAC_OES = 0x9278, + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279, + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_OES = 0x9279, + GL_BLEND_PREMULTIPLIED_SRC_NV = 0x9280, + GL_BLEND_OVERLAP_NV = 0x9281, + GL_UNCORRELATED_NV = 0x9282, + GL_DISJOINT_NV = 0x9283, + GL_CONJOINT_NV = 0x9284, + GL_BLEND_ADVANCED_COHERENT_KHR = 0x9285, + GL_BLEND_ADVANCED_COHERENT_NV = 0x9285, + GL_SRC_NV = 0x9286, + GL_DST_NV = 0x9287, + GL_SRC_OVER_NV = 0x9288, + GL_DST_OVER_NV = 0x9289, + GL_SRC_IN_NV = 0x928A, + GL_DST_IN_NV = 0x928B, + GL_SRC_OUT_NV = 0x928C, + GL_DST_OUT_NV = 0x928D, + GL_SRC_ATOP_NV = 0x928E, + GL_DST_ATOP_NV = 0x928F, + GL_PLUS_NV = 0x9291, + GL_PLUS_DARKER_NV = 0x9292, + GL_MULTIPLY = 0x9294, + GL_MULTIPLY_KHR = 0x9294, + GL_MULTIPLY_NV = 0x9294, + GL_SCREEN = 0x9295, + GL_SCREEN_KHR = 0x9295, + GL_SCREEN_NV = 0x9295, + GL_OVERLAY = 0x9296, + GL_OVERLAY_KHR = 0x9296, + GL_OVERLAY_NV = 0x9296, + GL_DARKEN = 0x9297, + GL_DARKEN_KHR = 0x9297, + GL_DARKEN_NV = 0x9297, + GL_LIGHTEN = 0x9298, + GL_LIGHTEN_KHR = 0x9298, + GL_LIGHTEN_NV = 0x9298, + GL_COLORDODGE = 0x9299, + GL_COLORDODGE_KHR = 0x9299, + GL_COLORDODGE_NV = 0x9299, + GL_COLORBURN = 0x929A, + GL_COLORBURN_KHR = 0x929A, + GL_COLORBURN_NV = 0x929A, + GL_HARDLIGHT = 0x929B, + GL_HARDLIGHT_KHR = 0x929B, + GL_HARDLIGHT_NV = 0x929B, + GL_SOFTLIGHT = 0x929C, + GL_SOFTLIGHT_KHR = 0x929C, + GL_SOFTLIGHT_NV = 0x929C, + GL_DIFFERENCE = 0x929E, + GL_DIFFERENCE_KHR = 0x929E, + GL_DIFFERENCE_NV = 0x929E, + GL_MINUS_NV = 0x929F, + GL_EXCLUSION = 0x92A0, + GL_EXCLUSION_KHR = 0x92A0, + GL_EXCLUSION_NV = 0x92A0, + GL_CONTRAST_NV = 0x92A1, + GL_INVERT_RGB_NV = 0x92A3, + GL_LINEARDODGE_NV = 0x92A4, + GL_LINEARBURN_NV = 0x92A5, + GL_VIVIDLIGHT_NV = 0x92A6, + GL_LINEARLIGHT_NV = 0x92A7, + GL_PINLIGHT_NV = 0x92A8, + GL_HARDMIX_NV = 0x92A9, + GL_HSL_HUE = 0x92AD, + GL_HSL_HUE_KHR = 0x92AD, + GL_HSL_HUE_NV = 0x92AD, + GL_HSL_SATURATION = 0x92AE, + GL_HSL_SATURATION_KHR = 0x92AE, + GL_HSL_SATURATION_NV = 0x92AE, + GL_HSL_COLOR = 0x92AF, + GL_HSL_COLOR_KHR = 0x92AF, + GL_HSL_COLOR_NV = 0x92AF, + GL_HSL_LUMINOSITY = 0x92B0, + GL_HSL_LUMINOSITY_KHR = 0x92B0, + GL_HSL_LUMINOSITY_NV = 0x92B0, + GL_PLUS_CLAMPED_NV = 0x92B1, + GL_PLUS_CLAMPED_ALPHA_NV = 0x92B2, + GL_MINUS_CLAMPED_NV = 0x92B3, + GL_INVERT_OVG_NV = 0x92B4, + GL_MAX_LGPU_GPUS_NVX = 0x92BA, + GL_MULTICAST_GPUS_NV = 0x92BA, + GL_PURGED_CONTEXT_RESET_NV = 0x92BB, + GL_PRIMITIVE_BOUNDING_BOX_ARB = 0x92BE, + GL_PRIMITIVE_BOUNDING_BOX = 0x92BE, + GL_PRIMITIVE_BOUNDING_BOX_EXT = 0x92BE, + GL_PRIMITIVE_BOUNDING_BOX_OES = 0x92BE, + GL_ALPHA_TO_COVERAGE_DITHER_MODE_NV = 0x92BF, + GL_ATOMIC_COUNTER_BUFFER = 0x92C0, + GL_ATOMIC_COUNTER_BUFFER_BINDING = 0x92C1, + GL_ATOMIC_COUNTER_BUFFER_START = 0x92C2, + GL_ATOMIC_COUNTER_BUFFER_SIZE = 0x92C3, + GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE = 0x92C4, + GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS = 0x92C5, + GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES = 0x92C6, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER = 0x92C7, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER = 0x92C8, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x92C9, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER = 0x92CA, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER = 0x92CB, + GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS = 0x92CC, + GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS = 0x92CD, + GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT = 0x92CD, + GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES = 0x92CD, + GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS = 0x92CE, + GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT = 0x92CE, + GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES = 0x92CE, + GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS = 0x92CF, + GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT = 0x92CF, + GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES = 0x92CF, + GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS = 0x92D0, + GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS = 0x92D1, + GL_MAX_VERTEX_ATOMIC_COUNTERS = 0x92D2, + GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS = 0x92D3, + GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT = 0x92D3, + GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES = 0x92D3, + GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS = 0x92D4, + GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT = 0x92D4, + GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES = 0x92D4, + GL_MAX_GEOMETRY_ATOMIC_COUNTERS = 0x92D5, + GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT = 0x92D5, + GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES = 0x92D5, + GL_MAX_FRAGMENT_ATOMIC_COUNTERS = 0x92D6, + GL_MAX_COMBINED_ATOMIC_COUNTERS = 0x92D7, + GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE = 0x92D8, + GL_ACTIVE_ATOMIC_COUNTER_BUFFERS = 0x92D9, + GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX = 0x92DA, + GL_UNSIGNED_INT_ATOMIC_COUNTER = 0x92DB, + GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 0x92DC, + GL_FRAGMENT_COVERAGE_TO_COLOR_NV = 0x92DD, + GL_FRAGMENT_COVERAGE_COLOR_NV = 0x92DE, + GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV = 0x92DF, + GL_DEBUG_OUTPUT = 0x92E0, + GL_DEBUG_OUTPUT_KHR = 0x92E0, + GL_UNIFORM = 0x92E1, + GL_UNIFORM_BLOCK = 0x92E2, + GL_PROGRAM_INPUT = 0x92E3, + GL_PROGRAM_OUTPUT = 0x92E4, + GL_BUFFER_VARIABLE = 0x92E5, + GL_SHADER_STORAGE_BLOCK = 0x92E6, + GL_IS_PER_PATCH = 0x92E7, + GL_IS_PER_PATCH_EXT = 0x92E7, + GL_IS_PER_PATCH_OES = 0x92E7, + GL_VERTEX_SUBROUTINE = 0x92E8, + GL_TESS_CONTROL_SUBROUTINE = 0x92E9, + GL_TESS_EVALUATION_SUBROUTINE = 0x92EA, + GL_GEOMETRY_SUBROUTINE = 0x92EB, + GL_FRAGMENT_SUBROUTINE = 0x92EC, + GL_COMPUTE_SUBROUTINE = 0x92ED, + GL_VERTEX_SUBROUTINE_UNIFORM = 0x92EE, + GL_TESS_CONTROL_SUBROUTINE_UNIFORM = 0x92EF, + GL_TESS_EVALUATION_SUBROUTINE_UNIFORM = 0x92F0, + GL_GEOMETRY_SUBROUTINE_UNIFORM = 0x92F1, + GL_FRAGMENT_SUBROUTINE_UNIFORM = 0x92F2, + GL_COMPUTE_SUBROUTINE_UNIFORM = 0x92F3, + GL_TRANSFORM_FEEDBACK_VARYING = 0x92F4, + GL_ACTIVE_RESOURCES = 0x92F5, + GL_MAX_NAME_LENGTH = 0x92F6, + GL_MAX_NUM_ACTIVE_VARIABLES = 0x92F7, + GL_MAX_NUM_COMPATIBLE_SUBROUTINES = 0x92F8, + GL_NAME_LENGTH = 0x92F9, + GL_TYPE = 0x92FA, + GL_ARRAY_SIZE = 0x92FB, + GL_OFFSET = 0x92FC, + GL_BLOCK_INDEX = 0x92FD, + GL_ARRAY_STRIDE = 0x92FE, + GL_MATRIX_STRIDE = 0x92FF, + GL_IS_ROW_MAJOR = 0x9300, + GL_ATOMIC_COUNTER_BUFFER_INDEX = 0x9301, + GL_BUFFER_BINDING = 0x9302, + GL_BUFFER_DATA_SIZE = 0x9303, + GL_NUM_ACTIVE_VARIABLES = 0x9304, + GL_ACTIVE_VARIABLES = 0x9305, + GL_REFERENCED_BY_VERTEX_SHADER = 0x9306, + GL_REFERENCED_BY_TESS_CONTROL_SHADER = 0x9307, + GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT = 0x9307, + GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES = 0x9307, + GL_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x9308, + GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT = 0x9308, + GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES = 0x9308, + GL_REFERENCED_BY_GEOMETRY_SHADER = 0x9309, + GL_REFERENCED_BY_GEOMETRY_SHADER_EXT = 0x9309, + GL_REFERENCED_BY_GEOMETRY_SHADER_OES = 0x9309, + GL_REFERENCED_BY_FRAGMENT_SHADER = 0x930A, + GL_REFERENCED_BY_COMPUTE_SHADER = 0x930B, + GL_TOP_LEVEL_ARRAY_SIZE = 0x930C, + GL_TOP_LEVEL_ARRAY_STRIDE = 0x930D, + GL_LOCATION = 0x930E, + GL_LOCATION_INDEX = 0x930F, + GL_LOCATION_INDEX_EXT = 0x930F, + GL_FRAMEBUFFER_DEFAULT_WIDTH = 0x9310, + GL_FRAMEBUFFER_DEFAULT_HEIGHT = 0x9311, + GL_FRAMEBUFFER_DEFAULT_LAYERS = 0x9312, + GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT = 0x9312, + GL_FRAMEBUFFER_DEFAULT_LAYERS_OES = 0x9312, + GL_FRAMEBUFFER_DEFAULT_SAMPLES = 0x9313, + GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS = 0x9314, + GL_MAX_FRAMEBUFFER_WIDTH = 0x9315, + GL_MAX_FRAMEBUFFER_HEIGHT = 0x9316, + GL_MAX_FRAMEBUFFER_LAYERS = 0x9317, + GL_MAX_FRAMEBUFFER_LAYERS_EXT = 0x9317, + GL_MAX_FRAMEBUFFER_LAYERS_OES = 0x9317, + GL_MAX_FRAMEBUFFER_SAMPLES = 0x9318, + GL_RASTER_MULTISAMPLE_EXT = 0x9327, + GL_RASTER_SAMPLES_EXT = 0x9328, + GL_MAX_RASTER_SAMPLES_EXT = 0x9329, + GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT = 0x932A, + GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT = 0x932B, + GL_EFFECTIVE_RASTER_SAMPLES_EXT = 0x932C, + GL_DEPTH_SAMPLES_NV = 0x932D, + GL_STENCIL_SAMPLES_NV = 0x932E, + GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV = 0x932F, + GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV = 0x9330, + GL_COVERAGE_MODULATION_TABLE_NV = 0x9331, + GL_COVERAGE_MODULATION_NV = 0x9332, + GL_COVERAGE_MODULATION_TABLE_SIZE_NV = 0x9333, + GL_WARP_SIZE_NV = 0x9339, + GL_WARPS_PER_SM_NV = 0x933A, + GL_SM_COUNT_NV = 0x933B, + GL_FILL_RECTANGLE_NV = 0x933C, + GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB = 0x933D, + GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV = 0x933D, + GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB = 0x933E, + GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV = 0x933E, + GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB = 0x933F, + GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV = 0x933F, + GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB = 0x9340, + GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV = 0x9340, + GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB = 0x9341, + GL_PROGRAMMABLE_SAMPLE_LOCATION_NV = 0x9341, + GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB = 0x9342, + GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV = 0x9342, + GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB = 0x9343, + GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV = 0x9343, + GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB = 0x9344, + GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB = 0x9345, + GL_CONSERVATIVE_RASTERIZATION_NV = 0x9346, + GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV = 0x9347, + GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV = 0x9348, + GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV = 0x9349, + GL_LOCATION_COMPONENT = 0x934A, + GL_TRANSFORM_FEEDBACK_BUFFER_INDEX = 0x934B, + GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE = 0x934C, + GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV = 0x934D, + GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV = 0x934E, + GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV = 0x934F, + GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV = 0x9350, + GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV = 0x9351, + GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV = 0x9352, + GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV = 0x9353, + GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV = 0x9354, + GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV = 0x9355, + GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV = 0x9356, + GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV = 0x9357, + GL_VIEWPORT_SWIZZLE_X_NV = 0x9358, + GL_VIEWPORT_SWIZZLE_Y_NV = 0x9359, + GL_VIEWPORT_SWIZZLE_Z_NV = 0x935A, + GL_VIEWPORT_SWIZZLE_W_NV = 0x935B, + GL_CLIP_ORIGIN = 0x935C, + GL_CLIP_ORIGIN_EXT = 0x935C, + GL_CLIP_DEPTH_MODE = 0x935D, + GL_CLIP_DEPTH_MODE_EXT = 0x935D, + GL_NEGATIVE_ONE_TO_ONE = 0x935E, + GL_NEGATIVE_ONE_TO_ONE_EXT = 0x935E, + GL_ZERO_TO_ONE = 0x935F, + GL_ZERO_TO_ONE_EXT = 0x935F, + GL_CLEAR_TEXTURE = 0x9365, + GL_TEXTURE_REDUCTION_MODE_ARB = 0x9366, + GL_TEXTURE_REDUCTION_MODE_EXT = 0x9366, + GL_WEIGHTED_AVERAGE_ARB = 0x9367, + GL_WEIGHTED_AVERAGE_EXT = 0x9367, + GL_FONT_GLYPHS_AVAILABLE_NV = 0x9368, + GL_FONT_TARGET_UNAVAILABLE_NV = 0x9369, + GL_FONT_UNAVAILABLE_NV = 0x936A, + GL_FONT_UNINTELLIGIBLE_NV = 0x936B, + GL_STANDARD_FONT_FORMAT_NV = 0x936C, + GL_FRAGMENT_INPUT_NV = 0x936D, + GL_UNIFORM_BUFFER_UNIFIED_NV = 0x936E, + GL_UNIFORM_BUFFER_ADDRESS_NV = 0x936F, + GL_UNIFORM_BUFFER_LENGTH_NV = 0x9370, + GL_MULTISAMPLES_NV = 0x9371, + GL_SUPERSAMPLE_SCALE_X_NV = 0x9372, + GL_SUPERSAMPLE_SCALE_Y_NV = 0x9373, + GL_CONFORMANT_NV = 0x9374, + GL_CONSERVATIVE_RASTER_DILATE_NV = 0x9379, + GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV = 0x937A, + GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV = 0x937B, + GL_VIEWPORT_POSITION_W_SCALE_NV = 0x937C, + GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV = 0x937D, + GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV = 0x937E, + GL_REPRESENTATIVE_FRAGMENT_TEST_NV = 0x937F, + GL_NUM_SAMPLE_COUNTS = 0x9380, + GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB = 0x9381, + GL_MULTISAMPLE_LINE_WIDTH_RANGE = 0x9381, + GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB = 0x9382, + GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY = 0x9382, + GL_VIEW_CLASS_EAC_R11 = 0x9383, + GL_VIEW_CLASS_EAC_RG11 = 0x9384, + GL_VIEW_CLASS_ETC2_RGB = 0x9385, + GL_VIEW_CLASS_ETC2_RGBA = 0x9386, + GL_VIEW_CLASS_ETC2_EAC_RGBA = 0x9387, + GL_VIEW_CLASS_ASTC_4x4_RGBA = 0x9388, + GL_VIEW_CLASS_ASTC_5x4_RGBA = 0x9389, + GL_VIEW_CLASS_ASTC_5x5_RGBA = 0x938A, + GL_VIEW_CLASS_ASTC_6x5_RGBA = 0x938B, + GL_VIEW_CLASS_ASTC_6x6_RGBA = 0x938C, + GL_VIEW_CLASS_ASTC_8x5_RGBA = 0x938D, + GL_VIEW_CLASS_ASTC_8x6_RGBA = 0x938E, + GL_VIEW_CLASS_ASTC_8x8_RGBA = 0x938F, + GL_VIEW_CLASS_ASTC_10x5_RGBA = 0x9390, + GL_VIEW_CLASS_ASTC_10x6_RGBA = 0x9391, + GL_VIEW_CLASS_ASTC_10x8_RGBA = 0x9392, + GL_VIEW_CLASS_ASTC_10x10_RGBA = 0x9393, + GL_VIEW_CLASS_ASTC_12x10_RGBA = 0x9394, + GL_VIEW_CLASS_ASTC_12x12_RGBA = 0x9395, + GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE = 0x93A0, + GL_BGRA8_EXT = 0x93A1, + GL_TEXTURE_USAGE_ANGLE = 0x93A2, + GL_FRAMEBUFFER_ATTACHMENT_ANGLE = 0x93A3, + GL_PACK_REVERSE_ROW_ORDER_ANGLE = 0x93A4, + GL_PROGRAM_BINARY_ANGLE = 0x93A6, + GL_COMPRESSED_RGBA_ASTC_4x4 = 0x93B0, + GL_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, + GL_COMPRESSED_RGBA_ASTC_5x4 = 0x93B1, + GL_COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1, + GL_COMPRESSED_RGBA_ASTC_5x5 = 0x93B2, + GL_COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2, + GL_COMPRESSED_RGBA_ASTC_6x5 = 0x93B3, + GL_COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3, + GL_COMPRESSED_RGBA_ASTC_6x6 = 0x93B4, + GL_COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4, + GL_COMPRESSED_RGBA_ASTC_8x5 = 0x93B5, + GL_COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5, + GL_COMPRESSED_RGBA_ASTC_8x6 = 0x93B6, + GL_COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6, + GL_COMPRESSED_RGBA_ASTC_8x8 = 0x93B7, + GL_COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7, + GL_COMPRESSED_RGBA_ASTC_10x5 = 0x93B8, + GL_COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8, + GL_COMPRESSED_RGBA_ASTC_10x6 = 0x93B9, + GL_COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9, + GL_COMPRESSED_RGBA_ASTC_10x8 = 0x93BA, + GL_COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA, + GL_COMPRESSED_RGBA_ASTC_10x10 = 0x93BB, + GL_COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB, + GL_COMPRESSED_RGBA_ASTC_12x10 = 0x93BC, + GL_COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC, + GL_COMPRESSED_RGBA_ASTC_12x12 = 0x93BD, + GL_COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD, + GL_COMPRESSED_RGBA_ASTC_3x3x3_OES = 0x93C0, + GL_COMPRESSED_RGBA_ASTC_4x3x3_OES = 0x93C1, + GL_COMPRESSED_RGBA_ASTC_4x4x3_OES = 0x93C2, + GL_COMPRESSED_RGBA_ASTC_4x4x4_OES = 0x93C3, + GL_COMPRESSED_RGBA_ASTC_5x4x4_OES = 0x93C4, + GL_COMPRESSED_RGBA_ASTC_5x5x4_OES = 0x93C5, + GL_COMPRESSED_RGBA_ASTC_5x5x5_OES = 0x93C6, + GL_COMPRESSED_RGBA_ASTC_6x5x5_OES = 0x93C7, + GL_COMPRESSED_RGBA_ASTC_6x6x5_OES = 0x93C8, + GL_COMPRESSED_RGBA_ASTC_6x6x6_OES = 0x93C9, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4 = 0x93D0, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4 = 0x93D1, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5 = 0x93D2, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5 = 0x93D3, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6 = 0x93D4, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5 = 0x93D5, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6 = 0x93D6, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8 = 0x93D7, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5 = 0x93D8, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6 = 0x93D9, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8 = 0x93DA, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10 = 0x93DB, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10 = 0x93DC, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12 = 0x93DD, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES = 0x93E0, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES = 0x93E1, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES = 0x93E2, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES = 0x93E3, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES = 0x93E4, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES = 0x93E5, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES = 0x93E6, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES = 0x93E7, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES = 0x93E8, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES = 0x93E9, + GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG = 0x93F0, + GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG = 0x93F1, + GL_PERFQUERY_COUNTER_EVENT_INTEL = 0x94F0, + GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL = 0x94F1, + GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL = 0x94F2, + GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL = 0x94F3, + GL_PERFQUERY_COUNTER_RAW_INTEL = 0x94F4, + GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL = 0x94F5, + GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL = 0x94F8, + GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL = 0x94F9, + GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL = 0x94FA, + GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL = 0x94FB, + GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL = 0x94FC, + GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL = 0x94FD, + GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL = 0x94FE, + GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL = 0x94FF, + GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL = 0x9500, + GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT = 0x9530, + GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT = 0x9531, + GL_SUBGROUP_SIZE_KHR = 0x9532, + GL_SUBGROUP_SUPPORTED_STAGES_KHR = 0x9533, + GL_SUBGROUP_SUPPORTED_FEATURES_KHR = 0x9534, + GL_SUBGROUP_QUAD_ALL_STAGES_KHR = 0x9535, + GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV = 0x9536, + GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV = 0x9537, + GL_MAX_MESH_OUTPUT_VERTICES_NV = 0x9538, + GL_MAX_MESH_OUTPUT_PRIMITIVES_NV = 0x9539, + GL_MAX_TASK_OUTPUT_COUNT_NV = 0x953A, + GL_MAX_MESH_WORK_GROUP_SIZE_NV = 0x953B, + GL_MAX_TASK_WORK_GROUP_SIZE_NV = 0x953C, + GL_MAX_DRAW_MESH_TASKS_COUNT_NV = 0x953D, + GL_MESH_WORK_GROUP_SIZE_NV = 0x953E, + GL_TASK_WORK_GROUP_SIZE_NV = 0x953F, + GL_QUERY_RESOURCE_TYPE_VIDMEM_ALLOC_NV = 0x9540, + GL_QUERY_RESOURCE_MEMTYPE_VIDMEM_NV = 0x9542, + GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV = 0x9543, + GL_QUERY_RESOURCE_SYS_RESERVED_NV = 0x9544, + GL_QUERY_RESOURCE_TEXTURE_NV = 0x9545, + GL_QUERY_RESOURCE_RENDERBUFFER_NV = 0x9546, + GL_QUERY_RESOURCE_BUFFEROBJECT_NV = 0x9547, + GL_PER_GPU_STORAGE_NV = 0x9548, + GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV = 0x9549, + GL_UPLOAD_GPU_MASK_NVX = 0x954A, + GL_CONSERVATIVE_RASTER_MODE_NV = 0x954D, + GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV = 0x954E, + GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV = 0x954F, + GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV = 0x9550, + GL_SHADER_BINARY_FORMAT_SPIR_V = 0x9551, + GL_SHADER_BINARY_FORMAT_SPIR_V_ARB = 0x9551, + GL_SPIR_V_BINARY = 0x9552, + GL_SPIR_V_BINARY_ARB = 0x9552, + GL_SPIR_V_EXTENSIONS = 0x9553, + GL_NUM_SPIR_V_EXTENSIONS = 0x9554, + GL_SCISSOR_TEST_EXCLUSIVE_NV = 0x9555, + GL_SCISSOR_BOX_EXCLUSIVE_NV = 0x9556, + GL_MAX_MESH_VIEWS_NV = 0x9557, + GL_RENDER_GPU_MASK_NV = 0x9558, + GL_MESH_SHADER_NV = 0x9559, + GL_TASK_SHADER_NV = 0x955A, + GL_SHADING_RATE_IMAGE_BINDING_NV = 0x955B, + GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV = 0x955C, + GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV = 0x955D, + GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV = 0x955E, + GL_MAX_COARSE_FRAGMENT_SAMPLES_NV = 0x955F, + GL_SHADING_RATE_IMAGE_NV = 0x9563, + GL_SHADING_RATE_NO_INVOCATIONS_NV = 0x9564, + GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV = 0x9565, + GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV = 0x9566, + GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV = 0x9567, + GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV = 0x9568, + GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV = 0x9569, + GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV = 0x956A, + GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV = 0x956B, + GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV = 0x956C, + GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV = 0x956D, + GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV = 0x956E, + GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV = 0x956F, + GL_MESH_VERTICES_OUT_NV = 0x9579, + GL_MESH_PRIMITIVES_OUT_NV = 0x957A, + GL_MESH_OUTPUT_TYPE_NV = 0x957B, + GL_MESH_SUBROUTINE_NV = 0x957C, + GL_TASK_SUBROUTINE_NV = 0x957D, + GL_MESH_SUBROUTINE_UNIFORM_NV = 0x957E, + GL_TASK_SUBROUTINE_UNIFORM_NV = 0x957F, + GL_TEXTURE_TILING_EXT = 0x9580, + GL_DEDICATED_MEMORY_OBJECT_EXT = 0x9581, + GL_NUM_TILING_TYPES_EXT = 0x9582, + GL_TILING_TYPES_EXT = 0x9583, + GL_OPTIMAL_TILING_EXT = 0x9584, + GL_LINEAR_TILING_EXT = 0x9585, + GL_HANDLE_TYPE_OPAQUE_FD_EXT = 0x9586, + GL_HANDLE_TYPE_OPAQUE_WIN32_EXT = 0x9587, + GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT = 0x9588, + GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT = 0x9589, + GL_HANDLE_TYPE_D3D12_RESOURCE_EXT = 0x958A, + GL_HANDLE_TYPE_D3D11_IMAGE_EXT = 0x958B, + GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT = 0x958C, + GL_LAYOUT_GENERAL_EXT = 0x958D, + GL_LAYOUT_COLOR_ATTACHMENT_EXT = 0x958E, + GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT = 0x958F, + GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT = 0x9590, + GL_LAYOUT_SHADER_READ_ONLY_EXT = 0x9591, + GL_LAYOUT_TRANSFER_SRC_EXT = 0x9592, + GL_LAYOUT_TRANSFER_DST_EXT = 0x9593, + GL_HANDLE_TYPE_D3D12_FENCE_EXT = 0x9594, + GL_D3D12_FENCE_VALUE_EXT = 0x9595, + GL_TIMELINE_SEMAPHORE_VALUE_NV = 0x9595, + GL_NUM_DEVICE_UUIDS_EXT = 0x9596, + GL_DEVICE_UUID_EXT = 0x9597, + GL_DRIVER_UUID_EXT = 0x9598, + GL_DEVICE_LUID_EXT = 0x9599, + GL_DEVICE_NODE_MASK_EXT = 0x959A, + GL_PROTECTED_MEMORY_OBJECT_EXT = 0x959B, + GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV = 0x959C, + GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV = 0x959D, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV = 0x959E, + GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV = 0x959F, + GL_REFERENCED_BY_MESH_SHADER_NV = 0x95A0, + GL_REFERENCED_BY_TASK_SHADER_NV = 0x95A1, + GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV = 0x95A2, + GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV = 0x95A3, + GL_ATTACHED_MEMORY_OBJECT_NV = 0x95A4, + GL_ATTACHED_MEMORY_OFFSET_NV = 0x95A5, + GL_MEMORY_ATTACHABLE_ALIGNMENT_NV = 0x95A6, + GL_MEMORY_ATTACHABLE_SIZE_NV = 0x95A7, + GL_MEMORY_ATTACHABLE_NV = 0x95A8, + GL_DETACHED_MEMORY_INCARNATION_NV = 0x95A9, + GL_DETACHED_TEXTURES_NV = 0x95AA, + GL_DETACHED_BUFFERS_NV = 0x95AB, + GL_MAX_DETACHED_TEXTURES_NV = 0x95AC, + GL_MAX_DETACHED_BUFFERS_NV = 0x95AD, + GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV = 0x95AE, + GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV = 0x95AF, + GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV = 0x95B0, + GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV = 0x95B1, + GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV = 0x95B2, + GL_SEMAPHORE_TYPE_NV = 0x95B3, + GL_SEMAPHORE_TYPE_BINARY_NV = 0x95B4, + GL_SEMAPHORE_TYPE_TIMELINE_NV = 0x95B5, + GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV = 0x95B6, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR = 0x9630, + GL_MAX_VIEWS_OVR = 0x9631, + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR = 0x9632, + GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR = 0x9633, + GL_GS_SHADER_BINARY_MTK = 0x9640, + GL_GS_PROGRAM_BINARY_MTK = 0x9641, + GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT = 0x9650, + GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT = 0x9651, + GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT = 0x9652, + GL_TEXTURE_FOVEATED_CUTOFF_DENSITY_QCOM = 0x96A0, + GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM = 0x96A2, + GL_VALIDATE_SHADER_BINARY_QCOM = 0x96A3, + GL_SHADING_RATE_QCOM = 0x96A4, + GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM = 0x96A5, + GL_SHADING_RATE_1X1_PIXELS_QCOM = 0x96A6, + GL_SHADING_RATE_1X2_PIXELS_QCOM = 0x96A7, + GL_SHADING_RATE_2X1_PIXELS_QCOM = 0x96A8, + GL_SHADING_RATE_2X2_PIXELS_QCOM = 0x96A9, + GL_SHADING_RATE_1X4_PIXELS_QCOM = 0x96AA, + GL_SHADING_RATE_4X1_PIXELS_QCOM = 0x96AB, + GL_SHADING_RATE_4X2_PIXELS_QCOM = 0x96AC, + GL_SHADING_RATE_2X4_PIXELS_QCOM = 0x96AD, + GL_SHADING_RATE_4X4_PIXELS_QCOM = 0x96AE, + GL_RASTER_POSITION_UNCLIPPED_IBM = 0x19262, + GL_CULL_VERTEX_IBM = 103050, + GL_ALL_STATIC_DATA_IBM = 103060, + GL_STATIC_VERTEX_ARRAY_IBM = 103061, + GL_VERTEX_ARRAY_LIST_IBM = 103070, + GL_NORMAL_ARRAY_LIST_IBM = 103071, + GL_COLOR_ARRAY_LIST_IBM = 103072, + GL_INDEX_ARRAY_LIST_IBM = 103073, + GL_TEXTURE_COORD_ARRAY_LIST_IBM = 103074, + GL_EDGE_FLAG_ARRAY_LIST_IBM = 103075, + GL_FOG_COORDINATE_ARRAY_LIST_IBM = 103076, + GL_SECONDARY_COLOR_ARRAY_LIST_IBM = 103077, + GL_VERTEX_ARRAY_LIST_STRIDE_IBM = 103080, + GL_NORMAL_ARRAY_LIST_STRIDE_IBM = 103081, + GL_COLOR_ARRAY_LIST_STRIDE_IBM = 103082, + GL_INDEX_ARRAY_LIST_STRIDE_IBM = 103083, + GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM = 103084, + GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM = 103085, + GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM = 103086, + GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM = 103087, + GL_PREFER_DOUBLEBUFFER_HINT_PGI = 0x1A1F8, + GL_CONSERVE_MEMORY_HINT_PGI = 0x1A1FD, + GL_RECLAIM_MEMORY_HINT_PGI = 0x1A1FE, + GL_NATIVE_GRAPHICS_HANDLE_PGI = 0x1A202, + GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI = 0x1A203, + GL_NATIVE_GRAPHICS_END_HINT_PGI = 0x1A204, + GL_ALWAYS_FAST_HINT_PGI = 0x1A20C, + GL_ALWAYS_SOFT_HINT_PGI = 0x1A20D, + GL_ALLOW_DRAW_OBJ_HINT_PGI = 0x1A20E, + GL_ALLOW_DRAW_WIN_HINT_PGI = 0x1A20F, + GL_ALLOW_DRAW_FRG_HINT_PGI = 0x1A210, + GL_ALLOW_DRAW_MEM_HINT_PGI = 0x1A211, + GL_STRICT_DEPTHFUNC_HINT_PGI = 0x1A216, + GL_STRICT_LIGHTING_HINT_PGI = 0x1A217, + GL_STRICT_SCISSOR_HINT_PGI = 0x1A218, + GL_FULL_STIPPLE_HINT_PGI = 0x1A219, + GL_CLIP_NEAR_HINT_PGI = 0x1A220, + GL_CLIP_FAR_HINT_PGI = 0x1A221, + GL_WIDE_LINE_HINT_PGI = 0x1A222, + GL_BACK_NORMALS_HINT_PGI = 0x1A223, + GL_VERTEX_DATA_HINT_PGI = 0x1A22A, + GL_VERTEX_CONSISTENT_HINT_PGI = 0x1A22B, + GL_MATERIAL_SIDE_HINT_PGI = 0x1A22C, + GL_MAX_VERTEX_HINT_PGI = 0x1A22D, + WGL_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, + WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, + WGL_NO_RESET_NOTIFICATION_ARB = 0x8261, + WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126, +} GL; + +typedef enum RegisterCombinerPname { + GL_COMBINE = 0x8570, + GL_COMBINE_ARB = 0x8570, + GL_COMBINE_EXT = 0x8570, + GL_COMBINE_RGB = 0x8571, + GL_COMBINE_RGB_ARB = 0x8571, + GL_COMBINE_RGB_EXT = 0x8571, + GL_COMBINE_ALPHA = 0x8572, + GL_COMBINE_ALPHA_ARB = 0x8572, + GL_COMBINE_ALPHA_EXT = 0x8572, + GL_RGB_SCALE = 0x8573, + GL_RGB_SCALE_ARB = 0x8573, + GL_RGB_SCALE_EXT = 0x8573, + GL_ADD_SIGNED = 0x8574, + GL_ADD_SIGNED_ARB = 0x8574, + GL_ADD_SIGNED_EXT = 0x8574, + GL_INTERPOLATE = 0x8575, + GL_INTERPOLATE_ARB = 0x8575, + GL_INTERPOLATE_EXT = 0x8575, + GL_CONSTANT = 0x8576, + GL_CONSTANT_ARB = 0x8576, + GL_CONSTANT_EXT = 0x8576, + GL_CONSTANT_NV = 0x8576, + GL_PRIMARY_COLOR = 0x8577, + GL_PRIMARY_COLOR_ARB = 0x8577, + GL_PRIMARY_COLOR_EXT = 0x8577, + GL_PREVIOUS = 0x8578, + GL_PREVIOUS_ARB = 0x8578, + GL_PREVIOUS_EXT = 0x8578, + GL_SOURCE0_RGB = 0x8580, + GL_SOURCE0_RGB_ARB = 0x8580, + GL_SOURCE0_RGB_EXT = 0x8580, + GL_SRC0_RGB = 0x8580, + GL_SOURCE1_RGB = 0x8581, + GL_SOURCE1_RGB_ARB = 0x8581, + GL_SOURCE1_RGB_EXT = 0x8581, + GL_SRC1_RGB = 0x8581, + GL_SOURCE2_RGB = 0x8582, + GL_SOURCE2_RGB_ARB = 0x8582, + GL_SOURCE2_RGB_EXT = 0x8582, + GL_SRC2_RGB = 0x8582, + GL_SOURCE3_RGB_NV = 0x8583, + GL_SOURCE0_ALPHA = 0x8588, + GL_SOURCE0_ALPHA_ARB = 0x8588, + GL_SOURCE0_ALPHA_EXT = 0x8588, + GL_SRC0_ALPHA = 0x8588, + GL_SOURCE1_ALPHA = 0x8589, + GL_SOURCE1_ALPHA_ARB = 0x8589, + GL_SOURCE1_ALPHA_EXT = 0x8589, + GL_SRC1_ALPHA = 0x8589, + GL_SRC1_ALPHA_EXT = 0x8589, + GL_SOURCE2_ALPHA = 0x858A, + GL_SOURCE2_ALPHA_ARB = 0x858A, + GL_SOURCE2_ALPHA_EXT = 0x858A, + GL_SRC2_ALPHA = 0x858A, + GL_SOURCE3_ALPHA_NV = 0x858B, + GL_OPERAND0_RGB = 0x8590, + GL_OPERAND0_RGB_ARB = 0x8590, + GL_OPERAND0_RGB_EXT = 0x8590, + GL_OPERAND1_RGB = 0x8591, + GL_OPERAND1_RGB_ARB = 0x8591, + GL_OPERAND1_RGB_EXT = 0x8591, + GL_OPERAND2_RGB = 0x8592, + GL_OPERAND2_RGB_ARB = 0x8592, + GL_OPERAND2_RGB_EXT = 0x8592, + GL_OPERAND3_RGB_NV = 0x8593, + GL_OPERAND0_ALPHA = 0x8598, + GL_OPERAND0_ALPHA_ARB = 0x8598, + GL_OPERAND0_ALPHA_EXT = 0x8598, + GL_OPERAND1_ALPHA = 0x8599, + GL_OPERAND1_ALPHA_ARB = 0x8599, + GL_OPERAND1_ALPHA_EXT = 0x8599, + GL_OPERAND2_ALPHA = 0x859A, + GL_OPERAND2_ALPHA_ARB = 0x859A, + GL_OPERAND2_ALPHA_EXT = 0x859A, + GL_OPERAND3_ALPHA_NV = 0x859B, +} RegisterCombinerPname; + +typedef enum ShaderType { + GL_FRAGMENT_SHADER = 0x8B30, + GL_FRAGMENT_SHADER_ARB = 0x8B30, + GL_VERTEX_SHADER = 0x8B31, + GL_VERTEX_SHADER_ARB = 0x8B31, +} ShaderType; + +typedef enum ContainerType { + GL_PROGRAM_OBJECT_ARB = 0x8B40, + GL_PROGRAM_OBJECT_EXT = 0x8B40, +} ContainerType; + +typedef enum AttributeType { + GL_FLOAT_VEC2 = 0x8B50, + GL_FLOAT_VEC2_ARB = 0x8B50, + GL_FLOAT_VEC3 = 0x8B51, + GL_FLOAT_VEC3_ARB = 0x8B51, + GL_FLOAT_VEC4 = 0x8B52, + GL_FLOAT_VEC4_ARB = 0x8B52, + GL_INT_VEC2 = 0x8B53, + GL_INT_VEC2_ARB = 0x8B53, + GL_INT_VEC3 = 0x8B54, + GL_INT_VEC3_ARB = 0x8B54, + GL_INT_VEC4 = 0x8B55, + GL_INT_VEC4_ARB = 0x8B55, + GL_BOOL = 0x8B56, + GL_BOOL_ARB = 0x8B56, + GL_BOOL_VEC2 = 0x8B57, + GL_BOOL_VEC2_ARB = 0x8B57, + GL_BOOL_VEC3 = 0x8B58, + GL_BOOL_VEC3_ARB = 0x8B58, + GL_BOOL_VEC4 = 0x8B59, + GL_BOOL_VEC4_ARB = 0x8B59, + GL_FLOAT_MAT2 = 0x8B5A, + GL_FLOAT_MAT2_ARB = 0x8B5A, + GL_FLOAT_MAT3 = 0x8B5B, + GL_FLOAT_MAT3_ARB = 0x8B5B, + GL_FLOAT_MAT4 = 0x8B5C, + GL_FLOAT_MAT4_ARB = 0x8B5C, + GL_SAMPLER_1D = 0x8B5D, + GL_SAMPLER_1D_ARB = 0x8B5D, + GL_SAMPLER_2D = 0x8B5E, + GL_SAMPLER_2D_ARB = 0x8B5E, + GL_SAMPLER_3D = 0x8B5F, + GL_SAMPLER_3D_ARB = 0x8B5F, + GL_SAMPLER_3D_OES = 0x8B5F, + GL_SAMPLER_CUBE = 0x8B60, + GL_SAMPLER_CUBE_ARB = 0x8B60, + GL_SAMPLER_1D_SHADOW = 0x8B61, + GL_SAMPLER_1D_SHADOW_ARB = 0x8B61, + GL_SAMPLER_2D_SHADOW = 0x8B62, + GL_SAMPLER_2D_SHADOW_ARB = 0x8B62, + GL_SAMPLER_2D_SHADOW_EXT = 0x8B62, + GL_SAMPLER_2D_RECT = 0x8B63, + GL_SAMPLER_2D_RECT_ARB = 0x8B63, + GL_SAMPLER_2D_RECT_SHADOW = 0x8B64, + GL_SAMPLER_2D_RECT_SHADOW_ARB = 0x8B64, + GL_FLOAT_MAT2x3 = 0x8B65, + GL_FLOAT_MAT2x3_NV = 0x8B65, + GL_FLOAT_MAT2x4 = 0x8B66, + GL_FLOAT_MAT2x4_NV = 0x8B66, + GL_FLOAT_MAT3x2 = 0x8B67, + GL_FLOAT_MAT3x2_NV = 0x8B67, + GL_FLOAT_MAT3x4 = 0x8B68, + GL_FLOAT_MAT3x4_NV = 0x8B68, + GL_FLOAT_MAT4x2 = 0x8B69, + GL_FLOAT_MAT4x2_NV = 0x8B69, + GL_FLOAT_MAT4x3 = 0x8B6A, + GL_FLOAT_MAT4x3_NV = 0x8B6A, +} AttributeType; + +typedef enum WGLColorBufferMask { + WGL_FRONT_COLOR_BUFFER_BIT_ARB = 0x00000001, + WGL_BACK_COLOR_BUFFER_BIT_ARB = 0x00000002, + WGL_DEPTH_BUFFER_BIT_ARB = 0x00000004, + WGL_STENCIL_BUFFER_BIT_ARB = 0x00000008, +} WGLColorBufferMask; + +typedef enum WGLContextFlagsMask { + WGL_CONTEXT_DEBUG_BIT_ARB = 0x00000001, + WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x00000002, + WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB = 0x00000004, + WGL_CONTEXT_RESET_ISOLATION_BIT_ARB = 0x00000008, +} WGLContextFlagsMask; + +typedef enum WGLContextProfileMask { + WGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001, + WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002, + WGL_CONTEXT_ES_PROFILE_BIT_EXT = 0x00000004, + WGL_CONTEXT_ES2_PROFILE_BIT_EXT = 0x00000004, +} WGLContextProfileMask; + +typedef enum WGLImageBufferMaskI3D { + WGL_IMAGE_BUFFER_MIN_ACCESS_I3D = 0x00000001, + WGL_IMAGE_BUFFER_LOCK_I3D = 0x00000002, +} WGLImageBufferMaskI3D; + +typedef enum WGLDXInteropMaskNV { + WGL_ACCESS_READ_ONLY_NV = 0x00000000, + WGL_ACCESS_READ_WRITE_NV = 0x00000001, + WGL_ACCESS_WRITE_DISCARD_NV = 0x00000002, +} WGLDXInteropMaskNV; + +typedef enum WGL { + WGL_GPU_VENDOR_AMD = 0x1F00, + WGL_GPU_RENDERER_STRING_AMD = 0x1F01, + WGL_GPU_OPENGL_VERSION_STRING_AMD = 0x1F02, + WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000, + WGL_NUMBER_PIXEL_FORMATS_EXT = 0x2000, + WGL_DRAW_TO_WINDOW_ARB = 0x2001, + WGL_DRAW_TO_WINDOW_EXT = 0x2001, + WGL_DRAW_TO_BITMAP_ARB = 0x2002, + WGL_DRAW_TO_BITMAP_EXT = 0x2002, + WGL_ACCELERATION_ARB = 0x2003, + WGL_ACCELERATION_EXT = 0x2003, + WGL_NEED_PALETTE_ARB = 0x2004, + WGL_NEED_PALETTE_EXT = 0x2004, + WGL_NEED_SYSTEM_PALETTE_ARB = 0x2005, + WGL_NEED_SYSTEM_PALETTE_EXT = 0x2005, + WGL_SWAP_LAYER_BUFFERS_ARB = 0x2006, + WGL_SWAP_LAYER_BUFFERS_EXT = 0x2006, + WGL_SWAP_METHOD_ARB = 0x2007, + WGL_SWAP_METHOD_EXT = 0x2007, + WGL_NUMBER_OVERLAYS_ARB = 0x2008, + WGL_NUMBER_OVERLAYS_EXT = 0x2008, + WGL_NUMBER_UNDERLAYS_ARB = 0x2009, + WGL_NUMBER_UNDERLAYS_EXT = 0x2009, + WGL_TRANSPARENT_ARB = 0x200A, + WGL_TRANSPARENT_EXT = 0x200A, + WGL_TRANSPARENT_VALUE_EXT = 0x200B, + WGL_SHARE_DEPTH_ARB = 0x200C, + WGL_SHARE_DEPTH_EXT = 0x200C, + WGL_SHARE_STENCIL_ARB = 0x200D, + WGL_SHARE_STENCIL_EXT = 0x200D, + WGL_SHARE_ACCUM_ARB = 0x200E, + WGL_SHARE_ACCUM_EXT = 0x200E, + WGL_SUPPORT_GDI_ARB = 0x200F, + WGL_SUPPORT_GDI_EXT = 0x200F, + WGL_SUPPORT_OPENGL_ARB = 0x2010, + WGL_SUPPORT_OPENGL_EXT = 0x2010, + WGL_DOUBLE_BUFFER_ARB = 0x2011, + WGL_DOUBLE_BUFFER_EXT = 0x2011, + WGL_STEREO_ARB = 0x2012, + WGL_STEREO_EXT = 0x2012, + WGL_PIXEL_TYPE_ARB = 0x2013, + WGL_PIXEL_TYPE_EXT = 0x2013, + WGL_COLOR_BITS_ARB = 0x2014, + WGL_COLOR_BITS_EXT = 0x2014, + WGL_RED_BITS_ARB = 0x2015, + WGL_RED_BITS_EXT = 0x2015, + WGL_RED_SHIFT_ARB = 0x2016, + WGL_RED_SHIFT_EXT = 0x2016, + WGL_GREEN_BITS_ARB = 0x2017, + WGL_GREEN_BITS_EXT = 0x2017, + WGL_GREEN_SHIFT_ARB = 0x2018, + WGL_GREEN_SHIFT_EXT = 0x2018, + WGL_BLUE_BITS_ARB = 0x2019, + WGL_BLUE_BITS_EXT = 0x2019, + WGL_BLUE_SHIFT_ARB = 0x201A, + WGL_BLUE_SHIFT_EXT = 0x201A, + WGL_ALPHA_BITS_ARB = 0x201B, + WGL_ALPHA_BITS_EXT = 0x201B, + WGL_ALPHA_SHIFT_ARB = 0x201C, + WGL_ALPHA_SHIFT_EXT = 0x201C, + WGL_ACCUM_BITS_ARB = 0x201D, + WGL_ACCUM_BITS_EXT = 0x201D, + WGL_ACCUM_RED_BITS_ARB = 0x201E, + WGL_ACCUM_RED_BITS_EXT = 0x201E, + WGL_ACCUM_GREEN_BITS_ARB = 0x201F, + WGL_ACCUM_GREEN_BITS_EXT = 0x201F, + WGL_ACCUM_BLUE_BITS_ARB = 0x2020, + WGL_ACCUM_BLUE_BITS_EXT = 0x2020, + WGL_ACCUM_ALPHA_BITS_ARB = 0x2021, + WGL_ACCUM_ALPHA_BITS_EXT = 0x2021, + WGL_DEPTH_BITS_ARB = 0x2022, + WGL_DEPTH_BITS_EXT = 0x2022, + WGL_STENCIL_BITS_ARB = 0x2023, + WGL_STENCIL_BITS_EXT = 0x2023, + WGL_AUX_BUFFERS_ARB = 0x2024, + WGL_AUX_BUFFERS_EXT = 0x2024, + WGL_NO_ACCELERATION_ARB = 0x2025, + WGL_NO_ACCELERATION_EXT = 0x2025, + WGL_GENERIC_ACCELERATION_ARB = 0x2026, + WGL_GENERIC_ACCELERATION_EXT = 0x2026, + WGL_FULL_ACCELERATION_ARB = 0x2027, + WGL_FULL_ACCELERATION_EXT = 0x2027, + WGL_SWAP_EXCHANGE_ARB = 0x2028, + WGL_SWAP_EXCHANGE_EXT = 0x2028, + WGL_SWAP_COPY_ARB = 0x2029, + WGL_SWAP_COPY_EXT = 0x2029, + WGL_SWAP_UNDEFINED_ARB = 0x202A, + WGL_SWAP_UNDEFINED_EXT = 0x202A, + WGL_TYPE_RGBA_ARB = 0x202B, + WGL_TYPE_RGBA_EXT = 0x202B, + WGL_TYPE_COLORINDEX_ARB = 0x202C, + WGL_TYPE_COLORINDEX_EXT = 0x202C, + WGL_DRAW_TO_PBUFFER_ARB = 0x202D, + WGL_DRAW_TO_PBUFFER_EXT = 0x202D, + WGL_MAX_PBUFFER_PIXELS_ARB = 0x202E, + WGL_MAX_PBUFFER_PIXELS_EXT = 0x202E, + WGL_MAX_PBUFFER_WIDTH_ARB = 0x202F, + WGL_MAX_PBUFFER_WIDTH_EXT = 0x202F, + WGL_MAX_PBUFFER_HEIGHT_ARB = 0x2030, + WGL_MAX_PBUFFER_HEIGHT_EXT = 0x2030, + WGL_OPTIMAL_PBUFFER_WIDTH_EXT = 0x2031, + WGL_OPTIMAL_PBUFFER_HEIGHT_EXT = 0x2032, + WGL_PBUFFER_LARGEST_ARB = 0x2033, + WGL_PBUFFER_LARGEST_EXT = 0x2033, + WGL_PBUFFER_WIDTH_ARB = 0x2034, + WGL_PBUFFER_WIDTH_EXT = 0x2034, + WGL_PBUFFER_HEIGHT_ARB = 0x2035, + WGL_PBUFFER_HEIGHT_EXT = 0x2035, + WGL_PBUFFER_LOST_ARB = 0x2036, + WGL_TRANSPARENT_RED_VALUE_ARB = 0x2037, + WGL_TRANSPARENT_GREEN_VALUE_ARB = 0x2038, + WGL_TRANSPARENT_BLUE_VALUE_ARB = 0x2039, + WGL_TRANSPARENT_ALPHA_VALUE_ARB = 0x203A, + WGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B, + WGL_DEPTH_FLOAT_EXT = 0x2040, + WGL_SAMPLE_BUFFERS_ARB = 0x2041, + WGL_SAMPLE_BUFFERS_EXT = 0x2041, + WGL_COVERAGE_SAMPLES_NV = 0x2042, + WGL_SAMPLES_ARB = 0x2042, + WGL_SAMPLES_EXT = 0x2042, + ERROR_INVALID_PIXEL_TYPE_ARB = 0x2043, + ERROR_INVALID_PIXEL_TYPE_EXT = 0x2043, + WGL_GENLOCK_SOURCE_MULTIVIEW_I3D = 0x2044, + WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D = 0x2045, + WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D = 0x2046, + WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D = 0x2047, + WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = 0x2048, + WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = 0x2049, + WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = 0x204A, + WGL_GENLOCK_SOURCE_EDGE_RISING_I3D = 0x204B, + WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = 0x204C, + WGL_GAMMA_TABLE_SIZE_I3D = 0x204E, + WGL_GAMMA_EXCLUDE_DESKTOP_I3D = 0x204F, + WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = 0x2050, + WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = 0x2051, + WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = 0x2052, + WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = 0x2053, + ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = 0x2054, + WGL_STEREO_EMITTER_ENABLE_3DL = 0x2055, + WGL_STEREO_EMITTER_DISABLE_3DL = 0x2056, + WGL_STEREO_POLARITY_NORMAL_3DL = 0x2057, + WGL_STEREO_POLARITY_INVERT_3DL = 0x2058, + WGL_SAMPLE_BUFFERS_3DFX = 0x2060, + WGL_SAMPLES_3DFX = 0x2061, + WGL_BIND_TO_TEXTURE_RGB_ARB = 0x2070, + WGL_BIND_TO_TEXTURE_RGBA_ARB = 0x2071, + WGL_TEXTURE_FORMAT_ARB = 0x2072, + WGL_TEXTURE_TARGET_ARB = 0x2073, + WGL_MIPMAP_TEXTURE_ARB = 0x2074, + WGL_TEXTURE_RGB_ARB = 0x2075, + WGL_TEXTURE_RGBA_ARB = 0x2076, + WGL_NO_TEXTURE_ARB = 0x2077, + WGL_TEXTURE_CUBE_MAP_ARB = 0x2078, + WGL_TEXTURE_1D_ARB = 0x2079, + WGL_TEXTURE_2D_ARB = 0x207A, + WGL_MIPMAP_LEVEL_ARB = 0x207B, + WGL_CUBE_MAP_FACE_ARB = 0x207C, + WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 0x207D, + WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 0x207E, + WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 0x207F, + WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 0x2080, + WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 0x2081, + WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 0x2082, + WGL_FRONT_LEFT_ARB = 0x2083, + WGL_FRONT_RIGHT_ARB = 0x2084, + WGL_BACK_LEFT_ARB = 0x2085, + WGL_BACK_RIGHT_ARB = 0x2086, + WGL_AUX0_ARB = 0x2087, + WGL_AUX1_ARB = 0x2088, + WGL_AUX2_ARB = 0x2089, + WGL_AUX3_ARB = 0x208A, + WGL_AUX4_ARB = 0x208B, + WGL_AUX5_ARB = 0x208C, + WGL_AUX6_ARB = 0x208D, + WGL_AUX7_ARB = 0x208E, + WGL_AUX8_ARB = 0x208F, + WGL_AUX9_ARB = 0x2090, + WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091, + WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092, + WGL_CONTEXT_LAYER_PLANE_ARB = 0x2093, + WGL_CONTEXT_FLAGS_ARB = 0x2094, + ERROR_INVALID_VERSION_ARB = 0x2095, + ERROR_INVALID_PROFILE_ARB = 0x2096, + WGL_CONTEXT_RELEASE_BEHAVIOR_ARB = 0x2097, + WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = 0x2098, + WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = 0x20A0, + WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = 0x20A1, + WGL_TEXTURE_RECTANGLE_NV = 0x20A2, + WGL_BIND_TO_TEXTURE_DEPTH_NV = 0x20A3, + WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV = 0x20A4, + WGL_DEPTH_TEXTURE_FORMAT_NV = 0x20A5, + WGL_TEXTURE_DEPTH_COMPONENT_NV = 0x20A6, + WGL_DEPTH_COMPONENT_NV = 0x20A7, + WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT = 0x20A8, + WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB = 0x20A9, + WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x20A9, + WGL_CONTEXT_MULTIGPU_ATTRIB_NV = 0x20AA, + WGL_CONTEXT_MULTIGPU_ATTRIB_SINGLE_NV = 0x20AB, + WGL_CONTEXT_MULTIGPU_ATTRIB_AFR_NV = 0x20AC, + WGL_CONTEXT_MULTIGPU_ATTRIB_MULTICAST_NV = 0x20AD, + WGL_CONTEXT_MULTIGPU_ATTRIB_MULTI_DISPLAY_MULTICAST_NV = 0x20AE, + WGL_FLOAT_COMPONENTS_NV = 0x20B0, + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = 0x20B1, + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = 0x20B2, + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = 0x20B3, + WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = 0x20B4, + WGL_TEXTURE_FLOAT_R_NV = 0x20B5, + WGL_TEXTURE_FLOAT_RG_NV = 0x20B6, + WGL_TEXTURE_FLOAT_RGB_NV = 0x20B7, + WGL_TEXTURE_FLOAT_RGBA_NV = 0x20B8, + WGL_COLOR_SAMPLES_NV = 0x20B9, + WGL_BIND_TO_VIDEO_RGB_NV = 0x20C0, + WGL_BIND_TO_VIDEO_RGBA_NV = 0x20C1, + WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV = 0x20C2, + WGL_VIDEO_OUT_COLOR_NV = 0x20C3, + WGL_VIDEO_OUT_ALPHA_NV = 0x20C4, + WGL_VIDEO_OUT_DEPTH_NV = 0x20C5, + WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV = 0x20C6, + WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV = 0x20C7, + WGL_VIDEO_OUT_FRAME = 0x20C8, + WGL_VIDEO_OUT_FIELD_1 = 0x20C9, + WGL_VIDEO_OUT_FIELD_2 = 0x20CA, + WGL_VIDEO_OUT_STACKED_FIELDS_1_2 = 0x20CB, + WGL_VIDEO_OUT_STACKED_FIELDS_2_1 = 0x20CC, + WGL_UNIQUE_ID_NV = 0x20CE, + WGL_NUM_VIDEO_CAPTURE_SLOTS_NV = 0x20CF, + ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV = 0x20D0, + ERROR_MISSING_AFFINITY_MASK_NV = 0x20D1, + WGL_NUM_VIDEO_SLOTS_NV = 0x20F0, + WGL_TYPE_RGBA_FLOAT_ARB = 0x21A0, + WGL_TYPE_RGBA_FLOAT_ATI = 0x21A0, + WGL_GPU_FASTEST_TARGET_GPUS_AMD = 0x21A2, + WGL_GPU_RAM_AMD = 0x21A3, + WGL_GPU_CLOCK_AMD = 0x21A4, + WGL_GPU_NUM_PIPES_AMD = 0x21A5, + WGL_TEXTURE_RECTANGLE_ATI = 0x21A5, + WGL_GPU_NUM_SIMD_AMD = 0x21A6, + WGL_GPU_NUM_RB_AMD = 0x21A7, + WGL_GPU_NUM_SPI_AMD = 0x21A8, + WGL_CONTEXT_OPENGL_NO_ERROR_ARB = 0x31B3, +} WGL; + +typedef enum EGL { + WGL_COLORSPACE_EXT = 0x309D, + WGL_COLORSPACE_SRGB_EXT = 0x3089, + WGL_COLORSPACE_LINEAR_EXT = 0x308A, +} EGL; diff --git a/src/DivaGL/gl_array_buffer.hpp b/src/DivaGL/gl_array_buffer.hpp new file mode 100644 index 0000000..9e0a57b --- /dev/null +++ b/src/DivaGL/gl_array_buffer.hpp @@ -0,0 +1,144 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "wrap.hpp" +#include "gl_state.hpp" + +struct GLArrayBuffer { +private: + GLuint buffer; + +public: + inline GLArrayBuffer() : buffer() { + + } + + inline ~GLArrayBuffer() { + + } + + inline void Bind(bool force = false) { + gl_state_bind_array_buffer(buffer, force); + } + + inline void Create(size_t size) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_array_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_ARRAY_BUFFER, (GLsizeiptr)size, + 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + else + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_DRAW); + } + + } + + inline void Create(size_t size, const void* data, bool dynamic = false) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_array_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_ARRAY_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + else + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + } + } + + inline void Destroy() { + if (buffer) { + glDeleteBuffers(1, &buffer); + buffer = 0; + } + } + + inline bool IsNull() { + return !buffer; + } + + inline void* MapMemory() { + if (!buffer) + return 0; + + void* data; + if (GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + gl_state_bind_array_buffer(buffer); + data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + return 0; + } + + inline bool NotNull() { + return !!buffer; + } + + inline void UnmapMemory() { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + } + + inline void WriteMemory(size_t offset, size_t size, const void* data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + gl_state_bind_array_buffer(buffer); + glBufferSubData(GL_ARRAY_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + template + inline void WriteMemory(T& data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, 0, sizeof(T), &data); + else { + gl_state_bind_array_buffer(buffer); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(T), &data); + } + } +}; diff --git a/src/DivaGL/gl_element_array_buffer.hpp b/src/DivaGL/gl_element_array_buffer.hpp new file mode 100644 index 0000000..6c3b054 --- /dev/null +++ b/src/DivaGL/gl_element_array_buffer.hpp @@ -0,0 +1,144 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "wrap.hpp" +#include "gl_state.hpp" + +struct GLElementArrayBuffer { +private: + GLuint buffer; + +public: + inline GLElementArrayBuffer() : buffer() { + + } + + inline ~GLElementArrayBuffer() { + + } + + inline void Bind(bool force = false) { + gl_state_bind_element_array_buffer(buffer, force); + } + + inline void Create(size_t size) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_element_array_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, + 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + else + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_DRAW); + } + + } + + inline void Create(size_t size, const void* data, bool dynamic = false) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_element_array_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + else + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + } + } + + inline void Destroy() { + if (buffer) { + glDeleteBuffers(1, &buffer); + buffer = 0; + } + } + + inline bool IsNull() { + return !buffer; + } + + inline void* MapMemory() { + if (!buffer) + return 0; + + void* data; + if (GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + gl_state_bind_element_array_buffer(buffer); + data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + gl_state_bind_element_array_buffer(0); + } + return 0; + } + + inline bool NotNull() { + return !!buffer; + } + + inline void UnmapMemory() { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); + gl_state_bind_element_array_buffer(0); + } + } + + inline void WriteMemory(size_t offset, size_t size, const void* data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + gl_state_bind_element_array_buffer(buffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + template + inline void WriteMemory(T& data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, 0, sizeof(T), &data); + else { + gl_state_bind_element_array_buffer(buffer); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(T), &data); + } + } +}; diff --git a/src/DivaGL/gl_shader_storage_buffer.hpp b/src/DivaGL/gl_shader_storage_buffer.hpp new file mode 100644 index 0000000..45de18f --- /dev/null +++ b/src/DivaGL/gl_shader_storage_buffer.hpp @@ -0,0 +1,144 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "wrap.hpp" +#include "gl_state.hpp" + +struct GLShaderStorageBuffer { +private: + GLuint buffer; + +public: + inline GLShaderStorageBuffer() : buffer() { + + } + + inline ~GLShaderStorageBuffer() { + + } + + inline void Bind(int32_t index, bool force = false) { + gl_state_bind_shader_storage_buffer_base(index, buffer, force); + } + + inline void Create(size_t size) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_shader_storage_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)size, + 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + else + glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_DRAW); + } + + } + + inline void Create(size_t size, const void* data, bool dynamic = false) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_shader_storage_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + else + glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + } + } + + inline void Destroy() { + if (buffer) { + glDeleteBuffers(1, &buffer); + buffer = 0; + } + } + + inline bool IsNull() { + return !buffer; + } + + inline void* MapMemory() { + if (!buffer) + return 0; + + void* data; + if (GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + gl_state_bind_shader_storage_buffer(buffer); + data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + gl_state_bind_shader_storage_buffer(0); + } + return 0; + } + + inline bool NotNull() { + return !!buffer; + } + + inline void UnmapMemory() { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + gl_state_bind_shader_storage_buffer(0); + } + } + + inline void WriteMemory(size_t offset, size_t size, const void* data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + gl_state_bind_shader_storage_buffer(buffer); + glBufferSubData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + template + inline void WriteMemory(T& data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, 0, sizeof(T), &data); + else { + gl_state_bind_shader_storage_buffer(buffer); + glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(T), &data); + } + } +}; diff --git a/src/DivaGL/gl_state.cpp b/src/DivaGL/gl_state.cpp new file mode 100644 index 0000000..a4b101c --- /dev/null +++ b/src/DivaGL/gl_state.cpp @@ -0,0 +1,489 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "gl_state.hpp" +#include "wrap.hpp" + +gl_state_struct gl_state; + +void gl_state_active_bind_texture_2d(int32_t index, GLuint texture, bool force) { + if (force || gl_state.texture_binding_2d[index] != texture) { + if (force || gl_state.active_texture_index != index) { + glActiveTexture((GLenum)(GL_TEXTURE0 + index)); + gl_state.active_texture = (GLenum)(GL_TEXTURE0 + index); + gl_state.active_texture_index = (GLuint)index; + } + glBindTextureDLL(GL_TEXTURE_2D, texture); + gl_state.texture_binding_2d[index] = texture; + } +} + +void gl_state_active_bind_texture_cube_map(int32_t index, GLuint texture, bool force) { + if (force || gl_state.texture_binding_cube_map[index] != texture) { + if (force || gl_state.active_texture_index != index) { + glActiveTexture((GLenum)(GL_TEXTURE0 + index)); + gl_state.active_texture = (GLenum)(GL_TEXTURE0 + index); + gl_state.active_texture_index = (GLuint)index; + } + glBindTextureDLL(GL_TEXTURE_CUBE_MAP, texture); + gl_state.texture_binding_cube_map[index] = texture; + } +} + +void gl_state_active_texture(size_t index, bool force) { + if (force || gl_state.active_texture_index != index) { + glActiveTexture((GLenum)(GL_TEXTURE0 + index)); + gl_state.active_texture = (GLenum)(GL_TEXTURE0 + index); + gl_state.active_texture_index = (GLuint)index; + } +} + +void gl_state_bind_framebuffer(GLuint framebuffer, bool force) { + if (force || gl_state.read_framebuffer_binding != framebuffer + || gl_state.draw_framebuffer_binding != framebuffer) { + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + gl_state.read_framebuffer_binding = framebuffer; + gl_state.draw_framebuffer_binding = framebuffer; + } +} + +void gl_state_bind_read_framebuffer(GLuint framebuffer, bool force) { + if (force || gl_state.read_framebuffer_binding != framebuffer) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer); + gl_state.read_framebuffer_binding = framebuffer; + } +} + +void gl_state_bind_draw_framebuffer(GLuint framebuffer, bool force) { + if (force || gl_state.draw_framebuffer_binding != framebuffer) { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); + gl_state.draw_framebuffer_binding = framebuffer; + } +} + +void gl_state_bind_vertex_array(GLuint array, bool force) { + if (force || gl_state.vertex_array_binding != array) { + glBindVertexArray(array); + gl_state.vertex_array_binding = array; + } +} + +void gl_state_bind_array_buffer(GLuint buffer, bool force) { + if (force || gl_state.array_buffer_binding != buffer) { + glBindBuffer(GL_ARRAY_BUFFER, buffer); + gl_state.array_buffer_binding = buffer; + } +} + +void gl_state_bind_element_array_buffer(GLuint buffer, bool force) { + if (force || gl_state.element_array_buffer_binding != buffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); + gl_state.element_array_buffer_binding = buffer; + } +} + +void gl_state_bind_uniform_buffer(GLuint buffer, bool force) { + if (force || gl_state.uniform_buffer_binding != buffer) { + glBindBuffer(GL_UNIFORM_BUFFER, buffer); + gl_state.uniform_buffer_binding = buffer; + } +} + +void gl_state_bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force) { + if (force || gl_state.uniform_buffer_bindings[index] != buffer) { + glBindBufferBase(GL_UNIFORM_BUFFER, index, buffer); + gl_state.uniform_buffer_bindings[index] = buffer; + gl_state.uniform_buffer_offsets[index] = 0; + gl_state.uniform_buffer_sizes[index] = -1; + } +} + +void gl_state_bind_uniform_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { + if (force || gl_state.uniform_buffer_bindings[index] != buffer + || gl_state.uniform_buffer_offsets[index] != offset + || gl_state.uniform_buffer_sizes[index] != size) { + glBindBufferRange(GL_UNIFORM_BUFFER, index, buffer, offset, size); + gl_state.uniform_buffer_bindings[index] = buffer; + gl_state.uniform_buffer_offsets[index] = offset; + gl_state.uniform_buffer_sizes[index] = size; + } +} + +void gl_state_bind_shader_storage_buffer(GLuint buffer, bool force) { + if (force || gl_state.shader_storage_buffer_binding != buffer) { + glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); + gl_state.shader_storage_buffer_binding = buffer; + } +} + +void gl_state_bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force) { + if (force || gl_state.shader_storage_buffer_bindings[index] != buffer) { + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer); + gl_state.shader_storage_buffer_bindings[index] = buffer; + gl_state.shader_storage_buffer_offsets[index] = 0; + gl_state.shader_storage_buffer_sizes[index] = -1; + } +} + +void gl_state_bind_shader_storage_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size, bool force) { + if (force || gl_state.shader_storage_buffer_bindings[index] != buffer + || gl_state.shader_storage_buffer_offsets[index] != offset + || gl_state.shader_storage_buffer_sizes[index] != size) { + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, index, buffer, offset, size); + gl_state.shader_storage_buffer_bindings[index] = buffer; + gl_state.shader_storage_buffer_offsets[index] = offset; + gl_state.shader_storage_buffer_sizes[index] = size; + } +} + +void gl_state_bind_texture_2d(GLuint texture, bool force) { + if (gl_state.texture_binding_2d[gl_state.active_texture_index] != texture) { + glBindTextureDLL(GL_TEXTURE_2D, texture); + gl_state.texture_binding_2d[gl_state.active_texture_index] = texture; + } +} + +void gl_state_bind_texture_cube_map(GLuint texture, bool force) { + if (force || gl_state.texture_binding_cube_map[gl_state.active_texture_index] != texture) { + glBindTextureDLL(GL_TEXTURE_CUBE_MAP, texture); + gl_state.texture_binding_cube_map[gl_state.active_texture_index] = texture; + } +} + +void gl_state_bind_sampler(int32_t index, GLuint sampler, bool force) { + if (force || gl_state.sampler_binding[index] != sampler) { + glBindSampler(index, sampler); + gl_state.sampler_binding[index] = sampler; + } +} + +bool gl_state_check_uniform_buffer_binding() { + return gl_state.uniform_buffer_binding != 0; +} + +bool gl_state_check_uniform_buffer_binding_base(size_t index) { + return gl_state.uniform_buffer_bindings[index] != 0; +} + +bool gl_state_check_texture_binding_2d(size_t index) { + return gl_state.texture_binding_2d[index] != 0; +} + +bool gl_state_check_shader_storage_buffer_binding() { + return gl_state.shader_storage_buffer_binding != 0; +} + +bool gl_state_check_shader_storage_buffer_binding_base(size_t index) { + return gl_state.shader_storage_buffer_bindings[index] != 0; +} + +bool gl_state_check_texture_binding_cube_map(size_t index) { + return gl_state.texture_binding_cube_map[index] != 0; +} + +bool gl_state_check_sampler_binding(int32_t index, GLuint sampler) { + return gl_state.sampler_binding[index] != 0; +} + +void gl_state_disable_blend(bool force) { + if (force || gl_state.blend) { + glDisableDLL(GL_BLEND); + gl_state.blend = GL_FALSE; + } +} + +void gl_state_disable_cull_face(bool force) { + if (force || gl_state.cull_face) { + glDisableDLL(GL_CULL_FACE); + gl_state.cull_face = GL_FALSE; + } +} + +void gl_state_disable_depth_test(bool force) { + if (force || gl_state.depth_test) { + glDisableDLL(GL_DEPTH_TEST); + gl_state.depth_test = GL_FALSE; + } +} + +void gl_state_disable_multisample(bool force) { + if (force || gl_state.multisample) { + glDisableDLL(GL_MULTISAMPLE); + gl_state.multisample = GL_FALSE; + } +} + +void gl_state_disable_primitive_restart(bool force) { + if (force || gl_state.primitive_restart) { + glDisableDLL(GL_PRIMITIVE_RESTART); + gl_state.primitive_restart = GL_FALSE; + } +} + +void gl_state_disable_scissor_test(bool force) { + if (force || gl_state.scissor_test) { + glDisableDLL(GL_SCISSOR_TEST); + gl_state.scissor_test = GL_FALSE; + } +} + +void gl_state_disable_stencil_test(bool force) { + if (force || gl_state.stencil_test) { + glDisableDLL(GL_STENCIL_TEST); + gl_state.stencil_test = GL_FALSE; + } +} + +void gl_state_enable_blend(bool force) { + if (force || !gl_state.blend) { + glEnableDLL(GL_BLEND); + gl_state.blend = GL_TRUE; + } +} + +void gl_state_enable_cull_face(bool force) { + if (force || !gl_state.cull_face) { + glEnableDLL(GL_CULL_FACE); + gl_state.cull_face = GL_TRUE; + } +} + +void gl_state_enable_depth_test(bool force) { + if (force || !gl_state.depth_test) { + glEnableDLL(GL_DEPTH_TEST); + gl_state.depth_test = GL_TRUE; + } +} + +void gl_state_enable_multisample(bool force) { + if (force || !gl_state.multisample) { + glEnableDLL(GL_MULTISAMPLE); + gl_state.multisample = GL_TRUE; + } +} + +void gl_state_enable_primitive_restart(bool force) { + if (force || !gl_state.primitive_restart) { + glEnableDLL(GL_PRIMITIVE_RESTART); + gl_state.primitive_restart = GL_TRUE; + } +} + +void gl_state_enable_scissor_test(bool force) { + if (force || !gl_state.scissor_test) { + glEnableDLL(GL_SCISSOR_TEST); + gl_state.scissor_test = GL_TRUE; + } +} + +void gl_state_enable_stencil_test(bool force) { + if (force || !gl_state.stencil_test) { + glEnableDLL(GL_STENCIL_TEST); + gl_state.stencil_test = GL_TRUE; + } +} + +void gl_state_get() { + glGetIntegervDLL(GL_CURRENT_PROGRAM, &gl_state.program); + glGetIntegervDLL(GL_ACTIVE_TEXTURE, (GLint*)&gl_state.active_texture); + gl_state.active_texture_index = gl_state.active_texture - GL_TEXTURE0; + for (GLuint i = 0; i < 32; i++) { + glActiveTexture((GLenum)(GL_TEXTURE0 + i)); + glGetIntegervDLL(GL_TEXTURE_BINDING_2D, &gl_state.texture_binding_2d[i]); + glGetIntegervDLL(GL_TEXTURE_BINDING_CUBE_MAP, &gl_state.texture_binding_cube_map[i]); + glGetIntegeri_v(GL_SAMPLER_BINDING, i, &gl_state.sampler_binding[i]); + } + glActiveTexture(gl_state.active_texture); + + glGetBooleanvDLL(GL_BLEND, &gl_state.blend); + glGetIntegervDLL(GL_BLEND_SRC_RGB, (GLint*)&gl_state.blend_src_rgb); + glGetIntegervDLL(GL_BLEND_SRC_ALPHA, (GLint*)&gl_state.blend_src_alpha); + glGetIntegervDLL(GL_BLEND_DST_RGB, (GLint*)&gl_state.blend_dst_rgb); + glGetIntegervDLL(GL_BLEND_DST_ALPHA, (GLint*)&gl_state.blend_dst_alpha); + glGetIntegervDLL(GL_BLEND_EQUATION_RGB, (GLint*)&gl_state.blend_mode_rgb); + glGetIntegervDLL(GL_BLEND_EQUATION_ALPHA, (GLint*)&gl_state.blend_mode_alpha); + + glGetIntegervDLL(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&gl_state.read_framebuffer_binding); + glGetIntegervDLL(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&gl_state.draw_framebuffer_binding); + glGetIntegervDLL(GL_VERTEX_ARRAY_BINDING, (GLint*)&gl_state.vertex_array_binding); + glGetIntegervDLL(GL_ARRAY_BUFFER_BINDING, (GLint*)&gl_state.array_buffer_binding); + glGetIntegervDLL(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&gl_state.element_array_buffer_binding); + + glGetIntegervDLL(GL_UNIFORM_BUFFER_BINDING, (GLint*)&gl_state.uniform_buffer_binding); + for (GLuint i = 0; i < 14; i++) { + glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, i, (GLint*)&gl_state.uniform_buffer_bindings[i]); + glGetIntegeri_v(GL_UNIFORM_BUFFER_START, i, (GLint*)&gl_state.uniform_buffer_offsets[i]); + glGetIntegeri_v(GL_UNIFORM_BUFFER_SIZE, i, (GLint*)&gl_state.uniform_buffer_sizes[i]); + } + + glGetIntegervDLL(GL_SHADER_STORAGE_BUFFER_BINDING, (GLint*)&gl_state.shader_storage_buffer_binding); + for (GLuint i = 0; i < 14; i++) { + glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, i, (GLint*)&gl_state.shader_storage_buffer_bindings[i]); + glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_START, i, (GLint*)&gl_state.shader_storage_buffer_offsets[i]); + glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_SIZE, i, (GLint*)&gl_state.shader_storage_buffer_sizes[i]); + } + + glGetBooleanvDLL(GL_COLOR_WRITEMASK, gl_state.color_mask); + glGetBooleanvDLL(GL_CULL_FACE, &gl_state.cull_face); + glGetIntegervDLL(GL_CULL_FACE_MODE, (GLint*)&gl_state.cull_face_mode); + glGetBooleanvDLL(GL_DEPTH_TEST, &gl_state.depth_test); + glGetIntegervDLL(GL_DEPTH_FUNC, (GLint*)&gl_state.depth_func); + glGetBooleanvDLL(GL_DEPTH_WRITEMASK, &gl_state.depth_mask); + glGetBooleanvDLL(GL_MULTISAMPLE, &gl_state.multisample); + glGetBooleanvDLL(GL_PRIMITIVE_RESTART, &gl_state.primitive_restart); + glGetIntegervDLL(GL_PRIMITIVE_RESTART_INDEX, (GLint*)&gl_state.primitive_restart_index); + glGetBooleanvDLL(GL_SCISSOR_TEST, &gl_state.scissor_test); + glGetBooleanvDLL(GL_STENCIL_TEST, &gl_state.stencil_test); + glGetIntegervDLL(GL_STENCIL_WRITEMASK, (GLint*)&gl_state.stencil_mask); + + glPolygonModeDLL(GL_FRONT_AND_BACK, GL_FILL); + gl_state.polygon_front_face_mode = GL_FILL; + gl_state.polygon_back_face_mode = GL_FILL; +} + +void gl_state_get_all_gl_errors() { + GLenum error; + while (error = glGetErrorDLL()) + printf_debug("GL Error: 0x%04X\n", error); +} + +GLenum gl_state_get_error() { + GLenum error = glGetErrorDLL(); + if (error) + printf_debug("GL Error: 0x%04X\n", error); + return error; +} + +GLuint gl_state_get_program() { + return gl_state.program; +} + +void gl_state_set_blend_func(GLenum src, GLenum dst, bool force) { + if (force || gl_state.blend_src_rgb != src || gl_state.blend_dst_rgb != dst + || gl_state.blend_src_alpha != GL_ONE || gl_state.blend_dst_alpha != GL_ONE_MINUS_SRC_ALPHA) { + glBlendFuncSeparate(src, dst, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + gl_state.blend_src_rgb = src; + gl_state.blend_dst_rgb = dst; + gl_state.blend_src_alpha = GL_ONE; + gl_state.blend_dst_alpha = GL_ONE_MINUS_SRC_ALPHA; + } +} + +void gl_state_set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, + GLenum src_alpha, GLenum dst_alpha, bool force) { + if (force || gl_state.blend_src_rgb != src_rgb || gl_state.blend_dst_rgb != dst_rgb + || gl_state.blend_src_alpha != src_alpha || gl_state.blend_dst_alpha != dst_alpha) { + glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha); + gl_state.blend_src_rgb = src_rgb; + gl_state.blend_dst_rgb = dst_rgb; + gl_state.blend_src_alpha = src_alpha; + gl_state.blend_dst_alpha = dst_alpha; + } +} + +void gl_state_set_blend_equation(GLenum mode, bool force) { + if (force || gl_state.blend_mode_rgb != mode || gl_state.blend_mode_alpha != mode) { + glBlendEquationSeparate(mode, mode); + gl_state.blend_mode_rgb = mode; + gl_state.blend_mode_alpha = mode; + } +} + +void gl_state_set_blend_equation_separate(GLenum mode_rgb, GLenum mode_alpha, bool force) { + if (force || gl_state.blend_mode_rgb != mode_rgb || gl_state.blend_mode_alpha != mode_alpha) { + glBlendEquationSeparate(mode_rgb, mode_alpha); + gl_state.blend_mode_rgb = mode_rgb; + gl_state.blend_mode_alpha = mode_alpha; + } +} + +void gl_state_set_color_mask(GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha, bool force) { + if (force || gl_state.color_mask[0] != red || gl_state.color_mask[1] != green + || gl_state.color_mask[2] != blue || gl_state.color_mask[3] != alpha) { + glColorMaskDLL(red, green, blue, alpha); + gl_state.color_mask[0] = red; + gl_state.color_mask[1] = green; + gl_state.color_mask[2] = blue; + gl_state.color_mask[3] = alpha; + } +} + +void gl_state_set_cull_face_mode(GLenum mode, bool force) { + if (force || gl_state.cull_face_mode != mode) { + glCullFaceDLL(mode); + gl_state.cull_face_mode = mode; + } +} + +void gl_state_set_depth_func(GLenum func, bool force) { + if (force || gl_state.depth_func != func) { + glDepthFuncDLL(func); + gl_state.depth_func = func; + } +} + +void gl_state_set_depth_mask(GLboolean flag, bool force) { + if (force || gl_state.depth_mask != flag) { + glDepthMaskDLL(flag); + gl_state.depth_mask = flag; + } +} + +void gl_state_set_polygon_mode(GLenum face, GLenum mode, bool force) { + switch (face) { + case GL_FRONT: + if (force || gl_state.polygon_front_face_mode != mode) { + glPolygonModeDLL(GL_FRONT, mode); + gl_state.polygon_front_face_mode = mode; + } + break; + case GL_BACK: + if (force || gl_state.polygon_back_face_mode != mode) { + glPolygonModeDLL(GL_BACK, mode); + gl_state.polygon_back_face_mode = mode; + } + break; + case GL_FRONT_AND_BACK: + if (force || gl_state.polygon_front_face_mode != mode + && gl_state.polygon_back_face_mode != mode) { + glPolygonModeDLL(GL_FRONT_AND_BACK, mode); + gl_state.polygon_front_face_mode = mode; + gl_state.polygon_back_face_mode = mode; + } + else if (gl_state.polygon_front_face_mode != mode) { + glPolygonModeDLL(GL_FRONT, mode); + gl_state.polygon_front_face_mode = mode; + } + else if (gl_state.polygon_back_face_mode != mode) { + glPolygonModeDLL(GL_BACK, mode); + gl_state.polygon_back_face_mode = mode; + } + break; + } +} + +void gl_state_set_primitive_restart_index(GLuint index, bool force) { + if (force || gl_state.primitive_restart_index != index) { + glPrimitiveRestartIndex(index); + gl_state.primitive_restart_index = index; + } +} + +void gl_state_set_stencil_mask(GLuint mask, bool force) { + if (force || gl_state.stencil_mask != mask) { + glStencilMask(mask); + gl_state.stencil_mask = mask; + } +} + +void gl_state_use_program(GLuint program, bool force) { + if (force || gl_state.program != program) { + glUseProgram(program); + gl_state.program = program; + } +} diff --git a/src/DivaGL/gl_state.hpp b/src/DivaGL/gl_state.hpp new file mode 100644 index 0000000..94cf942 --- /dev/null +++ b/src/DivaGL/gl_state.hpp @@ -0,0 +1,127 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "wrap.hpp" + +struct gl_state_struct { + GLint program; + GLenum active_texture; + GLuint active_texture_index; + GLint texture_binding_2d[32]; + GLint texture_binding_cube_map[32]; + GLint sampler_binding[32]; + GLboolean blend; + GLenum blend_src_rgb; + GLenum blend_src_alpha; + GLenum blend_dst_rgb; + GLenum blend_dst_alpha; + GLenum blend_mode_rgb; + GLenum blend_mode_alpha; + GLuint read_framebuffer_binding; + GLuint draw_framebuffer_binding; + GLuint vertex_array_binding; + GLuint array_buffer_binding; + GLuint element_array_buffer_binding; + GLuint uniform_buffer_binding; + GLuint uniform_buffer_bindings[14]; + GLintptr uniform_buffer_offsets[14]; + GLsizeiptr uniform_buffer_sizes[14]; + GLuint shader_storage_buffer_binding; + GLuint shader_storage_buffer_bindings[14]; + GLintptr shader_storage_buffer_offsets[14]; + GLsizeiptr shader_storage_buffer_sizes[14]; + GLboolean color_mask[4]; + GLboolean cull_face; + GLenum cull_face_mode; + GLboolean depth_test; + GLenum depth_func; + GLboolean depth_mask; + GLenum polygon_front_face_mode; + GLenum polygon_back_face_mode; + GLboolean multisample; + GLboolean primitive_restart; + GLuint primitive_restart_index; + GLboolean scissor_test; + GLboolean stencil_test; + GLuint stencil_mask; +}; + +extern gl_state_struct gl_state; + +extern void gl_state_active_bind_texture_2d(int32_t index, GLuint texture, bool force = false); +extern void gl_state_active_bind_texture_cube_map(int32_t index, GLuint texture, bool force = false); +extern void gl_state_active_texture(size_t index, bool force = false); +extern void gl_state_bind_framebuffer(GLuint framebuffer, bool force = false); +extern void gl_state_bind_read_framebuffer(GLuint framebuffer, bool force = false); +extern void gl_state_bind_draw_framebuffer(GLuint framebuffer, bool force = false); +extern void gl_state_bind_vertex_array(GLuint array, bool force = false); +extern void gl_state_bind_array_buffer(GLuint buffer, bool force = false); +extern void gl_state_bind_element_array_buffer(GLuint buffer, bool force = false); +extern void gl_state_bind_uniform_buffer(GLuint buffer, bool force = false); +extern void gl_state_bind_uniform_buffer_base(GLuint index, GLuint buffer, bool force = false); +extern void gl_state_bind_uniform_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); +extern void gl_state_bind_shader_storage_buffer(GLuint buffer, bool force = false); +extern void gl_state_bind_shader_storage_buffer_base(GLuint index, GLuint buffer, bool force = false); +extern void gl_state_bind_shader_storage_buffer_range(GLuint index, + GLuint buffer, GLintptr offset, GLsizeiptr size, bool force = false); +extern void gl_state_bind_texture_2d(GLuint texture, bool force = false); +extern void gl_state_bind_texture_cube_map(GLuint texture, bool force = false); +extern void gl_state_bind_sampler(int32_t index, GLuint sampler, bool force = false); +extern bool gl_state_check_uniform_buffer_binding(); +extern bool gl_state_check_uniform_buffer_binding_base(size_t index); +extern bool gl_state_check_shader_storage_buffer_binding(); +extern bool gl_state_check_shader_storage_buffer_binding_base(size_t index); +extern bool gl_state_check_texture_binding_2d(size_t index); +extern bool gl_state_check_texture_binding_cube_map(size_t index); +extern bool gl_state_check_sampler_binding(int32_t index, GLuint sampler); +extern void gl_state_disable_blend(bool force = false); +extern void gl_state_disable_cull_face(bool force = false); +extern void gl_state_disable_depth_test(bool force = false); +extern void gl_state_disable_multisample(bool force = false); +extern void gl_state_disable_primitive_restart(bool force = false); +extern void gl_state_disable_scissor_test(bool force = false); +extern void gl_state_disable_stencil_test(bool force = false); +extern void gl_state_enable_blend(bool force = false); +extern void gl_state_enable_cull_face(bool force = false); +extern void gl_state_enable_depth_test(bool force = false); +extern void gl_state_enable_multisample(bool force = false); +extern void gl_state_enable_primitive_restart(bool force = false); +extern void gl_state_enable_scissor_test(bool force = false); +extern void gl_state_enable_stencil_test(bool force = false); +extern void gl_state_get(); +extern void gl_state_get_all_gl_errors(); +extern GLenum gl_state_get_error(); +extern GLuint gl_state_get_program(); +extern void gl_state_set_blend_func(GLenum src, GLenum dst, bool force = false); +extern void gl_state_set_blend_func_separate(GLenum src_rgb, GLenum dst_rgb, + GLenum src_alpha, GLenum dst_alpha, bool force = false); +extern void gl_state_set_blend_equation(GLenum mode, bool force = false); +extern void gl_state_set_blend_equation_separate( + GLenum mode_rgb, GLenum mode_alpha, bool force = false); +extern void gl_state_set_color_mask(GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha, bool force = false); +extern void gl_state_set_cull_face_mode(GLenum mode, bool force = false); +extern void gl_state_set_depth_func(GLenum func, bool force = false); +extern void gl_state_set_depth_mask(GLboolean flag, bool force = false); +extern void gl_state_set_polygon_mode(GLenum face, GLenum mode, bool force = false); +extern void gl_state_set_primitive_restart_index(GLuint index, bool force = false); +extern void gl_state_set_stencil_mask(GLuint mask, bool force = false); +extern void gl_state_use_program(GLuint program, bool force = false); + +inline constexpr void gl_state_begin_event(const char* str) { +#ifdef DEBUG + glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)utf8_length(str), str); +#endif +} + +inline constexpr void gl_state_end_event() { +#ifdef DEBUG + glPopDebugGroup(); +#endif +} diff --git a/src/DivaGL/gl_uniform_buffer.hpp b/src/DivaGL/gl_uniform_buffer.hpp new file mode 100644 index 0000000..18fa1aa --- /dev/null +++ b/src/DivaGL/gl_uniform_buffer.hpp @@ -0,0 +1,144 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "wrap.hpp" +#include "gl_state.hpp" + +struct GLUniformBuffer { +private: + GLuint buffer; + +public: + inline GLUniformBuffer() : buffer() { + + } + + inline ~GLUniformBuffer() { + + } + + inline void Bind(int32_t index, bool force = false) { + gl_state_bind_uniform_buffer_base(index, buffer, force); + } + + inline void Create(size_t size) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_uniform_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_UNIFORM_BUFFER, (GLsizeiptr)size, + 0, GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT); + else + glBufferData(GL_UNIFORM_BUFFER, (GLsizeiptr)size, 0, GL_DYNAMIC_DRAW); + } + + } + + inline void Create(size_t size, const void* data, bool dynamic = false) { + if (buffer) + return; + + if (GL_VERSION_4_5) { + glCreateBuffers(1, &buffer); + glNamedBufferStorage(buffer, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + } + else { + glGenBuffers(1, &buffer); + gl_state_bind_uniform_buffer(buffer); + if (GL_VERSION_4_4) + glBufferStorage(GL_UNIFORM_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT : 0); + else + glBufferData(GL_UNIFORM_BUFFER, (GLsizeiptr)size, data, + dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + } + } + + inline void Destroy() { + if (buffer) { + glDeleteBuffers(1, &buffer); + buffer = 0; + } + } + + inline bool IsNull() { + return !buffer; + } + + inline void* MapMemory() { + if (!buffer) + return 0; + + void* data; + if (GL_VERSION_4_5) + data = glMapNamedBuffer(buffer, GL_WRITE_ONLY); + else { + gl_state_bind_uniform_buffer(buffer); + data = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); + } + + if (data) + return data; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_UNIFORM_BUFFER); + gl_state_bind_uniform_buffer(0); + } + return 0; + } + + inline bool NotNull() { + return !!buffer; + } + + inline void UnmapMemory() { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_UNIFORM_BUFFER); + gl_state_bind_uniform_buffer(0); + } + } + + inline void WriteMemory(size_t offset, size_t size, const void* data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, (GLsizeiptr)offset, (GLsizeiptr)size, data); + else { + gl_state_bind_uniform_buffer(buffer); + glBufferSubData(GL_UNIFORM_BUFFER, (GLsizeiptr)offset, (GLsizeiptr)size, data); + } + } + + template + inline void WriteMemory(T& data) { + if (!buffer) + return; + + if (GL_VERSION_4_5) + glNamedBufferSubData(buffer, 0, sizeof(T), &data); + else { + gl_state_bind_uniform_buffer(buffer); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(T), &data); + } + } +}; diff --git a/src/DivaGL/hook.cpp b/src/DivaGL/hook.cpp new file mode 100644 index 0000000..8356551 --- /dev/null +++ b/src/DivaGL/hook.cpp @@ -0,0 +1,117 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "hook.hpp" +#include "Glitter/glitter.hpp" +#include "mdl/disp_manager.hpp" +#include "rob/rob.hpp" +#include "auth_3d.hpp" +#include "camera.hpp" +#include "shader_glsl_ft.hpp" +#include "sprite.hpp" +#include "stage.hpp" +#include "texture.hpp" +#include + +HOOK(int32_t, FASTCALL, data_init, 0x0000000140192FF0) { + extern void FASTCALL wrap_addresses(); + wrap_addresses(); + + auth_3d_patch(); + camera_patch(); + mdl::disp_manager_patch(); + render_manager_patch(); + rob_patch(); + sprite_patch(); + stage_patch(); + Glitter::Patch(); + + rctx = new render_context; + int32_t ret = originaldata_init(); + + extern size_t diva_handle; + diva_handle = (size_t)WindowFromDC(wglGetCurrentDC()); + + rctx->init(); + sprite_manager_init(); + return ret; +} + +HOOK(int32_t, FASTCALL, data_free, 0x000000140192490) { + sprite_manager_free(); + rctx->free(); + + int32_t ret = originaldata_free(); + delete rctx; + return ret; +} + +HOOK(void, FASTCALL, sub_140194CD0, 0x000000140194CD0) { + rctx->ctrl(); + originalsub_140194CD0(); +} + +HOOK(void, FASTCALL, _gl_state_get, 0x0000000140442DF0) { + gl_state_get(); +} + +HOOK(void, FASTCALL, rndr__Render__update_res, 0x00000001404A9480, rndr::Render* rend, bool set, int32_t base_downsample) { + rend->update_res(set, base_downsample); +} + +HOOK(void, FASTCALL, rndr__Render__init_tone_map_buffers, 0x00000001404A9FF0, rndr::Render* rend) { + rend->init_tone_map_buffers(); +} + +HOOK(void, FASTCALL, rndr__Render__init_render_buffers, 0x00000001404AB0C0, rndr::Render* rend, + int32_t width, int32_t height, int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask) { + rend->init_render_buffers(width, height, ssaa, hd_res, ss_alpha_mask); +} + +HOOK(void, FASTCALL, rndr__Render__free, 0x00000001404AB900, rndr::Render* rend) { + rend->free(); +} + +HOOK(void, FASTCALL, rndr__RenderManager__render_ctrl, 0x0000000140502C90) { + render_manager->render->ctrl(); +} + +HOOK(void, FASTCALL, rndr__RenderManager__render_all, 0x0000000140502CA0) { + render_manager->render_all(); +} + +HOOK(int32_t, FASTCALL, shader_get_index_by_name, 0x00000001405E4ED0, const char* name) { + return shaders_ft.get_index_by_name(name); +} + +HOOK(void, FASTCALL, env_set_blend_color, 0x00000001405E5600, float_t r, float_t g, float_t b, float_t a) { + rctx->obj_batch.g_blend_color = { r, g, b, a }; +} + +HOOK(void, FASTCALL, env_set_offset_color, 0x00000001405E5630, float_t r, float_t g, float_t b, float_t a) { + rctx->obj_batch.g_offset_color = { r, g, b, a }; +} + +void hook_funcs() { + INSTALL_HOOK(data_init); + INSTALL_HOOK(data_free); + + INSTALL_HOOK(sub_140194CD0); + + INSTALL_HOOK(_gl_state_get); + + INSTALL_HOOK(rndr__Render__update_res); + INSTALL_HOOK(rndr__Render__init_tone_map_buffers); + INSTALL_HOOK(rndr__Render__init_render_buffers); + INSTALL_HOOK(rndr__Render__free); + + INSTALL_HOOK(rndr__RenderManager__render_ctrl); + INSTALL_HOOK(rndr__RenderManager__render_all); + + INSTALL_HOOK(shader_get_index_by_name); + + INSTALL_HOOK(env_set_blend_color); + INSTALL_HOOK(env_set_offset_color); +} \ No newline at end of file diff --git a/src/DivaGL/hook.hpp b/src/DivaGL/hook.hpp new file mode 100644 index 0000000..a0e81fd --- /dev/null +++ b/src/DivaGL/hook.hpp @@ -0,0 +1,10 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "gl_state.hpp" + +extern void hook_funcs(); diff --git a/src/DivaGL/inject.cpp b/src/DivaGL/inject.cpp new file mode 100644 index 0000000..fc73d07 --- /dev/null +++ b/src/DivaGL/inject.cpp @@ -0,0 +1,126 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "inject.hpp" +#include "gl.hpp" +#include "print.hpp" +#include "shader_table.hpp" +#include "shader_glsl_ft.hpp" +#include "sprite.hpp" +#include + +struct patch_struct { + void* address; + size_t func_ptr; +}; + +void inject_data(void* address, const void* data, size_t count) { + DWORD old_protect; + VirtualProtect(address, count, PAGE_EXECUTE_READWRITE, &old_protect); + memmove(address, (const void*)data, count); + VirtualProtect(address, count, old_protect, &old_protect); +} + +void inject_uint8_t(void* address, uint8_t data) { + DWORD old_protect; + VirtualProtect(address, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &old_protect); + *(uint8_t*)address = data; + VirtualProtect(address, sizeof(uint8_t), old_protect, &old_protect); +} + +void inject_uint16_t(void* address, uint16_t data) { + DWORD old_protect; + VirtualProtect(address, sizeof(uint16_t), PAGE_EXECUTE_READWRITE, &old_protect); + *(uint16_t*)address = data; + VirtualProtect(address, sizeof(uint16_t), old_protect, &old_protect); +} + +void inject_uint32_t(void* address, uint32_t data) { + DWORD old_protect; + VirtualProtect(address, sizeof(uint32_t), PAGE_EXECUTE_READWRITE, &old_protect); + *(uint32_t*)address = data; + VirtualProtect(address, sizeof(uint32_t), old_protect, &old_protect); +} + +void inject_uint64_t(void* address, uint64_t data) { + DWORD old_protect; + VirtualProtect(address, sizeof(uint64_t), PAGE_EXECUTE_READWRITE, &old_protect); + *(uint64_t*)address = data; + VirtualProtect(address, sizeof(uint64_t), old_protect, &old_protect); +} + +extern size_t glut_handle; + +static patch_struct patch_data[] = { + { (void*)0x00000001405E4CE0, (uint64_t)&shader_set, }, + { (void*)0x00000001405E4FC0, (uint64_t)&shader_load_all_shaders, }, + { (void*)0x00000001405E4DB0, (uint64_t)&shader_free, }, + { (void*)0x00000001405E4B50, (uint64_t)&shader_bind, }, + { (void*)0x00000001401D3860, (uint64_t)&printf_proxy, }, + { (void*)0x00000001400DE640, (uint64_t)&printf_proxy, }, + { (void*)0x0000000140442FB4, (uint64_t)&gl_state_get, }, +}; + +static HGLRC FASTCALL glut_create_context(int64_t a1, int64_t a2, int64_t a3, int64_t a4, int32_t a5); + +void inject_patches() { + // Reorder gl_state_get end + inject_data((void*)0x0000000140442F99, + "\xFF\x15\x51\x2B\x52\x00\x48\x8B\x5C\x24\x30\x48\x8B\x74\x24\x38" + "\x48\x8B\x7C\x24\x40\x48\x83\xC4\x20\x41\x5E\xC3", 28); + + uint8_t buf[0x0C]; + buf[0x00] = 0x48; + buf[0x01] = 0xB8; + buf[0x0A] = 0xFF; + buf[0x0B] = 0xE0; + + for (int32_t i = 0; i < sizeof(patch_data) / sizeof(patch_struct); i++) + if (patch_data[i].func_ptr) { + *(uint64_t*)&buf[0x02] = patch_data[i].func_ptr; + inject_data(patch_data[i].address, buf, 0x0C); + } + ; + + *(uint64_t*)&buf[0x02] = (uint64_t)&glut_create_context; + inject_data((void*)(glut_handle + 0x0000A970), buf, 0x0C); + + inject_uint64_t((void*)&shader_name_bind_func_table[0].bind_func, (uint64_t)&shader_bind_blinn); + inject_uint64_t((void*)&shader_name_bind_func_table[1].bind_func, (uint64_t)&shader_bind_cloth); + inject_uint64_t((void*)&shader_name_bind_func_table[2].bind_func, (uint64_t)&shader_bind_hair); + inject_uint64_t((void*)&shader_name_bind_func_table[3].bind_func, (uint64_t)&shader_bind_membrane); + inject_uint64_t((void*)&shader_name_bind_func_table[4].bind_func, (uint64_t)&shader_bind_eye_ball); + inject_uint64_t((void*)&shader_name_bind_func_table[5].bind_func, (uint64_t)&shader_bind_tone_map); + + // Patch font shader index + inject_uint32_t((void*)0x00000001401982D8, SHADER_FT_FONT); +} + +static HGLRC FASTCALL glut_create_context(int64_t a1, int64_t a2, int64_t a3, int64_t a4, int32_t a5) { + HDC& hDc = *(HDC*)(glut_handle + 0x55F20); + + if (true/*a5*/) { + const int32_t attrib_list[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 3, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, + 0, + }; + + typedef HGLRC(GLAPIENTRY* PFNWGLCREATECONTEXTGLUTPROC)(HDC hDc); + + HGLRC tmp_ctx = wglCreateContextGLUT(hDc);; + wglMakeCurrentGLUT(hDc, tmp_ctx); + PFNWGLCREATECONTEXTATTRIBSARBPROC _wglCreateContextAttribsARB + = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddressGLUT("wglCreateContextAttribsARB"); + HGLRC ctx = _wglCreateContextAttribsARB(hDc, 0, attrib_list); + wglMakeCurrentGLUT(hDc, ctx); + wglDeleteContextGLUT(tmp_ctx); + return ctx; + } + else + return wglCreateContextGLUT(hDc); +} diff --git a/src/DivaGL/inject.hpp b/src/DivaGL/inject.hpp new file mode 100644 index 0000000..fc0d0cb --- /dev/null +++ b/src/DivaGL/inject.hpp @@ -0,0 +1,15 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" + +extern void inject_data(void* address, const void* data, size_t count); +extern void inject_uint8_t(void* address, uint8_t data); +extern void inject_uint16_t(void* address, uint16_t data); +extern void inject_uint32_t(void* address, uint32_t data); +extern void inject_uint64_t(void* address, uint64_t data); +extern void inject_patches(); diff --git a/src/DivaGL/light_param/fog.cpp b/src/DivaGL/light_param/fog.cpp new file mode 100644 index 0000000..9fe3b8d --- /dev/null +++ b/src/DivaGL/light_param/fog.cpp @@ -0,0 +1,95 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "fog.hpp" +#include "../render_context.hpp" + +fog* fog_data = (fog*)0x00000001411974D0; + +fog_type fog::get_type() const { + return type; +} + +void fog::set_type(fog_type value) { + type = value; +} + +float_t fog::get_density() const { + return density; +} + +void fog::set_density(float_t value) { + density = value; +} + +float_t fog::get_start() const { + return start; +} + +void fog::set_start(float_t value) { + start = value; +} + +float_t fog::get_end() const { + return end; +} + +void fog::set_end(float_t value) { + end = value; +} + +int32_t fog::get_index() const { + return index; +} + +void fog::set_index(int32_t value) { + index = value; +} + +void fog::get_color(vec4& value) const { + value = color; +} + +void fog::set_color(const vec4& value) { + color = value; +} + +void fog::set_color(const vec4&& value) { + color = value; +} + +void fog::data_set(fog_id id) { + fog_type type = get_type(); + if (type == FOG_NONE) + return; + + float_t density = get_density(); + float_t start = get_start(); + float_t end = get_end(); + if (start >= end) + start = end - 0.01f; + + vec4 params; + params.x = density; + params.y = start; + params.z = end; + params.w = 1.0f / (end - start); + + extern render_context* rctx; + + switch (id) { + case FOG_DEPTH: + get_color(rctx->obj_scene.g_fog_depth_color); + rctx->obj_scene.g_fog_state_params = params; + break; + case FOG_HEIGHT: + get_color(rctx->obj_scene.g_fog_height_color); + rctx->obj_scene.g_fog_height_params = params; + break; + case FOG_BUMP: + rctx->obj_scene.g_fog_bump_params = params; + break; + } +} diff --git a/src/DivaGL/light_param/fog.hpp b/src/DivaGL/light_param/fog.hpp new file mode 100644 index 0000000..f40d80a --- /dev/null +++ b/src/DivaGL/light_param/fog.hpp @@ -0,0 +1,38 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/light_param/fog.hpp" +#include "../../KKdLib/vec.hpp" + +struct fog { + fog_type type; + float_t density; + float_t start; + float_t end; + int32_t index; + vec4 color; + + fog_type get_type() const; + void set_type(fog_type value); + float_t get_density() const; + void set_density(float_t value); + float_t get_start() const; + void set_start(float_t value); + float_t get_end() const; + void set_end(float_t value); + int32_t get_index() const; + void set_index(int32_t value); + void get_color(vec4& value) const; + void set_color(const vec4& value); + void set_color(const vec4&& value); + void data_set(fog_id id); +}; + +static_assert(sizeof(fog) == 0x24, "\"fog\" struct should have a size of 0x24"); + +extern fog* fog_data; diff --git a/src/DivaGL/light_param/light.cpp b/src/DivaGL/light_param/light.cpp new file mode 100644 index 0000000..1160384 --- /dev/null +++ b/src/DivaGL/light_param/light.cpp @@ -0,0 +1,497 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "light.hpp" +#include "../../KKdLib/mat.hpp" +#include "../render_context.hpp" +#include "../uniform.hpp" + +light_set* light_set_data = (light_set*)0x00000001411A00A0; + +static vec4* npr_cloth_spec_color = (vec4*)0x0000000140C9B2A0; + +static void light_get_direction_from_position(vec4* pos_dir, light_data* light, bool force = false); + +light_type light_data::get_type() const { + return type; +} + +void light_data::set_type(light_type value) { + type = value; + if (value < LIGHT_POINT) + position.w = 0.0f; + else + position.w = 1.0f; +} + +void light_data::get_ambient(vec4& value) const { + value = ambient; +} + +void light_data::set_ambient(const vec4& value) { + ambient = value; +} + +void light_data::set_ambient(const vec4&& value) { + ambient = value; +} + +void light_data::set_ambient(const vec4& value, bool set[4]) { + if (set[0]) + ambient.x = value.x; + if (set[1]) + ambient.y = value.y; + if (set[2]) + ambient.z = value.z; + if (set[3]) + ambient.w = value.w; +} + +void light_data::set_ambient(const vec4&& value, bool set[4]) { + if (set[0]) + ambient.x = value.x; + if (set[1]) + ambient.y = value.y; + if (set[2]) + ambient.z = value.z; + if (set[3]) + ambient.w = value.w; +} + +void light_data::get_diffuse(vec4& value) const { + value = diffuse; +} + +void light_data::set_diffuse(const vec4& value) { + diffuse = value; +} + +void light_data::set_diffuse(const vec4&& value) { + diffuse = value; +} + +void light_data::set_diffuse(const vec4& value, bool set[4]) { + if (set[0]) + diffuse.x = value.x; + if (set[1]) + diffuse.y = value.y; + if (set[2]) + diffuse.z = value.z; + if (set[3]) + diffuse.w = value.w; +} + +void light_data::set_diffuse(const vec4&& value, bool set[4]) { + if (set[0]) + diffuse.x = value.x; + if (set[1]) + diffuse.y = value.y; + if (set[2]) + diffuse.z = value.z; + if (set[3]) + diffuse.w = value.w; +} + +void light_data::get_specular(vec4& value) const { + value = specular; +} + +void light_data::set_specular(const vec4& value) { + specular = value; +} + +void light_data::set_specular(const vec4&& value) { + specular = value; +} + +void light_data::set_specular(const vec4& value, bool set[4]) { + if (set[0]) + specular.x = value.x; + if (set[1]) + specular.y = value.y; + if (set[2]) + specular.z = value.z; + if (set[3]) + specular.w = value.w; +} + +void light_data::set_specular(const vec4&& value, bool set[4]) { + if (set[0]) + specular.x = value.x; + if (set[1]) + specular.y = value.y; + if (set[2]) + specular.z = value.z; + if (set[3]) + specular.w = value.w; +} + +void light_data::get_position(vec3& value) const { + value = *(vec3*)&position; +} + +void light_data::set_position(const vec3& value) { + *(vec3*)&position = value; +} + +void light_data::set_position(const vec3&& value) { + *(vec3*)&position = value; +} + +void light_data::get_position(vec4& value) const { + value = position; +} + +void light_data::set_position(const vec4& value) { + position = value; +} + +void light_data::set_position(const vec4&& value) { + position = value; +} + +void light_data::get_spot_direction(vec3& value) const { + value = spot_direction; +} + +void light_data::set_spot_direction(const vec3& value) { + spot_direction = value; +} + +void light_data::set_spot_direction(const vec3&& value) { + spot_direction = value; +} + +float_t light_data::get_spot_exponent() const { + return spot_exponent; +} + +void light_data::set_spot_exponent(float_t value) { + spot_exponent = value; +} + +float_t light_data::get_spot_cutoff() const { + return spot_cutoff; +} + +void light_data::set_spot_cutoff(float_t value) { + spot_cutoff = value; +} + +float_t light_data::get_constant() const { + return attenuation.constant; +} + +void light_data::set_constant(float_t value) { + attenuation.constant = value; +} + +float_t light_data::get_linear() const { + return attenuation.linear; +} + +void light_data::set_linear(float_t value) { + attenuation.linear = value; +} + +float_t light_data::get_quadratic() const { + return attenuation.quadratic; +} + +void light_data::set_quadratic(float_t value) { + attenuation.quadratic = value; +} + +void light_data::get_attenuation(light_attenuation& value) const { + value = attenuation; +} + +void light_data::set_attenuation(const light_attenuation& value) { + attenuation = value; +} + +void light_data::set_attenuation(const light_attenuation&& value) { + attenuation = value; +} + +void light_data::get_ibl_color0(vec4& value) const { + value = ibl_color0; +} + +void light_data::set_ibl_color0(const vec4& value) { + ibl_color0 = value; +} + +void light_data::set_ibl_color0(const vec4&& value) { + ibl_color0 = value; +} + +void light_data::get_ibl_color1(vec4& value) const { + value = ibl_color1; +} + +void light_data::set_ibl_color1(const vec4& value) { + ibl_color1 = value; +} + +void light_data::set_ibl_color1(const vec4&& value) { + ibl_color1 = value; +} + +void light_data::get_ibl_direction(vec4& value) const { + value = ibl_direction; +} + +void light_data::set_ibl_direction(const vec4& value) { + ibl_direction = value; +} + +void light_data::set_ibl_direction(const vec4&& value) { + ibl_direction = value; +} + +void light_data::get_tone_curve(light_tone_curve& value) const { + value = tone_curve; +} + +void light_data::set_tone_curve(const light_tone_curve& value) { + tone_curve = value; +} + +void light_data::set_tone_curve(const light_tone_curve&& value) { + tone_curve = value; +} + +void light_data::get_clip_plane(light_clip_plane& value) const { + value = clip_plane; +} + +void light_data::set_clip_plane(const light_clip_plane& value) { + clip_plane = value; +} + +void light_data::set_clip_plane(const light_clip_plane&& value) { + clip_plane = value; +} + +void light_set::get_ambient_intensity(vec4& value) { + value = ambient_intensity; +} + +void light_set::set_ambient_intensity(const vec4& value) { + ambient_intensity = value; +} + +void light_set::set_ambient_intensity(const vec4&& value) { + ambient_intensity = value; +} + +void light_set::get_irradiance(mat4& r, mat4& g, mat4& b) { + r = irradiance_r; + g = irradiance_g; + b = irradiance_b; +} + +void light_set::set_irradiance(const mat4& r, const mat4& g, const mat4& b) { + irradiance_r = r; + irradiance_g = g; + irradiance_b = b; +} + +void light_set::set_irradiance(const mat4&& r, const mat4&& g, const mat4&& b) { + irradiance_r = r; + irradiance_g = g; + irradiance_b = b; +} + +void light_set::data_set(light_set_id id) { + static const float_t spec_coef = (float_t)(1.0 / (1.0 - cos(18.0 * DEG_TO_RAD))); + static const float_t luce_coef = (float_t)(1.0 / (1.0 - cos(45.0 * DEG_TO_RAD))); + + extern render_context* rctx; + obj_scene_shader_data& obj_scene = rctx->obj_scene; + + lights[LIGHT_STAGE].get_diffuse(obj_scene.g_light_env_stage_diffuse); + lights[LIGHT_STAGE].get_specular(obj_scene.g_light_env_stage_specular); + + lights[LIGHT_CHARA].get_diffuse(obj_scene.g_light_env_chara_diffuse); + lights[LIGHT_CHARA].get_ambient(obj_scene.g_light_env_chara_ambient); + lights[LIGHT_CHARA].get_specular(obj_scene.g_light_env_chara_specular); + + lights[LIGHT_REFLECT].get_diffuse(obj_scene.g_light_env_reflect_diffuse); + lights[LIGHT_REFLECT].get_ambient(obj_scene.g_light_env_reflect_ambient); + + lights[LIGHT_PROJECTION].get_diffuse(obj_scene.g_light_env_proj_diffuse); + lights[LIGHT_PROJECTION].get_specular(obj_scene.g_light_env_proj_specular); + lights[LIGHT_PROJECTION].get_position(obj_scene.g_light_env_proj_position); + if (lights[LIGHT_PROJECTION].get_type() == LIGHT_PARALLEL) + light_get_direction_from_position(&obj_scene.g_light_env_proj_position, 0, true); + + vec4 light_chara_dir; + vec4 light_chara_ibl_color0; + vec4 light_chara_ibl_color1; + vec4 light_chara_specular; + lights[LIGHT_CHARA].get_position(light_chara_dir); + light_get_direction_from_position(&light_chara_dir, &lights[LIGHT_CHARA]); + lights[LIGHT_CHARA].get_ibl_color0(light_chara_ibl_color0); + lights[LIGHT_CHARA].get_ibl_color1(light_chara_ibl_color1); + lights[LIGHT_CHARA].get_specular(light_chara_specular); + + obj_scene.g_light_chara_dir = light_chara_dir; + obj_scene.g_light_chara_spec = light_chara_specular * light_chara_ibl_color0 * spec_coef; + obj_scene.g_light_chara_luce = light_chara_ibl_color0 * luce_coef; + obj_scene.g_light_chara_back = light_chara_specular * light_chara_ibl_color1 * spec_coef; + + vec4 light_stage_dir; + vec4 light_stage_ibl_color; + vec4 light_stage_diffuse; + vec4 light_stage_specular; + lights[LIGHT_STAGE].get_position(light_stage_dir); + light_get_direction_from_position(&light_stage_dir, &lights[LIGHT_STAGE]); + lights[LIGHT_STAGE].get_ibl_color0(light_stage_ibl_color); + lights[LIGHT_STAGE].get_diffuse(light_stage_diffuse); + lights[LIGHT_STAGE].get_specular(light_stage_specular); + + obj_scene.g_light_stage_dir = light_stage_dir; + obj_scene.g_light_stage_diff = light_stage_diffuse * light_stage_ibl_color; + obj_scene.g_light_stage_spec = light_stage_specular * light_stage_ibl_color * spec_coef; + + mat4 irradiance_r_transforms; + mat4 irradiance_g_transforms; + mat4 irradiance_b_transforms; + get_irradiance(irradiance_r_transforms, irradiance_g_transforms, irradiance_b_transforms); + obj_scene.set_g_irradiance_r_transforms(irradiance_r_transforms); + obj_scene.set_g_irradiance_g_transforms(irradiance_g_transforms); + obj_scene.set_g_irradiance_b_transforms(irradiance_b_transforms); + + + float_t* (FASTCALL * face_data_get)() = (float_t * (FASTCALL*)())0x00000001403D8310; + float_t offset = face_data_get()[0]; + float_t v28 = (float_t)(1.0 - exp(offset * -0.44999999)) * 2.0f; + offset = max_def(offset, 0.0f); + obj_scene.g_light_face_diff = { v28 * 0.1f, offset * 0.06f, 1.0f, 1.0f }; + + if (lights[LIGHT_CHARA_COLOR].get_type() == LIGHT_PARALLEL) { + lights[LIGHT_CHARA_COLOR].get_ambient(obj_scene.g_chara_color_rim); + lights[LIGHT_CHARA_COLOR].get_diffuse(obj_scene.g_chara_color0); + lights[LIGHT_CHARA_COLOR].get_specular(obj_scene.g_chara_color1); + if (obj_scene.g_chara_color1.w > 1.0f) + obj_scene.g_chara_color1.w = 1.0f; + } + else { + obj_scene.g_chara_color_rim = 0.0f; + obj_scene.g_chara_color0 = 0.0f; + obj_scene.g_chara_color1 = 0.0f; + } + + if (lights[LIGHT_TONE_CURVE].get_type() == LIGHT_PARALLEL) { + uniform->arr[U_TONE_CURVE] = 1; + vec4 chara_f_dir; + vec4 chara_f_ambient; + vec4 chara_f_diffuse; + vec4 chara_tc_param; + lights[LIGHT_TONE_CURVE].get_position(chara_f_dir); + light_get_direction_from_position(&chara_f_dir, &lights[LIGHT_TONE_CURVE]); + lights[LIGHT_TONE_CURVE].get_ambient(chara_f_ambient); + lights[LIGHT_TONE_CURVE].get_diffuse(chara_f_diffuse); + + light_tone_curve tone_curve; + lights[LIGHT_TONE_CURVE].get_tone_curve(tone_curve); + chara_tc_param.x = tone_curve.start_point; + float_t end_point = min_def(tone_curve.end_point, 1.0f) - tone_curve.start_point; + if (end_point > 0.0f) + chara_tc_param.y = 1.0f / end_point; + else + chara_tc_param.y = 0.0f; + chara_tc_param.z = tone_curve.coefficient; + chara_tc_param.w = 0.0f; + + obj_scene.g_chara_f_dir = chara_f_dir; + obj_scene.g_chara_f_ambient = chara_f_ambient; + obj_scene.g_chara_f_diffuse = chara_f_diffuse; + obj_scene.g_chara_tc_param = chara_tc_param; + } + else { + uniform->arr[U_TONE_CURVE] = 0; + obj_scene.g_chara_f_dir = { 0.0f, 1.0f, 0.0f, 0.0f }; + obj_scene.g_chara_f_ambient = 0.0f; + obj_scene.g_chara_f_diffuse = 0.0f; + obj_scene.g_chara_tc_param = 0.0f; + } + + vec4 light_reflect_dir; + lights[LIGHT_CHARA].get_position(light_reflect_dir); + if (fabsf(light_reflect_dir.x) <= 0.000001f && fabsf(light_reflect_dir.y) <= 0.000001f + && fabsf(light_reflect_dir.z) <= 0.000001f) + *(vec3*)&light_reflect_dir = vec3(0.0f, 1.0f, 0.0f); + else { + float_t length = vec3::length(*(vec3*)&light_reflect_dir); + if (length != 0.0f) + *(vec3*)&light_reflect_dir *= 1.0f / length; + } + light_reflect_dir.w = 1.0f; + + obj_scene.g_light_reflect_dir = light_reflect_dir; + + if (lights[LIGHT_REFLECT].get_type() == LIGHT_SPOT) { + vec3 spot_direction; + vec4 position; + lights[LIGHT_REFLECT].get_spot_direction(spot_direction); + lights[LIGHT_REFLECT].get_position(position); + vec4 clip_plane; + *(vec3*)&clip_plane = -spot_direction; + light_get_direction_from_position(&clip_plane, &lights[LIGHT_REFLECT], true); + clip_plane.w = -vec3::dot(*(vec3*)&position, *(vec3*)&clip_plane); + + obj_scene.g_clip_plane = clip_plane; + } + else if (lights[LIGHT_REFLECT].get_type() == LIGHT_POINT) + obj_scene.g_clip_plane = { 0.0f, -1.0f, 0.0f, 9999.0f }; + else + obj_scene.g_clip_plane = { 0.0f, -1.0f, 0.0f, 0.0f }; + + vec4 light_chara_ibl_direction; + vec4 light_chara_position; + lights[LIGHT_CHARA].get_ibl_direction(light_chara_ibl_direction); + lights[LIGHT_CHARA].get_position(light_chara_position); + + mat4 normal_tangent_transforms = mat4_identity; + + float_t length = vec3::length(*(vec3*)&light_chara_ibl_direction); + if (length >= 0.000001f) { + vec3 ibl_direction = *(vec3*)&light_chara_ibl_direction * (1.0f / length); + + length = vec3::length(*(vec3*)&light_chara_position); + if (length >= 0.000001f) { + vec3 position = *(vec3*)&light_chara_position * (1.0f / length); + + vec3 axis = vec3::cross(ibl_direction, position); + length = vec3::length(axis); + + float_t v52 = vec3::dot(ibl_direction, position); + float_t angle = fabsf(atan2f(length, v52)); + if (angle >= 0.01f && angle <= 3.131592653589793f) { + if (length != 0.0f) + axis *= 1.0f / length; + + mat4_set(&axis, -angle, &normal_tangent_transforms); + } + } + } + + obj_scene.set_g_normal_tangent_transforms(normal_tangent_transforms); + obj_scene.g_npr_cloth_spec_color = *npr_cloth_spec_color; +} + +static void light_get_direction_from_position(vec4* pos_dir, light_data* light, bool force) { + if (force || light->get_type() == LIGHT_PARALLEL) { + float_t length = vec3::length(*(vec3*)pos_dir); + if (length <= 0.000001) + *(vec3*)pos_dir = vec3(0.0f, 1.0f, 0.0f); + else + *(vec3*)pos_dir *= 1.0f / length; + pos_dir->w = 0.0f; + } +} diff --git a/src/DivaGL/light_param/light.hpp b/src/DivaGL/light_param/light.hpp new file mode 100644 index 0000000..37dbfa8 --- /dev/null +++ b/src/DivaGL/light_param/light.hpp @@ -0,0 +1,105 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/light_param/light.hpp" +#include "../../KKdLib/mat.hpp" +#include "../../KKdLib/vec.hpp" + +struct light_data { + light_type type; + vec4 ambient; + vec4 diffuse; + vec4 specular; + vec4 position; + vec3 spot_direction; + float_t spot_exponent; + float_t spot_cutoff; + light_attenuation attenuation; + vec4 ibl_color0; + vec4 ibl_color1; + vec4 ibl_direction; + light_tone_curve tone_curve; + light_clip_plane clip_plane; + + light_type get_type() const; + void set_type(light_type value); + void get_ambient(vec4& value) const; + void set_ambient(const vec4& value); + void set_ambient(const vec4&& value); + void set_ambient(const vec4& value, bool set[4]); + void set_ambient(const vec4&& value, bool set[4]); + void get_diffuse(vec4& value) const; + void set_diffuse(const vec4& value); + void set_diffuse(const vec4&& value); + void set_diffuse(const vec4& value, bool set[4]); + void set_diffuse(const vec4&& value, bool set[4]); + void get_specular(vec4& value) const; + void set_specular(const vec4& value); + void set_specular(const vec4&& value); + void set_specular(const vec4& value, bool set[4]); + void set_specular(const vec4&& value, bool set[4]); + void get_position(vec3& value) const; + void set_position(const vec3& value); + void set_position(const vec3&& value); + void get_position(vec4& value) const; + void set_position(const vec4& value); + void set_position(const vec4&& value); + void get_spot_direction(vec3& value) const; + void set_spot_direction(const vec3& value); + void set_spot_direction(const vec3&& value); + float_t get_spot_exponent() const; + void set_spot_exponent(float_t value); + float_t get_spot_cutoff() const; + void set_spot_cutoff(float_t value); + float_t get_constant() const; + void set_constant(float_t value); + float_t get_linear() const; + void set_linear(float_t value); + float_t get_quadratic() const; + void set_quadratic(float_t value); + void get_attenuation(light_attenuation& value) const; + void set_attenuation(const light_attenuation& value); + void set_attenuation(const light_attenuation&& value); + void get_ibl_color0(vec4& value) const; + void set_ibl_color0(const vec4& value); + void set_ibl_color0(const vec4&& value); + void get_ibl_color1(vec4& value) const; + void set_ibl_color1(const vec4& value); + void set_ibl_color1(const vec4&& value); + void get_ibl_direction(vec4& value) const; + void set_ibl_direction(const vec4& value); + void set_ibl_direction(const vec4&& value); + void get_tone_curve(light_tone_curve& value) const; + void set_tone_curve(const light_tone_curve& value); + void set_tone_curve(const light_tone_curve&& value); + void get_clip_plane(light_clip_plane& value) const; + void set_clip_plane(const light_clip_plane& value); + void set_clip_plane(const light_clip_plane&& value); +}; + +static_assert(sizeof(light_data) == 0xA4, "\"light\" struct should have a size of 0xA4"); + +struct light_set { + light_data lights[LIGHT_MAX]; + vec4 ambient_intensity; + mat4 irradiance_r; + mat4 irradiance_g; + mat4 irradiance_b; + + void get_ambient_intensity(vec4& value); + void set_ambient_intensity(const vec4& value); + void set_ambient_intensity(const vec4&& value); + void get_irradiance(mat4& r, mat4& g, mat4& b); + void set_irradiance(const mat4& r, const mat4& g, const mat4& b); + void set_irradiance(const mat4&& r, const mat4&& g, const mat4&& b); + void data_set(light_set_id id); +}; + +static_assert(sizeof(light_set) == 0x5F0, "\"light_set\" struct should have a size of 0x5F0"); + +extern light_set* light_set_data; diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp new file mode 100644 index 0000000..1138fe2 --- /dev/null +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -0,0 +1,2343 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "disp_manager.hpp" +#include "../gl_state.hpp" +#include "../render_manager.hpp" +#include "../shader_glsl_ft.hpp" +#include "../uniform.hpp" +#include "../wrap.hpp" +#include "draw_object.hpp" +#include + +mdl::DispManager* disp_manager = (mdl::DispManager*)0x00000001411A27F0; + +static mat4* matrix_buffer = (mat4*)0x000000014CC587D0; +static BOOL* matrix_buffer_init = (BOOL*)0x000000014CC5D7D0; + +static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshArgs* args, + int32_t texcoord_array[2], GLuint vertex_attrib_buffer_binding[16]); + +static const GLuint POSITION_INDEX = 0; +static const GLuint BONE_WEIGHT_INDEX = 1; +static const GLuint NORMAL_INDEX = 2; +static const GLuint COLOR0_INDEX = 3; +static const GLuint COLOR1_INDEX = 4; +static const GLuint MORPH_COLOR_INDEX = 5; +static const GLuint TANGENT_INDEX = 6; +static const GLuint UNKNOWN_INDEX = 7; +static const GLuint TEXCOORD0_INDEX = 8; +static const GLuint TEXCOORD1_INDEX = 9; +static const GLuint MORPH_POSITION_INDEX = 10; +static const GLuint MORPH_NORMAL_INDEX = 11; +static const GLuint MORPH_TANGENT_INDEX = 12; +static const GLuint MORPH_TEXCOORD0_INDEX = 13; +static const GLuint MORPH_TEXCOORD1_INDEX = 14; +static const GLuint BONE_INDEX_INDEX = 15; + +namespace mdl { + prj::vector vertex_array_cache; + prj::vector etc_vertex_array_cache; + + void EtcObj::init(EtcObjType type) { + this->type = type; + color = 0xFFFFFFFF; + fog = false; + switch (type) { + case ETC_OBJ_TEAPOT: + data.teapot = {}; + break; + case ETC_OBJ_GRID: + data.grid = {}; + break; + case ETC_OBJ_CUBE: + data.cube = {}; + break; + case ETC_OBJ_SPHERE: + data.sphere = {}; + break; + case ETC_OBJ_PLANE: + data.plane = {}; + break; + case ETC_OBJ_CONE: + data.cone = {}; + break; + case ETC_OBJ_LINE: + data.line = {}; + break; + case ETC_OBJ_CROSS: + data.cross = {}; + break; + } + } + + void ObjData::init_etc(const mat4* mat, mdl::EtcObj* etc) { + kind = mdl::OBJ_KIND_ETC; + this->mat = *mat; + args.etc = *etc; + + disp_manager->add_vertex_array(&args.etc, this->mat); + } + + void ObjData::init_sub_mesh(const mat4* mat, + float_t radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, + prj::vector* textures, int32_t mat_count, mat4* mats, GLuint vertex_buffer, + GLuint index_buffer, vec4* blend_color, GLuint morph_vertex_buffer, + int32_t instances_count, mat4* instances_mat, + void(FASTCALL* func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data) { + kind = mdl::OBJ_KIND_NORMAL; + this->mat = *mat; + this->radius = radius; + + mdl::ObjSubMeshArgs* args = &this->args.sub_mesh; + args->mesh = mesh; + args->morph_weight = disp_manager->morph.weight; + args->material = material; + args->sub_mesh = sub_mesh; + args->textures = textures; + args->mat_count = mat_count; + args->mats = mats; + args->vertex_buffer = vertex_buffer; + args->index_buffer = index_buffer; + args->morph_vertex_buffer = morph_vertex_buffer; + + args->texture_pattern_count = disp_manager->texture_pattern_count; + for (int32_t i = 0; i < disp_manager->texture_pattern_count && i < TEXTURE_PATTERN_COUNT; i++) + args->texture_pattern_array[i] = disp_manager->texture_pattern_array[i]; + + args->texture_transform_count = disp_manager->texture_transform_count; + for (int32_t i = 0; i < disp_manager->texture_transform_count && i < TEXTURE_TRANSFORM_COUNT; i++) + args->texture_transform_array[i] = disp_manager->texture_transform_array[i]; + + if (blend_color && *blend_color != 1.0f) { + args->set_blend_color = true; + args->blend_color = *blend_color; + } + else { + args->set_blend_color = false; + args->blend_color = 1.0f; + } + + args->chara_color = disp_manager->chara_color; + args->self_shadow = disp_manager->obj_flags & (mdl::OBJ_8 | mdl::OBJ_4) ? 1 : 0; + args->shadow = disp_manager->shadow_type; + args->texture_color_coefficients = disp_manager->texture_color_coefficients; + args->texture_color_coefficients.w = disp_manager->wet_param; + args->texture_color_offset = disp_manager->texture_color_offset; + args->texture_specular_coefficients = disp_manager->texture_specular_coefficients; + args->texture_specular_offset = disp_manager->texture_specular_offset; + args->instances_count = instances_count; + args->instances_mat = instances_mat; + args->func = func; + args->func_data = func_data; + + disp_manager->add_vertex_array(args); + } + + void ObjData::init_translucent(const mat4* mat, ObjTranslucentArgs* translucent) { + kind = mdl::OBJ_KIND_TRANSLUCENT; + this->mat = *mat; + args.translucent = *translucent; + } + + void ObjData::init_user(const mat4* mat, UserArgsFunc func, void* data) { + kind = OBJ_KIND_USER; + this->mat = *mat; + args.user.func = func; + args.user.data = data; + } + + + void DispManager::add_vertex_array(ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + const obj_sub_mesh* sub_mesh = args->sub_mesh; + const obj_material_data* material = args->material; + + GLuint vertex_buffer = args->vertex_buffer; + GLuint morph_vertex_buffer = args->morph_vertex_buffer; + GLuint index_buffer = args->index_buffer; + + int32_t texcoord_array[2] = { -1, -1 }; + int32_t color_tex_index = 0; + for (const obj_material_texture_data& i : material->material.texdata) { + if (i.tex_index == -1) + continue; + + int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( + i.shader_info.m.tex_type, color_tex_index); + if (texcoord_index < 0) + continue; + + texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; + + if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + color_tex_index++; + } + + GLuint vertex_attrib_buffer_binding[16] = {}; + object_data_get_vertex_attrib_buffer_bindings(args, + texcoord_array, vertex_attrib_buffer_binding); + + GLsizei size_vertex = (GLsizei)mesh->size_vertex; + obj_vertex_format vertex_format = mesh->vertex_format; + + DispManager::vertex_array* vertex_array = 0; + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time >= 0 && i.vertex_buffer == vertex_buffer + && i.morph_vertex_buffer == morph_vertex_buffer + && i.index_buffer == index_buffer && i.vertex_format == vertex_format + && i.size_vertex == size_vertex + && !memcmp(i.vertex_attrib_buffer_binding, + vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)) + && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) + if (i.vertex_array) { + i.alive_time = 60; + return; + } + else { + vertex_array = &i; + break; + } + + if (!vertex_array) + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time <= 0) { + vertex_array = &i; + break; + } + + if (!vertex_array) { + vertex_array_cache.push_back({}); + vertex_array = &vertex_array_cache.back(); + } + + if (!vertex_array->vertex_array) { + glGenVertexArrays(1, &vertex_array->vertex_array); + + gl_state_bind_vertex_array(vertex_array->vertex_array); + glVertexAttrib4f(POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(BONE_WEIGHT_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + glVertexAttrib4f(NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f(COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f(MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f(TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(BONE_INDEX_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + } + + vertex_array->vertex_buffer = vertex_buffer; + vertex_array->morph_vertex_buffer = morph_vertex_buffer; + vertex_array->index_buffer = index_buffer; + vertex_array->alive_time = 60; + vertex_array->vertex_format = vertex_format; + vertex_array->size_vertex = size_vertex; + memcpy(&vertex_array->texcoord_array, texcoord_array, sizeof(texcoord_array)); + memcpy(&vertex_array->vertex_attrib_buffer_binding, + vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)); + + gl_state_bind_vertex_array(vertex_array->vertex_array); + gl_state_bind_array_buffer(vertex_buffer); + if (index_buffer) + gl_state_bind_element_array_buffer(index_buffer, true); + + size_t offset = 0; + if (vertex_format & OBJ_VERTEX_POSITION) { + if (!vertex_array->vertex_attrib_array[POSITION_INDEX]) { + glEnableVertexAttribArray(POSITION_INDEX); + vertex_array->vertex_attrib_array[POSITION_INDEX] = true; + } + + glVertexAttribPointer(POSITION_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + } + else if (vertex_array->vertex_attrib_array[POSITION_INDEX]) { + glDisableVertexAttribArray(POSITION_INDEX); + vertex_array->vertex_attrib_array[POSITION_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + if (!vertex_array->vertex_attrib_array[NORMAL_INDEX]) { + glEnableVertexAttribArray(NORMAL_INDEX); + vertex_array->vertex_attrib_array[NORMAL_INDEX] = true; + } + + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + } + else if (vertex_array->vertex_attrib_array[NORMAL_INDEX]) { + glDisableVertexAttribArray(NORMAL_INDEX); + vertex_array->vertex_attrib_array[NORMAL_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + if (!vertex_array->vertex_attrib_array[TANGENT_INDEX]) { + glEnableVertexAttribArray(TANGENT_INDEX); + vertex_array->vertex_attrib_array[TANGENT_INDEX] = true; + } + + glVertexAttribPointer(TANGENT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else if (vertex_array->vertex_attrib_array[TANGENT_INDEX]) { + glDisableVertexAttribArray(TANGENT_INDEX); + vertex_array->vertex_attrib_array[TANGENT_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_BINORMAL) + offset += 12; + + for (int32_t i = 0; i < 2; i++) { + int32_t texcoord_index = texcoord_array[i]; + if (texcoord_index < 0) { + if (vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i]) { + glDisableVertexAttribArray(TEXCOORD0_INDEX + i); + vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i] = false; + } + continue; + } + + if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << texcoord_index)) { + if (!vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i]) { + glEnableVertexAttribArray(TEXCOORD0_INDEX + i); + vertex_array->vertex_attrib_array[TEXCOORD0_INDEX + i] = true; + } + + glVertexAttribPointer(TEXCOORD0_INDEX + i, 2, GL_FLOAT, GL_FALSE, + size_vertex, (void*)(offset + 8ULL * texcoord_index)); + } + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 8; + + if (vertex_format & OBJ_VERTEX_COLOR0) { + if (!vertex_array->vertex_attrib_array[COLOR0_INDEX]) { + glEnableVertexAttribArray(COLOR0_INDEX); + vertex_array->vertex_attrib_array[COLOR0_INDEX] = true; + } + + glVertexAttribPointer(COLOR0_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else if (vertex_array->vertex_attrib_array[COLOR0_INDEX]) { + glDisableVertexAttribArray(COLOR0_INDEX); + vertex_array->vertex_attrib_array[COLOR0_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_COLOR1) + offset += 16; + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { + if (!vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX]) { + glEnableVertexAttribArray(BONE_WEIGHT_INDEX); + vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX] = true; + } + + glVertexAttribPointer(BONE_WEIGHT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + + if (!vertex_array->vertex_attrib_array[BONE_INDEX_INDEX]) { + glEnableVertexAttribArray(BONE_INDEX_INDEX); + vertex_array->vertex_attrib_array[BONE_INDEX_INDEX] = true; + } + + glVertexAttribIPointer(BONE_INDEX_INDEX, + 4, GL_SHORT, size_vertex, (void*)offset); + offset += 8; + } + else { + if (vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX]) { + glDisableVertexAttribArray(BONE_WEIGHT_INDEX); + vertex_array->vertex_attrib_array[BONE_WEIGHT_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[BONE_INDEX_INDEX]) { + glDisableVertexAttribArray(BONE_INDEX_INDEX); + vertex_array->vertex_attrib_array[BONE_INDEX_INDEX] = false; + } + } + + if (vertex_format & OBJ_VERTEX_UNKNOWN) { + if (!vertex_array->vertex_attrib_array[UNKNOWN_INDEX]) { + glEnableVertexAttribArray(UNKNOWN_INDEX); + vertex_array->vertex_attrib_array[UNKNOWN_INDEX] = true; + } + + glVertexAttribPointer(UNKNOWN_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else if (vertex_array->vertex_attrib_array[UNKNOWN_INDEX]) { + glDisableVertexAttribArray(UNKNOWN_INDEX); + vertex_array->vertex_attrib_array[UNKNOWN_INDEX] = false; + } + + if (morph_vertex_buffer) { + gl_state_bind_array_buffer(morph_vertex_buffer); + + size_t offset = 0; + if (vertex_format & OBJ_VERTEX_POSITION) { + if (!vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { + glEnableVertexAttribArray(MORPH_POSITION_INDEX); + vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = true; + } + + glVertexAttribPointer(MORPH_POSITION_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + } + else if (vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { + glDisableVertexAttribArray(MORPH_POSITION_INDEX); + vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_NORMAL) { + if (!vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { + glEnableVertexAttribArray(MORPH_NORMAL_INDEX); + vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = true; + } + + glVertexAttribPointer(MORPH_NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 12; + } + else if (vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { + glDisableVertexAttribArray(MORPH_NORMAL_INDEX); + vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_TANGENT) { + if (!vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { + glEnableVertexAttribArray(MORPH_TANGENT_INDEX); + vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = true; + } + + glVertexAttribPointer(MORPH_TANGENT_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else if (vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { + glDisableVertexAttribArray(MORPH_TANGENT_INDEX); + vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_BINORMAL) + offset += 12; + + if (vertex_format & OBJ_VERTEX_TEXCOORD0) { + if (!vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { + glEnableVertexAttribArray(MORPH_TEXCOORD0_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = true; + } + + glVertexAttribPointer(MORPH_TEXCOORD0_INDEX, + 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + } + else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD0_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD1) { + if (!vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { + glEnableVertexAttribArray(MORPH_TEXCOORD1_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = true; + } + + glVertexAttribPointer(MORPH_TEXCOORD1_INDEX, + 2, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 8; + } + else if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD1_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_TEXCOORD2) + offset += 8; + if (vertex_format & OBJ_VERTEX_TEXCOORD3) + offset += 8; + + if (vertex_format & OBJ_VERTEX_COLOR0) { + uniform->arr[U_MORPH_COLOR] = 1; + + if (!vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { + glEnableVertexAttribArray(MORPH_COLOR_INDEX); + vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = true; + } + + glVertexAttribPointer(MORPH_COLOR_INDEX, + 4, GL_FLOAT, GL_FALSE, size_vertex, (void*)offset); + offset += 16; + } + else if (vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { + glDisableVertexAttribArray(MORPH_COLOR_INDEX); + vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = false; + } + + if (vertex_format & OBJ_VERTEX_COLOR1) + offset += 16; + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + offset += 32; + + if (vertex_format & OBJ_VERTEX_UNKNOWN) + offset += 16; + } + else { + if (vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX]) { + glDisableVertexAttribArray(MORPH_POSITION_INDEX); + vertex_array->vertex_attrib_array[MORPH_POSITION_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX]) { + glDisableVertexAttribArray(MORPH_NORMAL_INDEX); + vertex_array->vertex_attrib_array[MORPH_NORMAL_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX]) { + glDisableVertexAttribArray(MORPH_TANGENT_INDEX); + vertex_array->vertex_attrib_array[MORPH_TANGENT_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD0_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD0_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX]) { + glDisableVertexAttribArray(MORPH_TEXCOORD1_INDEX); + vertex_array->vertex_attrib_array[MORPH_TEXCOORD1_INDEX] = false; + } + + if (vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX]) { + glDisableVertexAttribArray(MORPH_COLOR_INDEX); + vertex_array->vertex_attrib_array[MORPH_COLOR_INDEX] = false; + } + } + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + if (index_buffer) + gl_state_bind_element_array_buffer(0); + } + + static void gen_cube_vertices(prj::vector& data) { + data.resize(sizeof(vec3) * 2 * 4 * 6); + + vec3* vtx = (vec3*)data.data(); + *vtx++ = { -1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + *vtx++ = { 1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + *vtx++ = { 1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + *vtx++ = { -1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 0.0f, -1.0f }; + + *vtx++ = { -1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + *vtx++ = { 1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + *vtx++ = { 1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + *vtx++ = { -1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 0.0f, 1.0f }; + + *vtx++ = { -1.0f, 1.0f, 1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + *vtx++ = { -1.0f, 1.0f, -1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + *vtx++ = { -1.0f, -1.0f, -1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + *vtx++ = { -1.0f, -1.0f, 1.0f }; + *vtx++ = { -1.0f, 0.0f, 0.0f }; + + *vtx++ = { 1.0f, 1.0f, -1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + *vtx++ = { 1.0f, 1.0f, 1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, -1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, 1.0f }; + *vtx++ = { 1.0f, 0.0f, 0.0f }; + + *vtx++ = { -1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, -1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + *vtx++ = { 1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + *vtx++ = { -1.0f, -1.0f, 1.0f }; + *vtx++ = { 0.0f, -1.0f, 0.0f }; + + *vtx++ = { -1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + *vtx++ = { 1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + *vtx++ = { 1.0f, 1.0f, -1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + *vtx++ = { -1.0f, 1.0f, 1.0f }; + *vtx++ = { 0.0f, 1.0f, 0.0f }; + } + + static size_t gen_cube_indices(prj::vector& indices) { + const uint32_t sides_indices[] = { + 0, 1, 2, 0, 3, 1, + 4, 5, 6, 6, 7, 4, + 8, 9, 10, 10, 11, 8, + 12, 13, 14, 15, 14, 13, + 16, 17, 18, 18, 19, 16, + 20, 21, 22, 20, 23, 21, + }; + + const uint32_t edges_indices[] = { + 0, 2, 1, 2, 0, 3, 1, 3, + 4, 5, 6, 5, 4, 7, 6, 7, + 0, 4, 1, 6, 2, 5, 3, 7, + }; + + indices.insert(indices.end(), sides_indices, + sides_indices + sizeof(sides_indices) / sizeof(uint32_t)); + + size_t wire_offset = indices.size(); + + indices.insert(indices.end(), edges_indices, + edges_indices + sizeof(edges_indices) / sizeof(uint32_t)); + + return wire_offset; + } + + static void gen_sphere_vertices(prj::vector& data, + int32_t slices, int32_t stacks, float_t radius) { + if (slices < 2 || stacks < 2) + return; + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(radius); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(1.0f); + data.push_back(0.0f); + + double_t slice_step = (M_PI * 2.0) / (double_t)slices; + double_t stack_step = M_PI / (double_t)stacks; + + for (int32_t i = 1; i < stacks; i++) { + float_t stack_angle = (float_t)((M_PI / 2.0) - (double_t)i * stack_step); + float_t xz = cosf(stack_angle); + float_t y = sinf(stack_angle); + + data.reserve(sizeof(vec3) * 2 * slices); + + for (int32_t j = 0; j < slices; j++) { + float_t slice_angle = (float_t)((double_t)j * slice_step); + + float_t x = xz * cosf(slice_angle); + float_t z = xz * sinf(slice_angle); + + data.push_back(x * radius); + data.push_back(y * radius); + data.push_back(z * radius); + + data.push_back(x); + data.push_back(y); + data.push_back(z); + } + } + + data.reserve(sizeof(vec3) * 2); + + data.push_back(0.0f); + data.push_back(-radius); + data.push_back(0.0f); + + data.push_back(0.0f); + data.push_back(-1.0f); + data.push_back(0.0f); + } + + static size_t gen_sphere_indices(prj::vector& indices, + int32_t slices, int32_t stacks) { + if (slices < 2 || stacks < 2) + return 0; + + // Top stack vertices + { + int32_t m1 = 0; + int32_t m2 = 1; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Middle stacks vertices + for (int32_t i = 1; i < stacks - 1; i++) { + int32_t m1 = (i - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(6LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(j + m2); + + indices.push_back(k + m1); + indices.push_back(k + m2); + indices.push_back(j + m2); + + if (++k >= slices) + k = 0; + } + } + + // Bottom stack vertices + { + int32_t m1 = (stacks - 2) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(3LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(k + m1); + indices.push_back(m2); + + if (++k >= slices) + k = 0; + } + } + + size_t wire_offset = indices.size(); + + // Top stack wireframe + { + int32_t m1 = 0; + int32_t m2 = 1; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(m1); + indices.push_back(j + m2); + } + } + + // Middle stacks wireframe + for (int32_t i = 1; i < stacks - 1; i++) { + int32_t m1 = (i - 1) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(j + m2); + } + } + + // Bottom stack wireframe + { + int32_t m1 = (stacks - 2) * slices + 1; + int32_t m2 = m1 + slices; + + indices.reserve(2LL * slices); + + for (int32_t j = 0; j < slices; j++) { + indices.push_back(j + m1); + indices.push_back(m2); + } + } + + // Slices wireframe + for (int32_t i = 1; i < stacks; i++) { + int32_t m = (i - 1) * slices + 1; + + indices.reserve(2LL * slices); + + for (int32_t j = 0, k = 1; j < slices; j++) { + indices.push_back(j + m); + indices.push_back(k + m); + + if (k++ >= slices) + k = 0; + } + } + + return wire_offset; + } + + void DispManager::add_vertex_array(EtcObj* etc, mat4& mat) { + EtcObjType type = etc->type; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + break; + default: + return; + } + + bool indexed = false; + bool wire = false; + float_t length = 0.0f; + + switch (type) { + case mdl::ETC_OBJ_TEAPOT: { + EtcObjTeapot& teapot = etc->data.teapot; + + indexed = true; + } break; + case mdl::ETC_OBJ_GRID: { + EtcObjGrid& grid = etc->data.grid; + + } break; + case mdl::ETC_OBJ_CUBE: { + EtcObjCube& cube = etc->data.cube; + + vec3 size = cube.size * 0.5f; + mat4_scale_rot(&mat, &size, &mat); + + indexed = true; + wire = cube.wire; + } break; + case mdl::ETC_OBJ_SPHERE: { + EtcObjSphere& sphere = etc->data.sphere; + + indexed = true; + wire = sphere.wire; + } break; + case mdl::ETC_OBJ_PLANE: { + EtcObjPlane& plane = etc->data.plane; + + mat4_scale_rot(&mat, (float_t)plane.w * 0.5f, 1.0f, (float_t)plane.h * 0.5f, &mat); + } break; + case mdl::ETC_OBJ_CONE: { + EtcObjCone& cone = etc->data.cone; + + indexed = true; + wire = cone.wire; + } break; + case mdl::ETC_OBJ_LINE: { + EtcObjLine& line = etc->data.line; + + } break; + case mdl::ETC_OBJ_CROSS: { + EtcObjCross& cross = etc->data.cross; + + mat4_scale_rot(&mat, cross.size, &mat); + } break; + } + + DispManager::etc_vertex_array* etc_vertex_array = 0; + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + if (i.alive_time <= 0 || i.type != type || i.vertex_buffer.IsNull()) + continue; + + if (type == mdl::ETC_OBJ_TEAPOT + || type == mdl::ETC_OBJ_GRID + && !memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid)) + || type == mdl::ETC_OBJ_CUBE + || type == mdl::ETC_OBJ_SPHERE + && i.data.sphere.slices == etc->data.sphere.slices + && i.data.sphere.stacks == etc->data.sphere.stacks + && fabsf(i.data.sphere.radius - etc->data.sphere.radius) < 0.00001f + || type == mdl::ETC_OBJ_PLANE + || type == mdl::ETC_OBJ_CONE + && i.data.cone.slices == etc->data.cone.slices + && i.data.cone.stacks == etc->data.cone.stacks + && fabsf(i.data.cone.base - etc->data.cone.base) < 0.00001f + && fabsf(i.data.cone.height - etc->data.cone.height) < 0.00001f + || type == mdl::ETC_OBJ_LINE + || type == mdl::ETC_OBJ_CROSS) + if (i.vertex_array) { + i.alive_time = 2; + if (!wire) { + etc->count = i.count; + etc->offset = i.offset; + } + else { + etc->count = i.wire_count; + etc->offset = i.wire_offset; + } + return; + } + else { + etc_vertex_array = &i; + break; + } + } + + if (!etc_vertex_array) + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) + if (i.alive_time <= 0) { + etc_vertex_array = &i; + break; + } + + if (!etc_vertex_array) { + etc_vertex_array_cache.push_back({}); + etc_vertex_array = &etc_vertex_array_cache.back(); + } + + if (!etc_vertex_array->vertex_array) { + glGenVertexArrays(1, &etc_vertex_array->vertex_array); + + gl_state_bind_vertex_array(etc_vertex_array->vertex_array); + glVertexAttrib4f( POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( BONE_WEIGHT_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + glVertexAttrib4f( NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( COLOR0_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( COLOR1_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( MORPH_COLOR_INDEX, 1.0f, 1.0f, 1.0f, 1.0f); + glVertexAttrib4f( TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( UNKNOWN_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_POSITION_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_NORMAL_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( MORPH_TANGENT_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_TEXCOORD0_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f(MORPH_TEXCOORD1_INDEX, 0.0f, 0.0f, 0.0f, 1.0f); + glVertexAttrib4f( BONE_INDEX_INDEX, 0.0f, 0.0f, 0.0f, 0.0f); + } + + etc_vertex_array->alive_time = 2; + etc_vertex_array->data = etc->data; + etc_vertex_array->type = type; + + prj::vector vtx_data; + prj::vector vtx_indices; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: { + EtcObjTeapot& teapot = etc->data.teapot; + + etc_vertex_array->count = (GLsizei)vtx_indices.size(); + } break; + case mdl::ETC_OBJ_GRID: { + EtcObjGrid& grid = etc->data.grid; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + case mdl::ETC_OBJ_CUBE: { + EtcObjCube& cube = etc->data.cube; + + gen_cube_vertices(vtx_data); + size_t wire_offset = gen_cube_indices(vtx_indices); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; + case mdl::ETC_OBJ_SPHERE: { + EtcObjSphere& sphere = etc->data.sphere; + + gen_sphere_vertices(vtx_data, sphere.slices, sphere.stacks, sphere.radius); + size_t wire_offset = gen_sphere_indices(vtx_indices, sphere.slices, sphere.stacks); + + etc_vertex_array->offset = 0; + etc_vertex_array->count = (GLsizei)wire_offset; + etc_vertex_array->wire_offset = wire_offset * sizeof(uint32_t); + etc_vertex_array->wire_count = (GLsizei)(vtx_indices.size() - wire_offset); + } break; + case mdl::ETC_OBJ_PLANE: { + EtcObjPlane& plane = etc->data.plane; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + case mdl::ETC_OBJ_CONE: { + EtcObjCone& cone = etc->data.cone; + + etc_vertex_array->count = (GLsizei)vtx_indices.size(); + } break; + case mdl::ETC_OBJ_LINE: { + EtcObjLine& line = etc->data.line; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + case mdl::ETC_OBJ_CROSS: { + EtcObjCross& cross = etc->data.cross; + + etc_vertex_array->count = (GLsizei)(vtx_data.size() / 6); + } break; + } + + if (!wire) { + etc->count = etc_vertex_array->count; + etc->offset = etc_vertex_array->offset; + } + else { + etc->count = etc_vertex_array->wire_count; + etc->offset = etc_vertex_array->wire_offset; + } + + if (!etc_vertex_array->count) + return; + + if (etc_vertex_array->max_vtx < vtx_data.size()) { + etc_vertex_array->max_vtx = vtx_data.size(); + + etc_vertex_array->vertex_buffer.Destroy(); + } + + if (etc_vertex_array->max_idx < vtx_indices.size()) { + etc_vertex_array->max_idx = vtx_indices.size(); + + etc_vertex_array->index_buffer.Destroy(); + } + + GLsizei size_vertex = sizeof(vec3) * 2; + + gl_state_bind_vertex_array(etc_vertex_array->vertex_array); + + if (etc_vertex_array->vertex_buffer.IsNull()) + etc_vertex_array->vertex_buffer.Create(sizeof(float_t) * vtx_data.size()); + + etc_vertex_array->vertex_buffer.Bind(); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float_t) + * vtx_data.size(), vtx_data.data()); + + if (indexed) { + if (etc_vertex_array->index_buffer.IsNull()) + etc_vertex_array->index_buffer.Create(sizeof(uint32_t) * vtx_indices.size()); + + etc_vertex_array->index_buffer.Bind(); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint32_t) + * vtx_indices.size(), vtx_indices.data()); + } + + glEnableVertexAttribArray(POSITION_INDEX); + glVertexAttribPointer(POSITION_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)0); + + glEnableVertexAttribArray(NORMAL_INDEX); + glVertexAttribPointer(NORMAL_INDEX, + 3, GL_FLOAT, GL_FALSE, size_vertex, (void*)sizeof(vec3)); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + if (indexed) + gl_state_bind_element_array_buffer(0); + } + + void* DispManager::alloc_data(int32_t size) { + if (!buff || buff_offset + size > buff_size) + return 0; + + void* data = (void*)((size_t)buff + buff_offset); + buff_offset += size; + buff_max = max_def(buff_max, buff_offset); + return data; + } + + ObjData* DispManager::alloc_obj_data(ObjKind kind) { + int32_t size = (int32_t)align_val(sizeof(ObjKind) + sizeof(mat4) + sizeof(float_t) * 2, 0x08); + switch (kind) { + case OBJ_KIND_NORMAL: + return (ObjData*)alloc_data(size + sizeof(ObjSubMeshArgs)); + case OBJ_KIND_ETC: + return (ObjData*)alloc_data(size + sizeof(EtcObj)); + case OBJ_KIND_USER: + return (ObjData*)alloc_data(size + sizeof(UserArgs)); + case OBJ_KIND_TRANSLUCENT: + return (ObjData*)alloc_data(size + sizeof(ObjTranslucentArgs)); + default: + return 0; + } + } + + mat4* DispManager::alloc_mat4_array(int32_t count) { + return (mat4*)alloc_data(sizeof(mat4) * count); + } + + void DispManager::buffer_reset() { + buff_offset = 0; + } + + void DispManager::check_vertex_arrays() { + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time > 0 && --i.alive_time <= 0) { + i.vertex_buffer = 0; + i.morph_vertex_buffer = 0; + } + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) + if (i.alive_time > 0 && --i.alive_time <= 0) { + gl_state_bind_vertex_array(i.vertex_array); + glDisableVertexAttribArray(POSITION_INDEX); + glDisableVertexAttribArray(NORMAL_INDEX); + gl_state_bind_array_buffer(0, true); + gl_state_bind_element_array_buffer(0, true); + gl_state_bind_vertex_array(0); + } + } + + void DispManager::draw(ObjType type, int32_t depth_mask, bool a4) { + if (get_obj_count(type) < 1) + return; + + int32_t alpha_test = 0; + float_t min_alpha = 1.0f; + float_t alpha_threshold = 0.0f; + bool reflect = uniform->arr[U_REFLECT] == 1; + void(*func)(const ObjSubMeshArgs * args) = draw_sub_mesh_default; + + for (int32_t i = 0; i < 5; i++) + gl_state_active_bind_texture_2d(i, rctx->empty_texture_2d); + gl_state_active_bind_texture_cube_map(5, rctx->empty_texture_cube_map); + gl_state_active_texture(0); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + uniform_value_reset(); + gl_state_get(); + + rctx->obj_scene_ubo.Bind(0); + rctx->obj_batch_ubo.Bind(1); + rctx->obj_skinning_ubo.Bind(3); + + switch (type) { + case OBJ_TYPE_TRANSLUCENT: + case OBJ_TYPE_TRANSLUCENT_NO_SHADOW: + //case OBJ_TYPE_TRANSLUCENT_LOCAL: + if (depth_mask) + func = draw_sub_mesh_translucent; + else + gl_state_set_depth_mask(GL_FALSE); + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_TRANSPARENT: + //case OBJ_TYPE_TRANSPARENT_LOCAL: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + break; + case OBJ_TYPE_SHADOW_CHARA: + case OBJ_TYPE_SHADOW_STAGE: + case OBJ_TYPE_SHADOW_OBJECT_CHARA: + case OBJ_TYPE_SHADOW_OBJECT_STAGE: + func = draw_sub_mesh_shadow; + break; + case OBJ_TYPE_TYPE_6: + func = draw_sub_mesh_translucent; + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + draw_state->shader_index = SHADER_FT_SIL; + break; + case OBJ_TYPE_TYPE_7: + func = draw_sub_mesh_translucent; + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + draw_state->shader_index = SHADER_FT_SIL; + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.99999994f; + break; + case OBJ_TYPE_REFLECT_CHARA_OPAQUE: + gl_state_set_cull_face_mode(GL_FRONT); + if (reflect) + func = draw_sub_mesh_reflect; + else if (render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) + func = draw_sub_mesh_reflect_reflect_map; + break; + case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT: + gl_state_set_cull_face_mode(GL_FRONT); + if (reflect) + func = draw_sub_mesh_reflect; + else if (render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) + func = draw_sub_mesh_reflect_reflect_map; + min_alpha = 0.0f; + break; + case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: + gl_state_set_cull_face_mode(GL_FRONT); + if (reflect) + func = draw_sub_mesh_reflect; + else if (render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) + func = draw_sub_mesh_reflect_reflect_map; + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + break; + case OBJ_TYPE_REFLECT_OPAQUE: + alpha_test = 1; + if (!a4) + func = draw_sub_mesh_reflect_reflect_map; + break; + case OBJ_TYPE_REFLECT_TRANSLUCENT: + case OBJ_TYPE_REFRACT_TRANSLUCENT: + gl_state_set_depth_mask(GL_FALSE); + min_alpha = 0.0f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_REFLECT_TRANSPARENT: + case OBJ_TYPE_REFRACT_TRANSPARENT: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_SSS: + func = draw_sub_mesh_sss; + break; + case OBJ_TYPE_USER: + func = draw_sub_mesh_translucent; + break; + default: + break; + } + rctx->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; + uniform->arr[U_ALPHA_TEST] = alpha_test; + + for (ObjData*& i : obj[type]) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_ETC: { + draw_object_model_mat_load(i->mat); + draw_etc_obj(&i->args.etc); + } break; + case OBJ_KIND_USER: { + draw_object_model_mat_load(i->mat); + i->args.user.func(i->args.user.data); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (uint32_t j = 0; j < i->args.translucent.count; j++) + draw_sub_mesh(i->args.translucent.sub_mesh[j], &i->mat, func); + } break; + } + } + + switch (type) { + case OBJ_TYPE_TRANSLUCENT: + case OBJ_TYPE_TRANSLUCENT_NO_SHADOW: + case OBJ_TYPE_REFLECT_TRANSLUCENT: + case OBJ_TYPE_REFRACT_TRANSLUCENT: + if (!depth_mask) + gl_state_set_depth_mask(GL_TRUE); + break; + case OBJ_TYPE_TYPE_6: + case OBJ_TYPE_TYPE_7: + draw_state->shader_index = -1; + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + break; + case OBJ_TYPE_REFLECT_CHARA_OPAQUE: + case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT: + case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: + gl_state_set_cull_face_mode(GL_BACK); + break; + } + + uniform_value_reset(); + gl_state_bind_vertex_array(0); + shader_glsl::unbind(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + for (int32_t i = 0; i < 5; i++) + gl_state_bind_sampler(i, 0); + } + + void DispManager::draw_translucent(ObjType type, int32_t alpha) { + if (get_obj_count(type) < 1) + return; + + int32_t alpha_test = 0; + float_t min_alpha = 1.0f; + float_t alpha_threshold = 0.0f; + bool reflect = uniform->arr[U_REFLECT] == 1; + void(*func)(const ObjSubMeshArgs * args) = draw_sub_mesh_default; + + for (int32_t i = 0; i < 5; i++) + gl_state_active_bind_texture_2d(i, rctx->empty_texture_2d); + gl_state_active_bind_texture_cube_map(5, rctx->empty_texture_cube_map); + gl_state_active_texture(0); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + uniform_value_reset(); + gl_state_get(); + + rctx->obj_scene_ubo.Bind(0); + rctx->obj_batch_ubo.Bind(1); + rctx->obj_skinning_ubo.Bind(3); + + switch (type) { + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: + //case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL: + gl_state_set_depth_mask(GL_FALSE); + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.0f; + break; + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: + //case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + break; + } + rctx->obj_batch.g_max_alpha = { 0.0f, 0.0f, alpha_threshold, min_alpha }; + uniform->arr[U_ALPHA_TEST] = alpha_test; + + for (ObjData*& i : obj[type]) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + int32_t a = (int32_t)(i->args.sub_mesh.blend_color.w * 255.0f); + a = clamp_def(a, 0, 255); + if (a == alpha) + draw_sub_mesh(&i->args.sub_mesh, &i->mat, func); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (uint32_t j = 0; j < i->args.translucent.count; j++) { + ObjSubMeshArgs* args = i->args.translucent.sub_mesh[j]; + int32_t a = (int32_t)(args->blend_color.w * 255.0f); + a = clamp_def(a, 0, 255); + if (a == alpha) + draw_sub_mesh(args, &i->mat, func); + } + } break; + } + } + + switch (type) { + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: + gl_state_set_depth_mask(GL_TRUE); + break; + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: + gl_state_set_cull_face_mode(GL_BACK); + break; + } + + uniform_value_reset(); + shader_glsl::unbind(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + } + + /*void DispManager::draw_show_vector(ObjType type, int32_t show_vector) { + if (get_obj_count(type) < 1) + return; + + render_context* rctx = rctx_ptr; + + for (int32_t i = 0; i < 5; i++) + gl_state_active_bind_texture_2d(i, rctx->empty_texture_2d); + gl_state_active_bind_texture_cube_map(5, rctx->empty_texture_cube_map); + gl_state_active_texture(0); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + uniform_value_reset(); + gl_state_get(); + + for (ObjData*& i : obj[type]) { + switch (i->type) { + case OBJ_KIND_NORMAL: { + draw_sub_mesh_show_vector(&i->args.sub_mesh, + &i->mat, show_vector); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (uint32_t j = 0; j < i->args.translucent.count; j++) + draw_sub_mesh_show_vector(i->args.translucent.sub_mesh[j], + &i->mat, show_vector); + } break; + } + } + gl_state_set_blend_func(GL_ONE, GL_ZERO); + }*/ + + void DispManager::entry_list(ObjType type, ObjData* data) { + obj[type].push_back(data); + } + + static int32_t obj_axis_aligned_bounding_box_check_visibility( + obj_axis_aligned_bounding_box* aabb, const mat4* mat) { + vec3 points[8]; + points[0] = aabb->center + (aabb->size ^ vec3(0.0f, 0.0f, 0.0f)); + points[1] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, -0.0f)); + points[2] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, 0.0f)); + points[3] = aabb->center + (aabb->size ^ vec3(0.0f, -0.0f, -0.0f)); + points[4] = aabb->center + (aabb->size ^ vec3(0.0f, -0.0f, 0.0f)); + points[5] = aabb->center + (aabb->size ^ vec3(-0.0f, 0.0f, -0.0f)); + points[6] = aabb->center + (aabb->size ^ vec3(0.0f, 0.0f, -0.0f)); + points[7] = aabb->center + (aabb->size ^ vec3(-0.0f, -0.0f, 0.0f)); + + mat4 view_mat; + mat4_transpose(&camera_data->view_matrix, &view_mat); + mat4_mul(mat, &view_mat, &view_mat); + for (int32_t i = 0; i < 8; i++) + mat4_transform_point(&view_mat, &points[i], &points[i]); + + vec4 v2[6]; + *(vec3*)&v2[0] = { 0.0f, 0.0f, -1.0f }; + v2[0].w = (float_t)-camera_data->min_distance; + *(vec3*)&v2[1] = camera_data->field_1E4; + v2[1].w = 0.0f; + *(vec3*)&v2[2] = camera_data->field_1F0; + v2[2].w = 0.0f; + *(vec3*)&v2[3] = camera_data->field_1FC; + v2[3].w = 0.0f; + *(vec3*)&v2[4] = camera_data->field_208; + v2[4].w = 0.0f; + *(vec3*)&v2[5] = { 0.0f, 0.0f, 1.0f }; + v2[5].w = (float_t)camera_data->max_distance; + + for (int32_t i = 0; i < 6; i++) + for (int32_t j = 0; j < 8; j++) { + float_t v34 = vec3::dot(*(vec3*)&v2[i], points[j]) + v2[i].w; + if (v34 > 0.0f) + break; + + if (j == 7) + return 0; + } + return 1; + } + + static int32_t obj_bounding_sphere_check_visibility(obj_bounding_sphere* sphere, + CullingCheck* culling, const mat4* mat) { + if (disp_manager->culling_func) + return disp_manager->culling_func(sphere); + + mat4 view_mat; + mat4_transpose(&camera_data->view_matrix, &view_mat); + + vec3 center; + mat4_transform_point(mat, &sphere->center, ¢er); + mat4_transform_point(&view_mat, ¢er, ¢er); + float_t radius = mat4_get_max_scale(mat) * sphere->radius; + + double_t min_depth = (double_t)center.z - (double_t)radius; + double_t max_depth = (double_t)center.z + (double_t)radius; + if (-camera_data->min_distance < min_depth || -camera_data->max_distance > max_depth) + return 0; + + float_t v5 = vec3::dot(camera_data->field_1E4, center); + if (v5 < -radius) + return 0; + + float_t v6 = vec3::dot(camera_data->field_1F0, center); + if (v6 < -radius) + return 0; + + float_t v7 = vec3::dot(camera_data->field_1FC, center); + if (v7 < -radius) + return 0; + + float_t v8 = vec3::dot(camera_data->field_208, center); + if (v8 < -radius) + return 0; + + if (-camera_data->min_distance >= max_depth && -camera_data->max_distance <= min_depth + && v5 >= radius && v6 >= radius && v7 >= radius && v8 >= radius) + return 1; + return 2; + } + + bool DispManager::entry_obj(::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, + obj_mesh_index_buffer* obj_index_buf, const mat4* mat, + prj::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph, + obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, mat4* instances_mat, + void(*func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data, + bool enable_bone_mat, bool local) { + if (!obj_vertex_buf || !obj_index_buf) + return false; + + camera_struct::update_data(); + + if (!local && object_culling && !instances_count && !bone_mat && (!object + || !obj_bounding_sphere_check_visibility( + &object->bounding_sphere, &culling, mat))) { + culling.culled.objects++; + return false; + } + culling.passed.objects++; + + for (uint32_t i = 0; i < object->num_mesh; i++) { + obj_mesh* mesh = &object->mesh_array[i]; + obj_mesh* mesh_morph = 0; + if (obj_vertex_buf && obj_morph_vertex_buf) { + if (obj_vertex_buf[i].get_size() != obj_morph_vertex_buf[i].get_size()) + continue; + + if (object_morph && i < object_morph->num_mesh) + mesh_morph = &object_morph->mesh_array[i]; + } + + if (!local && object_culling && !instances_count && !bone_mat + && !obj_bounding_sphere_check_visibility( + &mesh->bounding_sphere, &culling, mat) + && (!mesh_morph || !obj_bounding_sphere_check_visibility( + &mesh_morph->bounding_sphere, &culling, mat))) { + culling.culled.meshes++; + continue; + } + culling.passed.meshes++; + + ObjSubMeshArgs* translucent_priority[40]; + int32_t translucent_priority_count = 0; + + for (uint32_t j = 0; j < mesh->num_submesh; j++) { + obj_sub_mesh* sub_mesh = &mesh->submesh_array[j]; + obj_sub_mesh* sub_mesh_morph = 0; + if (sub_mesh->attrib.m.cloth) + continue; + + if (!local && object_culling && !instances_count && !bone_mat) { + int32_t v32 = obj_bounding_sphere_check_visibility( + &sub_mesh->bounding_sphere, &culling, mat); + if (v32 != 2 || (!mesh->attrib.m.billboard && !mesh->attrib.m.billboard_y_axis)) { + if (v32 == 2) { + if (disp_manager->culling_func) + v32 = 1; + else + v32 = obj_axis_aligned_bounding_box_check_visibility( + sub_mesh->axis_aligned_bounding_box, mat); + } + + if (!v32) { + if (!mesh_morph || j >= mesh_morph->num_submesh) { + culling.culled.submesh_array++; + continue; + } + + sub_mesh_morph = &mesh_morph->submesh_array[j]; + if (!sub_mesh_morph) { + culling.culled.submesh_array++; + continue; + } + + v32 = obj_bounding_sphere_check_visibility( + &sub_mesh_morph->bounding_sphere, &culling, mat); + if (v32 == 2) { + if (disp_manager->culling_func) + v32 = 1; + else + v32 = obj_axis_aligned_bounding_box_check_visibility( + sub_mesh_morph->axis_aligned_bounding_box, mat); + } + + if (!v32) { + culling.culled.submesh_array++; + continue; + } + } + } + } + culling.passed.submesh_array++; + + int32_t num_bone_index = sub_mesh->num_bone_index; + uint16_t* bone_index = sub_mesh->bone_index_array; + + mat4* mats; + if (num_bone_index && enable_bone_mat) { + mats = alloc_mat4_array(num_bone_index); + if (bone_mat) + for (int32_t k = 0; k < num_bone_index; k++, bone_index++) + mats[k] = bone_mat[*bone_index]; + else + for (int32_t k = 0; k < num_bone_index; k++) + mats[k] = mat4_identity; + } + else { + mats = 0; + num_bone_index = 0; + } + + obj_material_data* material = &object->material_array[sub_mesh->material_index]; + ObjData* data = alloc_obj_data(OBJ_KIND_NORMAL); + if (!data) + continue; + + GLuint morph_vertex_buffer = 0; + if (obj_morph_vertex_buf) + morph_vertex_buffer = obj_morph_vertex_buf[i].get_buffer(); + + GLuint index_buffer = 0; + if (obj_index_buf) + index_buffer = obj_index_buf[i].buffer; + + GLuint vertex_buffer = 0; + if (obj_vertex_buf) + vertex_buffer = obj_vertex_buf[i].get_buffer(); + + if (!vertex_buffer || !index_buffer || obj_morph_vertex_buf && !morph_vertex_buffer) + continue; + + vec4 _blend_color = 1.0f; + if (blend_color) + _blend_color = *blend_color; + + data->init_sub_mesh(mat, object->bounding_sphere.radius, sub_mesh, + mesh, material, textures, num_bone_index, mats, vertex_buffer, index_buffer, + &_blend_color, morph_vertex_buffer, instances_count, instances_mat, func, func_data); + + if (obj_flags & mdl::OBJ_SHADOW_OBJECT) { + entry_list((ObjType)(OBJ_TYPE_SHADOW_OBJECT_CHARA + + shadow_type), data); + if (obj_flags & mdl::OBJ_USER) + entry_list(OBJ_TYPE_USER, data); + continue; + } + + obj_material_attrib_member attrib = material->material.attrib.m; + if (obj_flags & (mdl::OBJ_ALPHA_ORDER_1 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_3) + && data->args.sub_mesh.blend_color.w < 1.0f) { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { + if (attrib.flag_28 || (attrib.punch_through + || !(attrib.alpha_texture | attrib.alpha_material)) + && !sub_mesh->attrib.m.transparent) { + if (!attrib.punch_through) { + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(/*local ? OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL + : */OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, data); + else + entry_list(OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, data); + } + else { + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(/*local ? OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL + : */OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, data); + else + entry_list(OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, data); + } + + if (obj_flags & mdl::OBJ_SSS) + entry_list(OBJ_TYPE_SSS, data); + } + + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(/*local ? OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL + : */OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, data); + else + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, data); + } + } + else { + if (attrib.flag_28 || data->args.sub_mesh.blend_color.w >= 1.0f + && (attrib.punch_through || !(attrib.alpha_texture | attrib.alpha_material)) + && !sub_mesh->attrib.m.transparent) { + if (obj_flags & mdl::OBJ_SHADOW) + entry_list((ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); + + if (obj_flags & mdl::OBJ_SSS) + entry_list(OBJ_TYPE_SSS, data); + + if (attrib.punch_through) { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) + entry_list(/*local ? OBJ_TYPE_TRANSPARENT_LOCAL + : */OBJ_TYPE_TRANSPARENT, data); + + if (obj_flags & mdl::OBJ_CHARA_REFLECT) + entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFLECT) + entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFRACT) + entry_list(OBJ_TYPE_REFRACT_TRANSPARENT, data); + } + else { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) + entry_list(/*local ? OBJ_TYPE_OPAQUE_LOCAL + : */OBJ_TYPE_OPAQUE, data); + + if (obj_flags & mdl::OBJ_20) + entry_list(OBJ_TYPE_TYPE_6, data); + + if (obj_flags & mdl::OBJ_CHARA_REFLECT) + entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFLECT) + entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); + + if (obj_flags & mdl::OBJ_REFRACT) + entry_list(OBJ_TYPE_REFRACT_OPAQUE, data); + } + + if (obj_flags & mdl::OBJ_USER) + entry_list(OBJ_TYPE_USER, data); + continue; + } + else if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { + if (!attrib.translucent_priority) + /*if (local) + entry_list(OBJ_TYPE_TRANSLUCENT_LOCAL, data); + else */if (mesh->attrib.m.translucent_no_shadow + || obj_flags & mdl::OBJ_TRANSLUCENT_NO_SHADOW) { + entry_list(OBJ_TYPE_TRANSLUCENT_NO_SHADOW, data); + } + else + entry_list(OBJ_TYPE_TRANSLUCENT, data); + else if (translucent_priority_count < 40) + translucent_priority[translucent_priority_count++] = &data->args.sub_mesh; + } + } + + if (obj_flags & mdl::OBJ_SHADOW) + entry_list((ObjType)(OBJ_TYPE_SHADOW_CHARA + + shadow_type), data); + if (obj_flags & mdl::OBJ_40) + entry_list(OBJ_TYPE_TYPE_7, data); + if (obj_flags & mdl::OBJ_CHARA_REFLECT) + entry_list(OBJ_TYPE_REFLECT_CHARA_OPAQUE, data); + if (obj_flags & mdl::OBJ_REFLECT) { + if (render_manager->reflect_type != STAGE_DATA_REFLECT_REFLECT_MAP) + entry_list(OBJ_TYPE_REFLECT_OPAQUE, data); + else + entry_list(OBJ_TYPE_REFLECT_TRANSLUCENT, data); + } + if (obj_flags & mdl::OBJ_REFRACT) + entry_list(OBJ_TYPE_REFRACT_TRANSLUCENT, data); + if (obj_flags & mdl::OBJ_USER) + entry_list(OBJ_TYPE_USER, data); + } + + if (!translucent_priority_count) + continue; + + ObjTranslucentArgs translucent_args; + translucent_args.count = 0; + for (int32_t j = 62; j; j--) + for (int32_t k = 0; k < translucent_priority_count; k++) { + ObjSubMeshArgs* sub_mesh = translucent_priority[k]; + if (sub_mesh->material->material.attrib.m.translucent_priority != j) + continue; + + translucent_args.sub_mesh[translucent_args.count] = sub_mesh; + translucent_args.count++; + } + + ObjData* data = alloc_obj_data(OBJ_KIND_TRANSLUCENT); + if (!data) + continue; + + data->init_translucent(mat, &translucent_args); + if (obj_flags & mdl::OBJ_ALPHA_ORDER_1) + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_2) + entry_list(/*local ? OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL + : */OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_3) + entry_list(OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, data); + else + entry_list(/*local ? OBJ_TYPE_TRANSLUCENT_LOCAL + : */OBJ_TYPE_TRANSLUCENT, data); + } + return true; + } + + void DispManager::entry_obj_by_obj(const mat4* mat, + ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf, + obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) { + if (!obj) + return; + + vec4 blend_color = { 1.0f, 1.0f, 1.0f, alpha }; + vec4* blend_color_ptr = alpha < 1.0f ? &blend_color : 0; + + entry_obj(obj, obj_vert_buf, obj_index_buf, mat, textures, blend_color_ptr, + bone_mat, 0, 0, 0, 0, 0, 0, !!bone_mat); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat) { + vec4 blend_color = 1.0f; + return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, 0, true); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat, int32_t instances_count, mat4* instances_mat, + void(*func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data, + bool enable_bone_mat, bool local) { + if (obj_info.id == -1 && obj_info.set_id == -1) + return false; + + ::obj* object = object_info_get_object(obj_info); + if (!object) + return false; + + prj::vector* textures = obj_database_get_obj_set_textures(obj_info.set_id); + obj_mesh_vertex_buffer* obj_vertex_buffer = object_info_get_mesh_vertex_buffer(obj_info, 0); + obj_mesh_index_buffer* obj_index_buffer = object_info_get_mesh_index_buffer(obj_info, 0); + + ::obj* obj_morph = 0; + obj_mesh_vertex_buffer* obj_morph_vertex_buffer = 0; + if (morph.object.set_id != -1) { + obj_morph = object_info_get_object(morph.object); + obj_morph_vertex_buffer = object_info_get_mesh_vertex_buffer(morph.object, 0); + } + + return entry_obj(object, obj_vertex_buffer, obj_index_buffer, + mat, textures, blend_color, bone_mat, obj_morph, obj_morph_vertex_buffer, + instances_count, instances_mat, func, func_data, enable_bone_mat, local); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, + object_info obj_info, float_t alpha, mat4* bone_mat) { + vec4 blend_color = 1.0f; + blend_color.w = alpha; + return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, 0, true); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, + float_t r, float_t g, float_t b, float_t a, mat4* bone_mat, bool local) { + vec4 blend_color = { r, g, b, a }; + return entry_obj_by_object_info(mat, obj_info, &blend_color, bone_mat, 0, 0, 0, 0, true, local); + } + + bool DispManager::entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat, bool local) { + return entry_obj_by_object_info(mat, obj_info, blend_color, 0, 0, 0, 0, 0, false, local); + } + + void DispManager::entry_obj_by_object_info_object_skin(object_info obj_info, + prj::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha, + mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat) { + obj_skin* skin = obj_database_get_object_skin(obj_info); + if (!skin) + return; + + if (!*matrix_buffer_init) { + *matrix_buffer_init |= 1u; + mat4* mat = matrix_buffer; + for (int32_t i = 320; i; i--) + *mat++ = mat4_null; + } + + obj_skin_set_matrix_buffer(skin, matrices, ex_data_matrices, matrix_buffer, mat, global_mat); + + vec4 texture_color_coefficients; + vec4 texture_color_offset; + vec4 texture_specular_coefficients; + vec4 texture_specular_offset; + if (texture_data && !texture_data->field_0) { + vec4 value; + get_texture_color_coeff(texture_color_coefficients); + *(vec3*)&value = texture_data->texture_color_coefficients * *(vec3*)&texture_color_coefficients; + value.w = 0.0f; + set_texture_color_coefficients(value); + + get_texture_color_offset(texture_color_offset); + *(vec3*)&value = texture_data->texture_color_offset; + value.w = 0.0f; + set_texture_color_offset(value); + + get_texture_specular_coeff(texture_specular_coefficients); + *(vec3*)&value = texture_data->texture_specular_coefficients * *(vec3*)&texture_specular_coefficients; + value.w = 0.0f; + set_texture_specular_coefficients(value); + + get_texture_specular_offset(texture_specular_offset); + *(vec3*)&value = texture_data->texture_specular_offset; + value.w = 0.0f; + set_texture_specular_offset(value); + } + + size_t texture_pattern_count = texture_pattern ? texture_pattern->size() : 0; + if (texture_pattern && texture_pattern_count) + set_texture_pattern((int32_t)texture_pattern_count, texture_pattern->data()); + + if (fabsf(alpha - 1.0f) > 0.000001f) + entry_obj_by_object_info(global_mat, obj_info, alpha, matrix_buffer); + else + entry_obj_by_object_info(global_mat, obj_info, matrix_buffer); + + if (texture_pattern && texture_pattern_count) + set_texture_pattern(); + + if (texture_data && !texture_data->field_0) { + set_texture_color_coefficients(texture_color_coefficients); + set_texture_color_offset(texture_color_offset); + set_texture_specular_coefficients(texture_specular_coefficients); + set_texture_specular_offset(texture_specular_offset); + } + } + + void DispManager::entry_obj_etc(const mat4* mat, EtcObj* etc, bool local) { + ObjData* data = alloc_obj_data(mdl::OBJ_KIND_ETC); + if (!data) + return; + + data->init_etc(mat, etc); + if (etc->color.a == 0xFF) { + if (!local && (obj_flags & OBJ_SHADOW)) + mdl::DispManager::entry_list((mdl::ObjType)(OBJ_TYPE_SHADOW_CHARA + shadow_type), data); + mdl::DispManager::entry_list(/*local ? OBJ_TYPE_OPAQUE_LOCAL : */OBJ_TYPE_OPAQUE, data); + } + else + mdl::DispManager::entry_list(/*local ? OBJ_TYPE_TRANSLUCENT_LOCAL : */OBJ_TYPE_TRANSLUCENT, data); + } + + void DispManager::entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type) { + ObjData* _data = alloc_obj_data(OBJ_KIND_USER); + if (_data) { + _data->init_user(mat, func, data); + entry_list(type, _data); + } + } + + GLuint DispManager::get_vertex_array(const ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + const obj_sub_mesh* sub_mesh = args->sub_mesh; + const obj_material_data* material = args->material; + + GLuint vertex_buffer = args->vertex_buffer; + GLuint morph_vertex_buffer = args->morph_vertex_buffer; + GLuint index_buffer = args->index_buffer; + + int32_t texcoord_array[2] = { -1, -1 }; + int32_t color_tex_index = 0; + for (const obj_material_texture_data& i : material->material.texdata) { + if (i.tex_index == -1) + continue; + + int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( + i.shader_info.m.tex_type, color_tex_index); + if (texcoord_index < 0) + continue; + + texcoord_array[texcoord_index] = sub_mesh->uv_index[&i - material->material.texdata]; + + if (i.shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + color_tex_index++; + } + + GLuint vertex_attrib_buffer_binding[16] = {}; + object_data_get_vertex_attrib_buffer_bindings(args, + texcoord_array, vertex_attrib_buffer_binding); + + GLsizei size_vertex = (GLsizei)mesh->size_vertex; + obj_vertex_format vertex_format = mesh->vertex_format; + + for (DispManager::vertex_array& i : vertex_array_cache) + if (i.alive_time > 0 && i.vertex_buffer == vertex_buffer + && i.morph_vertex_buffer == morph_vertex_buffer + && i.index_buffer == index_buffer && i.vertex_format == vertex_format + && i.size_vertex == size_vertex + && !memcmp(i.vertex_attrib_buffer_binding, + vertex_attrib_buffer_binding, sizeof(vertex_attrib_buffer_binding)) + && !memcmp(i.texcoord_array, texcoord_array, sizeof(texcoord_array))) + return i.vertex_array; + return 0; + } + + GLuint DispManager::get_vertex_array(const mdl::EtcObj* etc) { + EtcObjType type = etc->type; + float_t length = 0; + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + break; + default: + return 0; + } + + for (DispManager::etc_vertex_array& i : etc_vertex_array_cache) { + if (i.alive_time <= 0 || i.type != type) + continue; + + switch (type) { + case mdl::ETC_OBJ_TEAPOT: + return i.vertex_array; + case mdl::ETC_OBJ_GRID: + if (!memcmp(&i.data.grid, &etc->data.grid, sizeof(EtcObjGrid))) + return i.vertex_array; + break; + case mdl::ETC_OBJ_CUBE: + return i.vertex_array; + case mdl::ETC_OBJ_SPHERE: + if (i.data.sphere.slices == etc->data.sphere.slices + && i.data.sphere.stacks == etc->data.sphere.stacks + && fabsf(i.data.sphere.radius - etc->data.sphere.radius) < 0.00001f) + return i.vertex_array; + break; + case mdl::ETC_OBJ_PLANE: + return i.vertex_array; + case mdl::ETC_OBJ_CONE: + if (i.data.cone.slices == etc->data.cone.slices + && i.data.cone.stacks == etc->data.cone.stacks + && fabsf(i.data.cone.base - etc->data.cone.base) < 0.00001f + && fabsf(i.data.cone.height - etc->data.cone.height) < 0.00001f) + return i.vertex_array; + break; + case mdl::ETC_OBJ_LINE: + return i.vertex_array; + case mdl::ETC_OBJ_CROSS: + return i.vertex_array; + } + } + return 0; + } + + bool DispManager::get_chara_color() { + return chara_color; + } + + ObjFlags DispManager::get_obj_flags() { + return obj_flags; + } + + void DispManager::get_morph(object_info& object, float_t& weight) { + weight = morph.weight; + object = morph.object; + } + + int32_t DispManager::get_obj_count(ObjType type) { + return (int32_t)obj[type].size(); + } + + shadow_type_enum DispManager::get_shadow_type() { + return shadow_type; + } + + void DispManager::get_texture_color_coeff(vec4& value) { + value = texture_color_coefficients; + } + + void DispManager::get_texture_color_offset(vec4& value) { + value = texture_color_offset; + } + + void DispManager::get_texture_pattern(int32_t& count, texture_pattern_struct*& value) { + count = texture_pattern_count; + + for (int32_t i = 0; i < count; i++) + value[i] = texture_pattern_array[i]; + } + + void DispManager::get_texture_specular_coeff(vec4& value) { + value = texture_specular_coefficients; + } + + void DispManager::get_texture_specular_offset(vec4& value) { + value = texture_specular_offset; + } + + void DispManager::get_texture_transform(int32_t& count, texture_transform_struct*& value) { + count = texture_transform_count; + + for (int32_t i = 0; i < count; i++) + value[i] = texture_transform_array[i]; + } + + float_t DispManager::get_wet_param() { + return wet_param; + } + + void DispManager::obj_sort(mat4* view, ObjType type, int32_t compare_func) { + prj::list& list = obj[type]; + if (list.size() < 1) + return; + + for (ObjData*& i : list) { + vec3 center; + mat4_get_translation(&i->mat, ¢er); + if (i->kind == OBJ_KIND_NORMAL) { + mat4 mat = i->mat; + if (i->args.sub_mesh.mesh->attrib.m.billboard) + model_mat_face_camera_view(view, &mat, &mat); + else if (i->args.sub_mesh.mesh->attrib.m.billboard_y_axis) + model_mat_face_camera_position(view, &mat, &mat); + + const obj_sub_mesh* sub_mesh = i->args.sub_mesh.sub_mesh; + if (i->args.sub_mesh.mat_count < 1 || !sub_mesh->num_bone_index) + mat4_transform_point(&mat, &sub_mesh->bounding_sphere.center, ¢er); + else { + vec3 center_sum = 0.0f; + for (uint32_t j = 0; j < sub_mesh->num_bone_index; j++) { + center = sub_mesh->bounding_sphere.center; + mat4_transform_point(&i->args.sub_mesh.mats[j], ¢er, ¢er); + center_sum += center; + } + center_sum *= 1.0f / (float_t)sub_mesh->num_bone_index; + } + i->radius = i->args.sub_mesh.mesh->bounding_sphere.radius; + } + + mat4_transform_point(view, ¢er, ¢er); + i->view_z = center.z; + } + + switch (compare_func) { + case 0: + list.sort([](ObjData* left, ObjData* right) { + return left->view_z > right->view_z; + }); + break; + case 1: + list.sort([](ObjData* left, ObjData* right) { + return left->view_z < right->view_z; + }); + break; + case 2: + list.sort([](ObjData* left, ObjData* right) { + return left->radius > right->radius; + }); + break; + } + } + + void DispManager::refresh() { + culling.passed_prev = culling.passed; + culling.culled_prev = culling.culled; + culling.passed = {}; + culling.culled = {}; + + obj_flags = (::mdl::ObjFlags)0; + field_8 = 0; + field_C = 0; + + texture_pattern_count = 0; + memset(texture_pattern_array, 0, sizeof(texture_pattern_array)); + texture_transform_count = 0; + memset(texture_transform_array, 0, sizeof(texture_transform_array)); + texture_color_coefficients = 1.0f; + texture_color_offset = 0.0f; + texture_specular_coefficients = 1.0f; + texture_specular_offset = 0.0f; + + for (prj::list& i : obj) + i.clear(); + + buffer_reset(); + } + + void DispManager::set_chara_color(bool value) { + chara_color = value; + } + + void DispManager::set_culling_finc(bool(FASTCALL* func)(obj_bounding_sphere*)) { + culling_func = func; + } + + void DispManager::set_obj_flags(ObjFlags flags) { + obj_flags = flags; + } + + void DispManager::set_morph(object_info object, float_t weight) { + morph.weight = weight; + morph.object = object; + } + + void DispManager::set_shadow_type(shadow_type_enum type) { + if (type == SHADOW_CHARA || type == SHADOW_STAGE) + shadow_type = type; + } + + void DispManager::set_texture_color_coefficients(vec4& value) { + texture_color_coefficients = value; + } + + void DispManager::set_texture_color_offset(vec4& value) { + texture_color_offset = value; + } + + void DispManager::set_texture_pattern(int32_t count, texture_pattern_struct* value) { + if (count > TEXTURE_PATTERN_COUNT) + return; + + texture_pattern_count = count; + + if (count) + for (int32_t i = 0; i < count; i++) + texture_pattern_array[i] = value[i]; + else + for (int32_t i = 0; i < TEXTURE_PATTERN_COUNT; i++) + texture_pattern_array[i] = {}; + } + + void DispManager::set_texture_specular_coefficients(vec4& value) { + texture_specular_coefficients = value; + } + + void DispManager::set_texture_specular_offset(vec4& value) { + texture_specular_offset = value; + } + + void DispManager::set_texture_transform(int32_t count, texture_transform_struct* value) { + if (count > TEXTURE_TRANSFORM_COUNT) + return; + + texture_transform_count = count; + + if (count) + for (int32_t i = 0; i < count; i++) + texture_transform_array[i] = value[i]; + else + for (int32_t i = count; i < TEXTURE_TRANSFORM_COUNT; i++) + texture_transform_array[i] = {}; + } + + void DispManager::set_wet_param(float_t value) { + wet_param = value; + } + + static const mat4* rob_chara_item_equip_mat = 0; + + HOOK(void, FASTCALL, DispManager__entry_obj, 0x00000001404379E0, + obj* obj_data, obj_mesh_vertex_buffer* obj_vert_buf, obj_mesh_index_buffer* obj_index_buf, + prj::vector* textures, vec4* blend_color, mat4* bone_mat, obj* obj_morph, + obj_mesh_vertex_buffer* obj_morph_vert_buf, float_t morph_value, + int32_t instances_count, mat4* instances_mat, obj_mesh_vertex_buffer* a12, int32_t* a13, + void(FASTCALL* func)(const mdl::ObjSubMeshArgs*), const mdl::ObjSubMeshArgs* func_data, bool enable_bone_mat) { + abort(); + } + + HOOK(void, FASTCALL, DispManager__entry_obj_by_obj, 0x0000000140439A20, obj* obj_data, prj::vector* textures, + obj_mesh_vertex_buffer* obj_vert_buf, obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha) { + if (!obj_data) + return; + + vec4 blend_color = 1.0f; + blend_color.w = alpha; + + vec4* blend_color_ptr = alpha < 1.0f ? &blend_color : 0; + disp_manager->entry_obj(obj_data, obj_vert_buf, obj_index_buf, rob_chara_item_equip_mat, + textures, blend_color_ptr, bone_mat, 0, 0, 0, 0, 0, 0, 0, !!bone_mat); + } + + HOOK(void, FASTCALL, DispManager__entry_obj_by_object_info_object_skin, 0x00000001405E8E20, + object_info obj_info, prj::vector* texture_pattern, + texture_data_struct* texture_data, float_t alpha, mat4* matrices, mat4* ex_data_matrices, mat4* mat) { + disp_manager->entry_obj_by_object_info_object_skin(obj_info, texture_pattern, texture_data, + alpha, matrices, ex_data_matrices, mat, rob_chara_item_equip_mat); + } + + void disp_manager_patch() { + WRITE_NOP_6(0x0000000140542019); + WRITE_NOP_6(0x000000014054204F); + WRITE_NOP_6(0x000000014054208E); + + uint8_t buf[0x1B] = {}; + buf[0x00] = 0x48; + buf[0x01] = 0x8D; + buf[0x02] = 0x8F; + buf[0x03] = 0xFC; + buf[0x04] = 0x00; + buf[0x05] = 0x00; + buf[0x06] = 0x00; + buf[0x07] = 0x48; + buf[0x08] = 0xB8; + *(uint64_t*)&buf[0x09] = (uint64_t)&rob_chara_item_equip_mat; + buf[0x11] = 0x48; + buf[0x12] = 0x89; + buf[0x13] = 0x08; + buf[0x14] = 0x0F; + buf[0x15] = 0x1F; + buf[0x16] = 0x80; + buf[0x17] = 0x00; + buf[0x18] = 0x00; + buf[0x19] = 0x00; + buf[0x1A] = 0x00; + WRITE_MEMORY_STRING(0x0000000140512A82, buf, sizeof(buf)); + + WRITE_NOP_6(0x0000000140512BE6); + + INSTALL_HOOK(DispManager__entry_obj); + INSTALL_HOOK(DispManager__entry_obj_by_obj); + INSTALL_HOOK(DispManager__entry_obj_by_object_info_object_skin); + } +} + +static void object_data_get_vertex_attrib_buffer_bindings(const mdl::ObjSubMeshArgs* args, + int32_t texcoord_array[2], GLuint vertex_attrib_buffer_binding[16]) { + const obj_mesh* mesh = args->mesh; + const obj_sub_mesh* sub_mesh = args->sub_mesh; + + GLuint vertex_buffer = args->vertex_buffer; + GLuint morph_vertex_buffer = args->morph_vertex_buffer; + + GLsizei size_vertex = (GLsizei)mesh->size_vertex; + obj_vertex_format vertex_format = mesh->vertex_format; + + if (vertex_format & OBJ_VERTEX_POSITION) + vertex_attrib_buffer_binding[POSITION_INDEX] = vertex_buffer; + if (vertex_format & OBJ_VERTEX_NORMAL) + vertex_attrib_buffer_binding[NORMAL_INDEX] = vertex_buffer; + if (vertex_format & OBJ_VERTEX_TANGENT) + vertex_attrib_buffer_binding[TANGENT_INDEX] = vertex_buffer; + + for (int32_t i = 0; i < 2; i++) { + int32_t texcoord_index = texcoord_array[i]; + if (texcoord_index >= 0) + if (vertex_format & (OBJ_VERTEX_TEXCOORD0 << texcoord_index)) + vertex_attrib_buffer_binding[TEXCOORD0_INDEX + i] = vertex_buffer; + } + + if (vertex_format & OBJ_VERTEX_COLOR0) + vertex_attrib_buffer_binding[COLOR0_INDEX] = vertex_buffer; + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) { + vertex_attrib_buffer_binding[BONE_WEIGHT_INDEX] = vertex_buffer; + vertex_attrib_buffer_binding[BONE_INDEX_INDEX] = vertex_buffer; + } + + if (vertex_format & OBJ_VERTEX_UNKNOWN) + vertex_attrib_buffer_binding[UNKNOWN_INDEX] = vertex_buffer; + + if (args->morph_vertex_buffer) { + if (vertex_format & OBJ_VERTEX_POSITION) + vertex_attrib_buffer_binding[MORPH_POSITION_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_NORMAL) + vertex_attrib_buffer_binding[MORPH_NORMAL_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_TANGENT) + vertex_attrib_buffer_binding[MORPH_TANGENT_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_TEXCOORD0) + vertex_attrib_buffer_binding[MORPH_TEXCOORD0_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_TEXCOORD1) + vertex_attrib_buffer_binding[MORPH_TEXCOORD1_INDEX] = morph_vertex_buffer; + if (vertex_format & OBJ_VERTEX_COLOR0) + vertex_attrib_buffer_binding[MORPH_COLOR_INDEX] = morph_vertex_buffer; + } +} diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp new file mode 100644 index 0000000..641ada5 --- /dev/null +++ b/src/DivaGL/mdl/disp_manager.hpp @@ -0,0 +1,449 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/mat.hpp" +#include "../../KKdLib/vec.hpp" +#include "../gl_array_buffer.hpp" +#include "../gl_element_array_buffer.hpp" +#include "../color.hpp" +#include "../object.hpp" +#include "../shadow.hpp" + +#define TEXTURE_PATTERN_COUNT 24 +#define TEXTURE_TRANSFORM_COUNT 24 + +namespace mdl { + enum EtcObjType { + ETC_OBJ_TEAPOT = 0, + ETC_OBJ_GRID, + ETC_OBJ_CUBE, + ETC_OBJ_SPHERE, + ETC_OBJ_PLANE, + ETC_OBJ_CONE, + ETC_OBJ_LINE, + ETC_OBJ_CROSS, + ETC_OBJ_MAX, + }; + + enum ObjKind { + OBJ_KIND_NORMAL = 0, + OBJ_KIND_ETC, + OBJ_KIND_USER, + OBJ_KIND_TRANSLUCENT, + OBJ_KIND_MAX, + }; + + enum ObjFlags : uint32_t { + OBJ_SHADOW = 0x00000001, + OBJ_2 = 0x00000002, + OBJ_4 = 0x00000004, + OBJ_8 = 0x00000008, + OBJ_10 = 0x00000010, + OBJ_20 = 0x00000020, + OBJ_40 = 0x00000040, + OBJ_SHADOW_OBJECT = 0x00000080, + OBJ_CHARA_REFLECT = 0x00000100, + OBJ_REFLECT = 0x00000200, + OBJ_REFRACT = 0x00000400, + OBJ_800 = 0x00000800, + OBJ_TRANSLUCENT_NO_SHADOW = 0x00001000, + OBJ_SSS = 0x00002000, + OBJ_4000 = 0x00004000, + OBJ_8000 = 0x00008000, + OBJ_ALPHA_ORDER_1 = 0x00010000, + OBJ_ALPHA_ORDER_2 = 0x00020000, + OBJ_ALPHA_ORDER_3 = 0x00040000, + OBJ_80000 = 0x00080000, + OBJ_100000 = 0x00100000, + OBJ_200000 = 0x00200000, + OBJ_400000 = 0x00400000, + OBJ_800000 = 0x00800000, + OBJ_USER = 0x01000000, + OBJ_2000000 = 0x02000000, + OBJ_4000000 = 0x04000000, + OBJ_8000000 = 0x08000000, + OBJ_10000000 = 0x10000000, + OBJ_20000000 = 0x20000000, + OBJ_40000000 = 0x40000000, + OBJ_NO_TRANSLUCENCY = 0x80000000, + }; + + enum ObjType { + OBJ_TYPE_OPAQUE = 0, + OBJ_TYPE_TRANSLUCENT, + OBJ_TYPE_TRANSLUCENT_NO_SHADOW, + OBJ_TYPE_TRANSPARENT, + OBJ_TYPE_SHADOW_CHARA, + OBJ_TYPE_SHADOW_STAGE, + OBJ_TYPE_TYPE_6, + OBJ_TYPE_TYPE_7, + OBJ_TYPE_SHADOW_OBJECT_CHARA, + OBJ_TYPE_SHADOW_OBJECT_STAGE, + OBJ_TYPE_REFLECT_CHARA_OPAQUE, + OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT, + OBJ_TYPE_REFLECT_CHARA_TRANSPARENT, + OBJ_TYPE_REFLECT_OPAQUE, + OBJ_TYPE_REFLECT_TRANSLUCENT, + OBJ_TYPE_REFLECT_TRANSPARENT, + OBJ_TYPE_REFRACT_OPAQUE, + OBJ_TYPE_REFRACT_TRANSLUCENT, + OBJ_TYPE_REFRACT_TRANSPARENT, + OBJ_TYPE_SSS, + OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, + OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, + OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, + OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, + OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, + OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, + OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, + OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, + OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, + OBJ_TYPE_USER, + OBJ_TYPE_MAX, + }; +} + +struct morph_struct { + object_info object; + float_t weight; +}; + +static_assert(sizeof(morph_struct) == 0x08, "\"morph_struct\" struct should have a size of 0x08"); + +struct texture_pattern_struct { + uint32_t src; + uint32_t dst; +}; + +static_assert(sizeof(texture_pattern_struct) == 0x08, "\"texture_pattern_struct\" struct should have a size of 0x08"); + +struct texture_transform_struct { + uint32_t id; + mat4 mat; +}; + +static_assert(sizeof(texture_transform_struct) == 0x44, "\"texture_pattern_struct\" struct should have a size of 0x44"); + +struct texture_data_struct { + int32_t field_0; + vec3 texture_color_coefficients; + vec3 texture_color_offset; + vec3 texture_specular_coefficients; + vec3 texture_specular_offset; +}; + +static_assert(sizeof(texture_data_struct) == 0x34, "\"texture_pattern_struct\" struct should have a size of 0x34"); + +namespace mdl { + struct ObjSubMeshArgs { + obj_sub_mesh* sub_mesh; + obj_mesh* mesh; + obj_material_data* material; + prj::vector* textures; + int32_t mat_count; + mat4* mats; + GLuint vertex_buffer; + GLuint index_buffer; + bool set_blend_color; + bool chara_color; + vec4 blend_color; + int32_t self_shadow; + shadow_type_enum shadow; + GLuint morph_vertex_buffer; + float_t morph_weight; + int32_t texture_pattern_count; + texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; + vec4 texture_color_coefficients; + vec4 texture_color_offset; + vec4 texture_specular_coefficients; + vec4 texture_specular_offset; + int32_t texture_transform_count; + texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; + int32_t field_7C4; + int32_t field_7C8; + int32_t instances_count; + mat4* instances_mat; + void(FASTCALL* func)(const ObjSubMeshArgs*); + const ObjSubMeshArgs* func_data; + }; + + static_assert(sizeof(mdl::ObjSubMeshArgs) == 0x7E8, "\"mdl::ObjSubMeshArgs\" struct should have a size of 0x7F8"); + + struct EtcObjTeapot { + float_t size; + }; + + static_assert(sizeof(mdl::EtcObjTeapot) == 0x04, "\"mdl::EtcObjTeapot\" struct should have a size of 0x04"); + + struct EtcObjGrid { + int32_t w; + int32_t h; + int32_t ws; + int32_t hs; + }; + + static_assert(sizeof(mdl::EtcObjGrid) == 0x10, "\"mdl::EtcObjGrid\" struct should have a size of 0x10"); + + struct EtcObjCube { + vec3 size; + bool wire; + }; + + static_assert(sizeof(mdl::EtcObjCube) == 0x10, "\"mdl::EtcObjCube\" struct should have a size of 0x10"); + + struct EtcObjSphere { + float_t radius; + int32_t slices; + int32_t stacks; + bool wire; + }; + + static_assert(sizeof(mdl::EtcObjSphere) == 0x10, "\"mdl::EtcObjSphere\" struct should have a size of 0x10"); + + struct EtcObjPlane { + int32_t w; + int32_t h; + }; + + static_assert(sizeof(mdl::EtcObjPlane) == 0x08, "\"mdl::EtcObjPlane\" struct should have a size of 0x08"); + + struct EtcObjCone { + float_t base; + float_t height; + int32_t slices; + int32_t stacks; + bool wire; + }; + + static_assert(sizeof(mdl::EtcObjCone) == 0x14, "\"mdl::EtcObjCone\" struct should have a size of 0x14"); + + struct EtcObjLine { + vec3 pos[2]; + }; + + static_assert(sizeof(mdl::EtcObjLine) == 0x18, "\"mdl::EtcObjLine\" struct should have a size of 0x18"); + + struct EtcObjCross { + float_t size; + }; + + static_assert(sizeof(mdl::EtcObjCross) == 0x04, "\"mdl::EtcObjCross\" struct should have a size of 0x04"); + + struct EtcObj { + union Data { + EtcObjTeapot teapot; + EtcObjGrid grid; + EtcObjCube cube; + EtcObjSphere sphere; + EtcObjPlane plane; + EtcObjCone cone; + EtcObjLine line; + EtcObjCross cross; + }; + + EtcObjType type; + color4u8_bgra color; + bool fog; + Data data; + GLsizei count; // Added + size_t offset; // Added + + void init(EtcObjType type); + }; + + static_assert(sizeof(mdl::EtcObj) == 0x30, "\"mdl::EtcObj\" struct should have a size of 0x30"); + + typedef void(*UserArgsFunc)(void* data); + + struct UserArgs { + UserArgsFunc func; + void* data; + }; + + static_assert(sizeof(mdl::UserArgs) == 0x10, "\"mdl::UserArgs\" struct should have a size of 0x10"); + + struct ObjTranslucentArgs { + uint32_t count; + ObjSubMeshArgs* sub_mesh[40]; + }; + + static_assert(sizeof(mdl::ObjTranslucentArgs) == 0x148, "\"mdl::ObjTranslucentArgs\" struct should have a size of 0x148"); + + struct ObjData { + union Args { + ObjSubMeshArgs sub_mesh; + EtcObj etc; + UserArgs user; + ObjTranslucentArgs translucent; + }; + + ObjKind kind; + mat4 mat; + float_t view_z; + float_t radius; + Args args; + + void init_etc(const mat4* mat, mdl::EtcObj* etc); + void init_sub_mesh(const mat4* mat, + float_t radius, obj_sub_mesh* sub_mesh, obj_mesh* mesh, obj_material_data* material, + prj::vector* textures, int32_t mat_count, mat4* mats, GLuint vertex_buffer, + GLuint index_buffer, vec4* blend_color, GLuint morph_vertex_buffer, + int32_t instances_count, mat4* instances_mat, + void(FASTCALL* func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data); + void init_translucent(const mat4* mat, ObjTranslucentArgs* translucent); + void init_user(const mat4* mat, UserArgsFunc func, void* data); + }; + + static_assert(sizeof(mdl::ObjData) == 0x838, "\"mdl::ObjData\" struct should have a size of 0x838"); + + struct CullingCheck { + struct Info { + int32_t objects; + int32_t meshes; + int32_t submesh_array; + int pad; + }; + + static_assert(sizeof(mdl::CullingCheck::Info) == 0x10, "\"mdl::CullingCheck::Info\" struct should have a size of 0x10"); + + Info passed; + Info culled; + Info passed_prev; + Info culled_prev; + }; + + static_assert(sizeof(mdl::CullingCheck) == 0x40, "\"mdl::CullingCheck\" struct should have a size of 0x40"); + + struct DispManager { + struct vertex_array { + GLuint vertex_buffer; + GLuint morph_vertex_buffer; + GLuint index_buffer; + int32_t alive_time; + GLuint vertex_array; + bool vertex_attrib_array[16]; + obj_vertex_format vertex_format; + GLsizei size_vertex; + bool compressed; + GLuint vertex_attrib_buffer_binding[16]; + int32_t texcoord_array[2]; + }; + + struct etc_vertex_array { + GLArrayBuffer vertex_buffer; + GLElementArrayBuffer index_buffer; + int32_t alive_time; + GLuint vertex_array; + EtcObj::Data data; + EtcObjType type; + GLsizei count; + size_t offset; + GLsizei wire_count; + size_t wire_offset; + size_t max_vtx; + size_t max_idx; + }; + + mdl::ObjFlags obj_flags; + shadow_type_enum shadow_type; + int32_t field_8; + int32_t field_C; + prj::list obj[mdl::OBJ_TYPE_MAX]; + mdl::CullingCheck culling; + int32_t put_index; + bool show_alpha_center; + bool show_mat_center; + bool object_culling; + bool object_sort; + bool chara_color; + int32_t buff_offset; + int32_t buff_max; + int32_t buff_size; + size_t buff; + morph_struct morph; + int32_t texture_pattern_count; + texture_pattern_struct texture_pattern_array[TEXTURE_PATTERN_COUNT]; + vec4 texture_color_coefficients; + vec4 texture_color_offset; + vec4 texture_specular_coefficients; + vec4 texture_specular_offset; + float_t wet_param; + int32_t texture_transform_count; + texture_transform_struct texture_transform_array[TEXTURE_TRANSFORM_COUNT]; + bool(FASTCALL* culling_func)(obj_bounding_sphere*); + + void add_vertex_array(ObjSubMeshArgs* args); + void add_vertex_array(EtcObj* etc, mat4& mat); + void* alloc_data(int32_t size); + ObjData* alloc_obj_data(ObjKind kind); + mat4* alloc_mat4_array(int32_t count); + void buffer_reset(); + void check_vertex_arrays(); + void draw(mdl::ObjType type, int32_t depth_mask = 0, bool a4 = true); + void draw_translucent(mdl::ObjType type, int32_t alpha); + /*void draw_show_vector(mdl::ObjType type, int32_t show_vector);*/ + void entry_list(ObjType type, ObjData* data); + bool entry_obj(::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, + obj_mesh_index_buffer* obj_index_buf, const mat4* mat, + prj::vector* textures, vec4* blend_color, mat4* bone_mat, ::obj* object_morph, + obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, mat4* instances_mat, + void(*func)(const mdl::ObjSubMeshArgs*), const ObjSubMeshArgs* func_data, + bool enable_bone_mat, bool local = false); + void entry_obj_by_obj(const mat4* mat, + ::obj* obj, prj::vector* textures, obj_mesh_vertex_buffer* obj_vert_buf, + obj_mesh_index_buffer* obj_index_buf, mat4* bone_mat, float_t alpha); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, mat4* bone_mat = 0); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat, int32_t instances_count, mat4* instances_mat, + void(*func)(const ObjSubMeshArgs*), const ObjSubMeshArgs* func_data, bool enable_bone_mat, bool local = false); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, float_t alpha, mat4* bone_mat = 0); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, + float_t r, float_t g, float_t b, float_t a, mat4* bone_mat = 0, bool local = false); + bool entry_obj_by_object_info(const mat4* mat, object_info obj_info, + vec4* blend_color, mat4* bone_mat = 0, bool local = false); + void entry_obj_by_object_info_object_skin(object_info obj_info, + prj::vector* texture_pattern, texture_data_struct* texture_data, float_t alpha, + mat4* matrices, mat4* ex_data_matrices, const mat4* mat, const mat4* global_mat); + void entry_obj_etc(const mat4* mat, EtcObj* etc, bool local = false); + void entry_obj_user(const mat4* mat, UserArgsFunc func, void* data, ObjType type); + GLuint get_vertex_array(const ObjSubMeshArgs* args); + GLuint get_vertex_array(const mdl::EtcObj* etc); + bool get_chara_color(); + ObjFlags get_obj_flags(); + void get_morph(object_info& object, float_t& weight); + int32_t get_obj_count(ObjType type); + shadow_type_enum get_shadow_type(); + void get_texture_color_coeff(vec4& value); + void get_texture_color_offset(vec4& value); + void get_texture_pattern(int32_t& count, texture_pattern_struct*& value); + void get_texture_specular_coeff(vec4& value); + void get_texture_specular_offset(vec4& value); + void get_texture_transform(int32_t& count, texture_transform_struct*& value); + float_t get_wet_param(); + void obj_sort(mat4* view, ObjType type, int32_t compare_func); + void refresh(); + void set_chara_color(bool value = false); + void set_culling_finc(bool(FASTCALL* func)(obj_bounding_sphere*) = 0); + void set_obj_flags(ObjFlags flags = (ObjFlags)0); + void set_morph(object_info object = {}, float_t weight = 0.0f); + void set_shadow_type(shadow_type_enum type = SHADOW_CHARA); + void set_texture_color_coefficients(vec4& value); + void set_texture_color_offset(vec4& value); + void set_texture_pattern(int32_t count = 0, texture_pattern_struct* value = 0); + void set_texture_specular_coefficients(vec4& value); + void set_texture_specular_offset(vec4& value); + void set_texture_transform(int32_t count = 0, texture_transform_struct* value = 0); + void set_wet_param(float_t value = 0.0f); + }; + + static_assert(sizeof(mdl::DispManager) == 0x9D0, "\"mdl::DispManager\" struct should have a size of 0x9D0"); + + extern void disp_manager_patch(); +} + +extern mdl::DispManager* disp_manager; diff --git a/src/DivaGL/mdl/draw_object.cpp b/src/DivaGL/mdl/draw_object.cpp new file mode 100644 index 0000000..c9101e2 --- /dev/null +++ b/src/DivaGL/mdl/draw_object.cpp @@ -0,0 +1,1145 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "draw_object.hpp" +#include "../light_param/light.hpp" +#include "../shader_glsl_ft.hpp" +#include "../texture.hpp" + +static bool draw_object_blend_set( + const mdl::ObjSubMeshArgs* args, obj_material_shader_lighting_type lighting_type); +static bool draw_object_blend_set_check_use_default_blend(int32_t index); +static void draw_object_chara_color_fog_set( + const mdl::ObjSubMeshArgs* args, bool disable_fog); +static void draw_object_material_reset_default(const obj_material_data* mat_data); +static void draw_object_material_reset_reflect(); +static void draw_object_material_set_default( + const mdl::ObjSubMeshArgs* args, bool use_shader); +static void draw_object_material_set_parameter( + const obj_material_data* mat_data); +static void draw_object_material_set_reflect(const mdl::ObjSubMeshArgs* args); +static void draw_object_material_set_uniform(const obj_material_data* mat_data, bool disable_color_l); +static void draw_object_vertex_attrib_reset_default(const mdl::ObjSubMeshArgs* args); +static void draw_object_vertex_attrib_reset_reflect(const mdl::ObjSubMeshArgs* args); +static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* args); +static void draw_object_vertex_attrib_set_reflect(const mdl::ObjSubMeshArgs* args); + +static bool(FASTCALL* use_shader_get)() = (bool(FASTCALL*)())0x0000000140440E30; + +namespace mdl { + void draw(obj_primitive_type primitive_type, uint32_t count, + uint16_t start, uint16_t end, obj_index_format index_format, size_t indices) { + GLenum mesh_draw_mode[] = { + GL_ZERO, //GL_POINTS, + GL_LINES, + GL_LINE_STRIP, + GL_LINE_LOOP, + GL_TRIANGLES, + GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, + GL_ZERO, //GL_QUADS, + GL_ZERO, //GL_QUAD_STRIP, + GL_ZERO, //GL_POLYGON, + }; + + GLenum mesh_indices_type[] = { + GL_ZERO, + GL_UNSIGNED_SHORT, + GL_UNSIGNED_INT, + }; + + rctx->obj_batch_ubo.WriteMemory(rctx->obj_batch); + if (primitive_type == OBJ_PRIMITIVE_TRIANGLE_STRIP && index_format == OBJ_INDEX_U16) + shaders_ft.draw_range_elements(GL_TRIANGLE_STRIP, + start, end, count, GL_UNSIGNED_SHORT, (void*)indices); + else + shaders_ft.draw_elements(mesh_draw_mode[primitive_type], + count, mesh_indices_type[index_format], (void*)indices); + + draw_state->stats.draw_count += count; + if (primitive_type == OBJ_PRIMITIVE_TRIANGLES) + draw_state->stats.draw_triangle_count += count / 3; + else if (primitive_type == OBJ_PRIMITIVE_TRIANGLE_STRIP) + draw_state->stats.draw_triangle_count += count - 2; + } + + void draw_etc_obj(mdl::EtcObj* etc) { + switch (etc->type) { + case mdl::ETC_OBJ_TEAPOT: + case mdl::ETC_OBJ_GRID: + case mdl::ETC_OBJ_CUBE: + case mdl::ETC_OBJ_SPHERE: + case mdl::ETC_OBJ_PLANE: + case mdl::ETC_OBJ_CONE: + case mdl::ETC_OBJ_LINE: + case mdl::ETC_OBJ_CROSS: + break; + default: + return; + } + + if (!etc->count) + return; + + GLuint vao = disp_manager->get_vertex_array(etc); + if (!vao) + return; + + vec4 g_material_state_diffuse = rctx->obj_batch.g_material_state_diffuse; + vec4 g_material_state_ambient = rctx->obj_batch.g_material_state_ambient; + vec4 g_material_state_specular = rctx->obj_batch.g_material_state_specular; + vec4 g_material_state_emission = rctx->obj_batch.g_material_state_emission; + vec4 g_material_state_shininess = rctx->obj_batch.g_material_state_shininess; + + vec4 color = etc->color; + + vec4 ambient; + *(vec3*)&ambient = *(vec3*)&color * 0.5f; + ambient.w = color.w; + + rctx->obj_batch.g_material_state_diffuse = color; + rctx->obj_batch.g_material_state_ambient = ambient; + rctx->obj_batch.g_material_state_specular = { 0.0f, 0.0f, 0.0f, 1.0f }; + rctx->obj_batch.g_material_state_emission = { 0.0f, 0.0f, 0.0f, 1.0f }; + rctx->obj_batch.g_material_state_shininess = { 0.0f, 0.0f, 0.0f, 1.0f }; + + rctx->obj_batch.g_blend_color = color; + + gl_state_bind_vertex_array(vao); + rctx->obj_batch_ubo.WriteMemory(rctx->obj_batch); + + shaders_ft.set(SHADER_FT_SIMPLE); + switch (etc->type) { + case mdl::ETC_OBJ_TEAPOT: + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, 0); + break; + case mdl::ETC_OBJ_GRID: + shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + break; + case mdl::ETC_OBJ_CUBE: + if (etc->data.sphere.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + break; + case mdl::ETC_OBJ_SPHERE: + if (etc->data.sphere.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + break; + case mdl::ETC_OBJ_PLANE: + shaders_ft.draw_arrays(GL_TRIANGLES, 0, etc->count); + break; + case mdl::ETC_OBJ_CONE: + if (etc->data.cone.wire) + shaders_ft.draw_elements(GL_LINES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + else + shaders_ft.draw_elements(GL_TRIANGLES, etc->count, GL_UNSIGNED_INT, (void*)etc->offset); + break; + case mdl::ETC_OBJ_LINE: + shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + break; + case mdl::ETC_OBJ_CROSS: + shaders_ft.draw_arrays(GL_LINES, 0, etc->count); + break; + } + shader_glsl::unbind(); + uniform_value_reset(); + + rctx->obj_batch.g_material_state_diffuse = g_material_state_diffuse; + rctx->obj_batch.g_material_state_ambient = g_material_state_ambient; + rctx->obj_batch.g_material_state_specular = g_material_state_specular; + rctx->obj_batch.g_material_state_emission = g_material_state_emission; + rctx->obj_batch.g_material_state_shininess = g_material_state_shininess; + + rctx->obj_batch.g_blend_color = 1.0f; + } + + void draw_sub_mesh(const ObjSubMeshArgs* args, const mat4* model, + void(*func)(const ObjSubMeshArgs* args)) { + GLuint vao = disp_manager->get_vertex_array(args); + if (!vao) + return; + + if (args->mats) { + const mat4* mats = args->mats; + rctx->obj_batch.set_g_joint(mats[0]); + + vec4* g_joint_transforms = rctx->obj_skinning.g_joint_transforms; + + mat4 mat; + for (int32_t i = 0; i < args->mat_count; i++, mats++, g_joint_transforms += 3) { + mat4_transpose(mats, &mat); + g_joint_transforms[0] = mat.row0; + g_joint_transforms[1] = mat.row1; + g_joint_transforms[2] = mat.row2; + } + + rctx->obj_skinning_ubo.WriteMemory(rctx->obj_skinning); + + rctx->obj_batch.set_transforms(mat4_identity, rctx->view_mat, rctx->proj_mat); + + uniform->arr[U_BONE_MAT] = 1; + gl_state_bind_vertex_array(vao); + func(args); + uniform->arr[U_BONE_MAT] = 0; + } + else { + mat4 mat; + if (args->mesh->attrib.m.billboard) + model_mat_face_camera_view(&rctx->view_mat, model, &mat); + else if (args->mesh->attrib.m.billboard_y_axis) + model_mat_face_camera_position(&rctx->view_mat, model, &mat); + else + mat = *model; + + uniform->arr[U_BONE_MAT] = 0; + gl_state_bind_vertex_array(vao); + if (func != draw_sub_mesh_default || !args->instances_count) { + draw_object_model_mat_load(mat); + func(args); + } + else + draw_sub_mesh_default_instanced(args, &mat); + uniform->arr[U_BONE_MAT] = 0; + } + } + + /*void draw_sub_mesh_show_vector( + const ObjSubMeshArgs* args, mat4* model, int32_t show_vector) { + return; + }*/ + + void draw_sub_mesh_default(const ObjSubMeshArgs* args) { + if (args->set_blend_color) { + rctx->obj_batch.g_blend_color = args->blend_color; + rctx->obj_batch.g_offset_color = 0.0f; + } + + if (!args->func) + draw_object_vertex_attrib_set_default(args); + + draw_object_material_set_default(args, use_shader_get()); + + const obj_sub_mesh* sub_mesh = args->sub_mesh; + draw( + sub_mesh->primitive_type, + sub_mesh->num_index, + sub_mesh->first_index, + sub_mesh->last_index, + sub_mesh->index_format, + sub_mesh->index_offset); + + draw_object_material_reset_default(args->material); + if (!args->func) + draw_object_vertex_attrib_reset_default(args); + + if (args->set_blend_color) { + rctx->obj_batch.g_blend_color = 1.0f; + rctx->obj_batch.g_offset_color = 0.0f; + } + + draw_state->stats.object_draw_count++; + } + + void draw_sub_mesh_default_instanced( + const ObjSubMeshArgs* args, const mat4* mat) { + if (args->set_blend_color) { + rctx->obj_batch.g_blend_color = args->blend_color; + rctx->obj_batch.g_offset_color = 0.0f; + } + + if (!args->func) + draw_object_vertex_attrib_set_default(args); + + draw_object_material_set_default(args, use_shader_get()); + + const obj_sub_mesh* sub_mesh = args->sub_mesh; + const mat4* instances_mat = args->instances_mat; + mat4 _mat; + for (int32_t i = args->instances_count; i >= 0; i--, instances_mat++) { + mat4_mul(instances_mat, mat, &_mat); + draw_object_model_mat_load(_mat); + draw( + sub_mesh->primitive_type, + sub_mesh->num_index, + sub_mesh->first_index, + sub_mesh->last_index, + sub_mesh->index_format, + sub_mesh->index_offset); + } + + draw_object_material_reset_default(args->material); + if (!args->func) + draw_object_vertex_attrib_reset_default(args); + + if (args->set_blend_color) { + rctx->obj_batch.g_blend_color = 1.0f; + rctx->obj_batch.g_offset_color = 0.0f; + } + + draw_state->stats.object_draw_count++; + } + + void draw_sub_mesh_sss(const ObjSubMeshArgs* args) { + obj_material_attrib_member attrib = args->material->material.attrib.m; + uniform->arr[U_ALPHA_TEST] = (!attrib.flag_28 && (args->blend_color.w < 1.0f + || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through + || args->sub_mesh->attrib.m.transparent) + || attrib.punch_through) ? 1 : 0; + + uniform->arr[U26] = 1; + bool aniso = false; + const obj_material_data* material = args->material; + switch (material->material.shader.index) { + case SHADER_FT_CLOTH: + if (!render_manager->npr_param && material->material.color.ambient.w < 1.0f + && material->material.shader_info.m.aniso_direction == OBJ_MATERIAL_ANISO_DIRECTION_NORMAL) + aniso = true; + break; + case SHADER_FT_TIGHTS: + if (!render_manager->npr_param) + aniso = true; + break; + //case SHADER_FT_EYEBALL: + case SHADER_FT_GLASEYE: + uniform->arr[U26] = 0; + aniso = true; + break; + case SHADER_FT_SKIN: + aniso = true; + break; + } + + if (aniso) { + rctx->obj_batch.g_sss_param = { 0.0f, 0.0f, 0.0f, 0.5f }; + uniform->arr[U37] = 1; + } + else { + const vec4& sss_param = sss_data_get()->param; + rctx->obj_batch.g_sss_param = { sss_param.x, sss_param.y, sss_param.z, 0.5f }; + uniform->arr[U37] = 0; + } + draw_sub_mesh_default(args); + } + + void draw_sub_mesh_reflect(const ObjSubMeshArgs* args) { + const obj_material_data* material = args->material; + draw_object_vertex_attrib_set_reflect(args); + obj_material_shader_lighting_type lighting_type + = material->material.shader_info.get_lighting_type(); + bool disable_fog = draw_object_blend_set(args, lighting_type); + draw_object_chara_color_fog_set(args, disable_fog); + draw_object_material_set_reflect(args); + + const obj_sub_mesh* sub_mesh = args->sub_mesh; + if (sub_mesh->index_format != OBJ_INDEX_U8) + draw( + sub_mesh->primitive_type, + sub_mesh->num_index, + sub_mesh->first_index, + sub_mesh->last_index, + sub_mesh->index_format, + sub_mesh->index_offset); + + draw_object_material_reset_reflect(); + draw_object_vertex_attrib_reset_reflect(args); + uniform_value_reset(); + + draw_state->stats.object_reflect_draw_count++; + } + + void draw_sub_mesh_reflect_reflect_map(const ObjSubMeshArgs* args) { + draw_object_vertex_attrib_set_reflect(args); + draw_object_material_set_reflect(args); + + const obj_sub_mesh* sub_mesh = args->sub_mesh; + if (sub_mesh->index_format != OBJ_INDEX_U8) + draw( + sub_mesh->primitive_type, + sub_mesh->num_index, + sub_mesh->first_index, + sub_mesh->last_index, + sub_mesh->index_format, + sub_mesh->index_offset); + + draw_object_material_reset_reflect(); + draw_object_vertex_attrib_reset_reflect(args); + + draw_state->stats.object_reflect_draw_count++; + } + + void draw_sub_mesh_shadow(const ObjSubMeshArgs* args) { + obj_material_attrib_member attrib = args->material->material.attrib.m; + if (!attrib.flag_28 && (args->blend_color.w < 1.0f + || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through + || args->sub_mesh->attrib.m.transparent) + || attrib.punch_through) { + uniform->arr[U_ALPHA_TEST] = 1; + draw_sub_mesh_translucent(args); + } + else { + uniform->arr[U_ALPHA_TEST] = 0; + draw_sub_mesh_translucent(args); + } + } + + void draw_sub_mesh_translucent(const ObjSubMeshArgs* args) { + const obj_material_data* material = args->material; + const prj::vector* textures = args->textures; + if (draw_state->shader_index != -1) { + rctx->obj_batch.g_material_state_emission = material->material.color.emission; + draw_object_material_set_uniform(material, false); + if (material->material.attrib.m.alpha_texture) + uniform->arr[U_TEXTURE_COUNT] = 0; + rctx->obj_batch.g_texture_blend = { (float_t)uniform->arr[U_TEXTURE_BLEND], 0.0f, 0.0f, 0.0f }; + shaders_ft.set(draw_state->shader_index); + } + + draw_object_vertex_attrib_set_default(args); + if (args->material->material.attrib.m.double_sided) + gl_state_disable_cull_face(); + + GLuint tex_id = -1; + int32_t tex_index = 0; + if (material->material.attrib.m.alpha_texture) { + const obj_material_texture_data* texdata = material->material.texdata; + uint32_t texture_id = -1; + if (!material->material.shader_compo.m.transparency) { + for (int32_t i = 0; i < 8; i++, texdata++) + if (texdata->shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) { + texture_id = texdata->tex_index; + break; + } + tex_index = 0; + } + else { + for (int32_t i = 0; i < 8; i++, texdata++) + if (texdata->shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_TRANSPARENCY) { + if (texdata->attrib.m.flag_29) + texture_id = texdata->tex_index; + break; + } + tex_index = 3; + } + + if (texture_id != -1) { + texture_id &= 0xFFFFF; + for (int32_t j = 0; j < args->texture_pattern_count; j++) + if (args->texture_pattern_array[j].src == tex_index) { + texture* tex = texture_handler_get_texture(args->texture_pattern_array[j].dst); + if (tex) + tex_id = tex->tex; + break; + } + + if (tex_id == -1) + tex_id = (*textures)[texdata->tex_index >> 20]; + + if (tex_id == -1) + tex_id = 0; + + gl_state_active_bind_texture_2d(tex_index, tex_id); + + int32_t wrap_s; + if (texdata->attrib.m.mirror_u) + wrap_s = 2; + else if (texdata->attrib.m.repeat_u) + wrap_s = 1; + else + wrap_s = 0; + + int32_t wrap_t; + if (texdata->attrib.m.mirror_v) + wrap_t = 2; + else if (texdata->attrib.m.repeat_v) + wrap_t = 1; + else + wrap_t = 0; + + texture* tex = texture_handler_get_texture(texture_id); + gl_state_bind_sampler(tex_index, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + + (tex->max_mipmap_level > 0 ? 1 : 0)]); + } + } + + const obj_sub_mesh* sub_mesh = args->sub_mesh; + if (sub_mesh->index_format != OBJ_INDEX_U8) + draw( + sub_mesh->primitive_type, + sub_mesh->num_index, + sub_mesh->first_index, + sub_mesh->last_index, + sub_mesh->index_format, + sub_mesh->index_offset); + + if (tex_id != -1) + gl_state_active_bind_texture_2d(tex_index, rctx->empty_texture_2d); + + gl_state_enable_cull_face(); + draw_object_vertex_attrib_reset_default(args); + + if (draw_state->shader_index != -1) + uniform_value_reset(); + + draw_state->stats.object_translucent_draw_count++; + } +} + +inline void draw_object_model_mat_load(const mat4& mat) { + rctx->obj_batch.set_transforms(mat, rctx->view_mat, rctx->proj_mat); + rctx->obj_batch.set_g_joint(mat); +} + +inline void model_mat_face_camera_position(const mat4* view, const mat4* src, mat4* dst) { + mat4 mat; + mat4_invert_fast(view, &mat); + + vec3 dir = vec3::normalize(*(vec3*)&mat.row3 - *(vec3*)&src->row3); + + vec3 x_rot; + vec3 y_rot; + vec3 z_rot; + + y_rot = *(vec3*)&src->row1; + x_rot = vec3::normalize(vec3::cross(y_rot, dir)); + z_rot = vec3::cross(x_rot, y_rot); + + *(vec3*)&dst->row0 = x_rot; + *(vec3*)&dst->row1 = y_rot; + *(vec3*)&dst->row2 = z_rot; + *(vec3*)&dst->row3 = *(vec3*)&src->row3; + dst->row0.w = 0.0f; + dst->row1.w = 0.0f; + dst->row2.w = 0.0f; + dst->row3.w = 1.0f; +} + +inline void model_mat_face_camera_view(const mat4* view, const mat4* src, mat4* dst) { + mat3 mat; + mat4_to_mat3(view, &mat); + mat3_invert(&mat, &mat); + mat4_from_mat3(&mat, dst); + mat4_mul(dst, src, dst); +} + +static bool draw_object_blend_set( + const mdl::ObjSubMeshArgs* args, obj_material_shader_lighting_type lighting_type) { + static const GLenum blend_factor_table[] = { + GL_ZERO, + GL_ONE, + GL_SRC_COLOR, + GL_ONE_MINUS_SRC_COLOR, + GL_SRC_ALPHA, + GL_ONE_MINUS_SRC_ALPHA, + GL_DST_ALPHA, + GL_ONE_MINUS_DST_ALPHA, + GL_DST_COLOR, + GL_ONE_MINUS_DST_COLOR, + GL_SRC_ALPHA_SATURATE, + GL_ZERO, + GL_ZERO, + GL_ZERO, + GL_ZERO, + GL_ZERO, + }; + + const obj_material_data* material = args->material; + obj_material_attrib_member attrib = material->material.attrib.m; + if ((!attrib.alpha_texture && !attrib.alpha_material) || attrib.punch_through) + return false; + + GLenum src_blend_factor = blend_factor_table[attrib.src_blend_factor]; + GLenum dst_blend_factor = blend_factor_table[attrib.dst_blend_factor]; + if (args->chara_color) { + light_set* set = &light_set_data[LIGHT_SET_MAIN]; + light_data* chara_color = &set->lights[LIGHT_CHARA_COLOR]; + vec4 specular; + chara_color->get_specular(specular); + if (specular.w >= 4.0f && chara_color->get_type() == LIGHT_PARALLEL + && (src_blend_factor != GL_ONE || dst_blend_factor)) { + int32_t shader_index = draw_state->shader_index; + if (shader_index == -1) { + shader_index = material->material.shader.index; + if (shader_index == SHADER_FT_BLINN) { + if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_CONSTANT) + shader_index = SHADER_FT_CONSTANT; + if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_LAMBERT) + shader_index = SHADER_FT_LAMBERT; + } + } + + if (draw_object_blend_set_check_use_default_blend(shader_index)) { + src_blend_factor = GL_SRC_ALPHA; + dst_blend_factor = GL_ONE_MINUS_SRC_ALPHA; + } + } + } + gl_state_set_blend_func(src_blend_factor, dst_blend_factor); + return dst_blend_factor == GL_ONE; +} + +static bool draw_object_blend_set_check_use_default_blend(int32_t index) { + bool use_default_blend[] = { + false, false, true, false, true, false, false, true, true, true, false, false, + false, true, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false + }; + + if (index >= 0 && index < SHADER_FT_MAX) + return use_default_blend[index]; + return false; +} + +static void draw_object_chara_color_fog_set(const mdl::ObjSubMeshArgs* args, bool disable_fog) { + uniform->arr[U_CHARA_COLOR] = 0; + if (args->chara_color) { + light_set* set = &light_set_data[LIGHT_SET_MAIN]; + light_data* chara_color = &set->lights[LIGHT_CHARA_COLOR]; + vec4 specular; + chara_color->get_specular(specular); + if (specular.w > 0.0f && chara_color->get_type() == LIGHT_PARALLEL) + uniform->arr[U_CHARA_COLOR] = 1; + } + + obj_material_attrib_member attrib = args->material->material.attrib.m; + if (!attrib.no_fog && !disable_fog) { + if (attrib.has_fog_height) + uniform->arr[U_FOG_HEIGHT] = 2 + attrib.fog_height; + else + uniform->arr[U_FOG_HEIGHT] = 1; + uniform->arr[U_FOG] = draw_state->fog_height ? 2 : 1; + } +} + +static void draw_object_material_reset_default(const obj_material_data* mat_data) { + if (mat_data) { + gl_state_enable_cull_face(); + obj_material_attrib_member attrib = mat_data->material.attrib.m; + if ((attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through) + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + uniform_value_reset(); +} + +static void draw_object_material_reset_reflect() { + gl_state_active_bind_texture_2d(0, rctx->empty_texture_2d); + gl_state_enable_cull_face(); + uniform_value_reset(); +} + +static void draw_object_material_set_default(const mdl::ObjSubMeshArgs* args, bool use_shader) { + const prj::vector* textures = args->textures; + const obj_material_data* material = args->material; + obj_material_shader_lighting_type lighting_type = + material->material.shader_info.get_lighting_type(); + bool disable_fog = draw_object_blend_set(args, lighting_type); + draw_object_material_set_uniform(material, false); + if (!draw_state->light) + uniform->arr[U_LIGHT_0] = 0; + else if (args->self_shadow) + uniform->arr[U_LIGHT_0] = 1; + else + uniform->arr[U_LIGHT_0] = args->sub_mesh->attrib.m.recieve_shadow ? 1 : 0; + uniform->arr[U_SHADOW] = 0; + uniform->arr[U_SELF_SHADOW] = draw_state->self_shadow ? 1 : 0; + + const obj_material_texture_data* texdata = material->material.texdata; + uniform->arr[U_SHADOW] = args->shadow > SHADOW_CHARA; + for (int32_t i = 0, j = 0; i < 8; i++, texdata++) { + if (texdata->tex_index == -1) + continue; + + GLuint tex_id = -1; + uint32_t texture_id = texdata->tex_index & 0xFFFFF; + for (int32_t j = 0; j < args->texture_pattern_count; j++) + if (args->texture_pattern_array[j].src == texture_id) { + texture* tex = texture_handler_get_texture(args->texture_pattern_array[j].dst); + if (tex) + tex_id = tex->tex; + break; + } + + if (tex_id == -1) + tex_id = (*textures)[texdata->tex_index >> 20]; + + if (tex_id == -1) + continue; + + int32_t tex_index = obj_material_texture_type_get_texture_index(texdata->shader_info.m.tex_type, j); + if (tex_index < 0) + continue; + + obj_material_texture_type tex_type = texdata->shader_info.m.tex_type; + if (tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + j++; + + if (texdata->attrib.m.flag_29) { + switch (tex_type) { + case OBJ_MATERIAL_TEXTURE_NORMAL: + uniform->arr[U_NORMAL] = 0; + break; + case OBJ_MATERIAL_TEXTURE_SPECULAR: + uniform->arr[U_SPECULAR] = 0; + break; + case OBJ_MATERIAL_TEXTURE_TRANSLUCENCY: + uniform->arr[U_TRANSLUCENCY] = 0; + break; + case OBJ_MATERIAL_TEXTURE_TRANSPARENCY: + uniform->arr[U_TRANSPARENCY] = 0; + break; + } + continue; + } + + if (tex_type == OBJ_MATERIAL_TEXTURE_ENVIRONMENT_CUBE) { + gl_state_active_bind_texture_cube_map(tex_index, tex_id); + gl_state_bind_sampler(tex_index, 0); + } + else { + gl_state_active_bind_texture_2d(tex_index, tex_id); + + int32_t wrap_s; + if (texdata->attrib.m.mirror_u) + wrap_s = 2; + else if (texdata->attrib.m.repeat_u) + wrap_s = 1; + else + wrap_s = 0; + + int32_t wrap_t; + if (texdata->attrib.m.mirror_v) + wrap_t = 2; + else if (texdata->attrib.m.repeat_v) + wrap_t = 1; + else + wrap_t = 0; + + texture* tex = texture_handler_get_texture(texture_id); + gl_state_bind_sampler(tex_index, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + + (tex->max_mipmap_level > 0 ? 1 : 0)]); + } + + if (material->material.shader.index == SHADER_FT_SKY) { + uniform_name uni_type = U_TEX_0_TYPE; + if (tex_index == 1) + uni_type = U_TEX_1_TYPE; + + texture* tex = texture_handler_get_texture(texture_id); + if (!tex) + uniform->arr[uni_type] = 1; + else if (tex->internal_format == GL_COMPRESSED_RED_RGTC1_EXT) + uniform->arr[uni_type] = 3; + else if (tex->internal_format == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) + uniform->arr[uni_type] = 2; + else + uniform->arr[uni_type] = 1; + } + + if (tex_index >= 0 && tex_index <= 1) + uniform->arr[U_TEXTURE_BLEND] = texdata->attrib.get_blend(); + } + + if (material->material.attrib.m.double_sided) { + gl_state_disable_cull_face(); + if (!material->material.attrib.m.normal_dir_light) + uniform->arr[U0B] = 1; + } + + draw_object_chara_color_fog_set(args, disable_fog); + + rctx->obj_batch.g_material_state_ambient = material->material.color.ambient; + if (!sss_data_get()->enable) + rctx->obj_batch.g_material_state_ambient.w = 1.0f; + rctx->obj_batch.g_material_state_diffuse = material->material.color.diffuse; + rctx->obj_batch.g_material_state_emission = material->material.color.emission; + + float_t line_light; + if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_PHONG) { + const vec4& specular = material->material.color.specular; + rctx->obj_batch.g_material_state_specular = specular; + + float_t luma = vec3::dot(*(vec3*)&specular, { 0.30f, 0.59f, 0.11f }); + if (luma >= 0.01f || args->texture_color_coefficients.w >= 0.1f) + uniform->arr[U_SPECULAR_IBL] = 1; + else + uniform->arr[U_SPECULAR_IBL] = 0; + + if (!material->material.shader_info.m.fresnel_type) + uniform->arr[U_TRANSLUCENCY] = 0; + + line_light = (float_t)material->material.shader_info.m.line_light * (float_t)(1.0 / 9.0); + } + else + line_light = 0.0; + + if (!use_shader) + shaders_ft.set(SHADER_FT_SIMPLE); + else if (draw_state->shader_index != -1) + shaders_ft.set(draw_state->shader_index); + else if (material->material.shader.index != -1) { + if (material->material.shader.index != SHADER_FT_BLINN) + shaders_ft.set(material->material.shader.index); + else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_LAMBERT) + shaders_ft.set(SHADER_FT_LAMBERT); + else if (lighting_type == OBJ_MATERIAL_SHADER_LIGHTING_PHONG) + shaders_ft.set(SHADER_FT_BLINN); + else + shaders_ft.set(SHADER_FT_CONSTANT); + } + else + shaders_ft.set(SHADER_FT_CONSTANT); + + rctx->obj_batch.g_texture_blend = { (float_t)uniform->arr[U_TEXTURE_BLEND], 0.0f, 0.0f, 0.0f }; + if (lighting_type != OBJ_MATERIAL_SHADER_LIGHTING_CONSTANT) { + float_t material_shininess; + if (material->material.shader.index == SHADER_FT_GLASEYE/*SHADER_FT_EYEBALL*/) + material_shininess = 10.0f; + else { + material_shininess = (material->material.color.shininess - 16.0f) * (float_t)(1.0 / 112.0); + material_shininess = max_def(material_shininess, 0.0f); + } + rctx->obj_batch.g_material_state_shininess = { material_shininess, 0.0f, 0.0f, 1.0f }; + + float_t fresnel = (float_t)material->material.shader_info.m.fresnel_type; + if (fresnel > 9.0f) + fresnel = 9.0f; + else if (fresnel == 0.0f) + fresnel = draw_state->fresnel; + fresnel = (fresnel - 1.0f) * 0.12f * 0.82f; + + rctx->obj_batch.g_fresnel_coefficients = { fresnel, 0.18f, line_light, 0.0f }; + + float_t shininess = max_def(material->material.color.shininess, 1.0f); + rctx->obj_batch.g_shininess = { shininess, 0.0f, 0.0f, 0.0f }; + + switch (material->material.shader.index) { + case SHADER_FT_SKIN: { + vec4 texture_color_coefficients = args->texture_color_coefficients; + vec4 texture_color_offset = args->texture_color_offset; + vec4 texture_specular_coefficients = args->texture_specular_coefficients; + vec4 texture_specular_offset = args->texture_specular_offset; + + texture_color_coefficients.w *= 0.015f; + texture_specular_coefficients.w *= 0.015f; + + rctx->obj_batch.g_texture_color_coefficients = texture_color_coefficients; + rctx->obj_batch.g_texture_color_offset = texture_color_offset; + rctx->obj_batch.g_texture_specular_coefficients = texture_specular_coefficients; + rctx->obj_batch.g_texture_specular_offset = texture_specular_offset; + } break; + case SHADER_FT_HAIR: + case SHADER_FT_CLOTH: + case SHADER_FT_TIGHTS: + rctx->obj_batch.g_texture_color_coefficients = { + 1.0f - args->texture_color_coefficients.w * 0.4f, + 0.0f, 0.0f, args->texture_color_coefficients.w * 0.02f }; + break; + } + } + + draw_object_material_set_parameter(material); +} + +static void draw_object_material_set_parameter(const obj_material_data* mat_data) { + float_t bump_depth; + float_t intensity; + float_t reflect_uv_scale; + float_t refract_uv_scale; + float_t inv_bump_depth; + if (draw_state->use_global_material) { + bump_depth = draw_state->bump_depth; + intensity = draw_state->intensity; + reflect_uv_scale = draw_state->reflect_uv_scale; + refract_uv_scale = draw_state->refract_uv_scale; + inv_bump_depth = (1.0f - draw_state->bump_depth) * 64.0f + 1.0f; + + vec4 specular = mat_data->material.color.specular; + specular.w = draw_state->reflectivity; + rctx->obj_batch.g_material_state_specular = specular; + } + else { + bump_depth = mat_data->material.bump_depth; + reflect_uv_scale = 0.1f; + intensity = mat_data->material.color.intensity; + refract_uv_scale = 0.1f; + inv_bump_depth = (1.0f - bump_depth) * 256.0f + 1.0f; + } + + rctx->obj_batch.g_bump_depth = { inv_bump_depth, bump_depth, 0.0f, 0.0f }; + rctx->obj_batch.g_intensity = { intensity, max_def(intensity, 1.0f), intensity * 25.5f, 1.0f }; + rctx->obj_batch.g_reflect_uv_scale = { + reflect_uv_scale, reflect_uv_scale, refract_uv_scale, refract_uv_scale }; +} + +static void draw_object_material_set_reflect(const mdl::ObjSubMeshArgs* args) { + const obj_material_data* material = args->material; + const prj::vector* textures = args->textures; + if (material->material.attrib.m.double_sided) + gl_state_disable_cull_face(); + + const obj_material_texture_data* texdata = material->material.texdata; + for (int32_t i = 0; i < 1; i++, texdata++) { + uint32_t texture_id = texdata->tex_index & 0xFFFFF; + if (texdata->tex_index == -1) + break; + + GLuint tex_id = -1; + for (int32_t j = 0; j < args->texture_pattern_count; j++) + if (args->texture_pattern_array[j].src == texture_id) { + texture* tex = texture_handler_get_texture(args->texture_pattern_array[j].dst); + if (tex) + tex_id = tex->tex; + break; + } + + if (tex_id == -1) + tex_id = (*textures)[texdata->tex_index >> 20]; + + if (tex_id == -1) + tex_id = 0; + + gl_state_active_bind_texture_2d(i, tex_id); + + int32_t wrap_s; + if (texdata->attrib.m.mirror_u) + wrap_s = 2; + else if (texdata->attrib.m.repeat_u) + wrap_s = 1; + else + wrap_s = 0; + + int32_t wrap_t; + if (texdata->attrib.m.mirror_v) + wrap_t = 2; + else if (texdata->attrib.m.repeat_v) + wrap_t = 1; + else + wrap_t = 0; + + texture* tex = texture_handler_get_texture(texture_id); + gl_state_bind_sampler(i, rctx->samplers[(wrap_t * 3 + wrap_s) * 2 + + (tex->max_mipmap_level > 0 ? 1 : 0)]); + } + + vec4 ambient; + vec4 diffuse; + vec4 emission; + vec4 specular; + if (material->material.shader.index == -1) { + ambient = 1.0f; + diffuse = material->material.color.diffuse; + emission = 1.0f; + specular = material->material.color.specular; + } + else { + ambient = material->material.color.ambient; + diffuse = material->material.color.diffuse; + emission = material->material.color.emission; + specular = material->material.color.specular; + } + + draw_object_material_set_uniform(material, true); + rctx->obj_batch.g_texture_blend = { (float_t)uniform->arr[U_TEXTURE_BLEND], 0.0f, 0.0f, 0.0f }; + shaders_ft.set(draw_state->shader_index); + rctx->obj_batch.g_material_state_ambient = ambient; + rctx->obj_batch.g_material_state_diffuse = diffuse; + rctx->obj_batch.g_material_state_emission = emission; + rctx->obj_batch.g_material_state_specular = specular; + draw_object_material_set_parameter(args->material); +} + +static void draw_object_material_set_uniform(const obj_material_data* mat_data, bool disable_color_l) { + obj_shader_compo_member shader_compo = mat_data->material.shader_compo.m; + obj_material_shader_attrib_member shader_info = mat_data->material.shader_info.m; + + if (disable_color_l) { + if (shader_compo.color) + shader_compo.color_l1 = 0; + shader_compo.color_l2 = 0; + } + + int32_t v4 = 0; + if (shader_compo.color) { + if (!shader_compo.color_l2) + if (shader_compo.color_l1) { + uniform->arr[U_TEXTURE_COUNT] = 2; + v4 = 3; + } + else { + uniform->arr[U_TEXTURE_COUNT] = 1; + v4 = 1; + } + } + else if (shader_compo.color_l1 && !shader_compo.color_l2) { + uniform->arr[U_TEXTURE_COUNT] = 1; + v4 = 1; + } + else + uniform->arr[U_TEXTURE_COUNT] = 0; + + if (shader_compo.normal_01) + uniform->arr[U_NORMAL] = 1; + if (shader_compo.specular) + uniform->arr[U_SPECULAR] = 1; + if (shader_compo.transparency) { + uniform->arr[U_TRANSPARENCY] = 1; + v4 |= 2; + } + if (shader_compo.translucency) { + uniform->arr[U_TRANSLUCENCY] = 1; + v4 |= 2; + } + if (shader_compo.override_ibl) + uniform->arr[U_ENV_MAP] = 1; + + if (shader_info.aniso_direction != OBJ_MATERIAL_ANISO_DIRECTION_NORMAL) + uniform->arr[U_ANISO] = shader_info.aniso_direction; + + if (v4 == 1) + uniform->arr[U45] = 0; + else if (v4 == 2 || v4 == 3) + uniform->arr[U45] = 1; +} + +static void draw_object_vertex_attrib_reset_default(const mdl::ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + obj_vertex_format vertex_format = mesh->vertex_format; + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + uniform->arr[U_BONE_MAT] = 0; + + if (args->morph_vertex_buffer) { + uniform->arr[U_MORPH] = 0; + uniform->arr[U_MORPH_COLOR] = 0; + } + + /*if (args->instances_count) + uniform->arr[U_INSTANCE] = 0;*/ + + gl_state_active_texture(0); +} + +static void draw_object_vertex_attrib_reset_reflect(const mdl::ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + obj_vertex_format vertex_format = mesh->vertex_format; + + if ((vertex_format & OBJ_VERTEX_BONE_DATA) == OBJ_VERTEX_BONE_DATA) + uniform->arr[U_BONE_MAT] = 0; + + if (args->morph_vertex_buffer) { + uniform->arr[U_MORPH] = 0; + uniform->arr[U_MORPH_COLOR] = 0; + } + + gl_state_active_texture(0); +} + +static void draw_object_vertex_attrib_set_default(const mdl::ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + obj_vertex_format vertex_format = mesh->vertex_format; + + bool texcoord_mat_set[4] = { false }; + const obj_material_data* material = args->material; + for (int32_t i = 0, j = 0, l = 0; i < 4; i++) { + if (material->material.texdata[i].tex_index == -1) + continue; + + int32_t texcoord_index = obj_material_texture_type_get_texcoord_index( + material->material.texdata[i].shader_info.m.tex_type, j); + if (texcoord_index < 0) + continue; + + if (material->material.texdata[i].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + j++; + + l++; + + if (texcoord_mat_set[texcoord_index]) + continue; + + uint32_t texture_id = material->material.texdata[i].tex_index & 0xFFFFF; + + rctx->obj_batch.set_g_texcoord_transforms(texcoord_index, + material->material.texdata[i].tex_coord_mat); + if (material->material.texdata[i].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + for (int32_t k = 0; k < args->texture_transform_count; k++) + if (args->texture_transform_array[k].id == texture_id) { + rctx->obj_batch.set_g_texcoord_transforms(texcoord_index, + args->texture_transform_array[k].mat); + texcoord_mat_set[texcoord_index] = true; + break; + } + } + + if (vertex_format & OBJ_VERTEX_BONE_DATA) + uniform->arr[U_BONE_MAT] = 1; + else + uniform->arr[U_BONE_MAT] = 0; + + if (args->morph_vertex_buffer) { + uniform->arr[U_MORPH] = 1; + + if (vertex_format & OBJ_VERTEX_COLOR0) + uniform->arr[U_MORPH_COLOR] = 1; + else + uniform->arr[U_MORPH_COLOR] = 0; + + rctx->obj_batch.g_morph_weight = { args->morph_weight, 1.0f - args->morph_weight, 0.0f, 0.0f }; + } + else { + uniform->arr[U_MORPH] = 0; + uniform->arr[U_MORPH_COLOR] = 0; + } + + /*if (args->instances_count) + uniform->arr[U_INSTANCE] = 1; + else + uniform->arr[U_INSTANCE] = 0;*/ +} + +static void draw_object_vertex_attrib_set_reflect(const mdl::ObjSubMeshArgs* args) { + const obj_mesh* mesh = args->mesh; + obj_vertex_format vertex_format = mesh->vertex_format; + + const obj_material_data* material = args->material; + if (material->material.texdata[0].tex_index != -1) { + uint32_t texture_id = material->material.texdata[0].tex_index & 0xFFFFF; + + rctx->obj_batch.set_g_texcoord_transforms(0, + material->material.texdata[0].tex_coord_mat); + if (material->material.texdata[0].shader_info.m.tex_type == OBJ_MATERIAL_TEXTURE_COLOR) + for (int32_t j = 0; j < args->texture_transform_count; j++) + if (args->texture_transform_array[j].id == texture_id) { + rctx->obj_batch.set_g_texcoord_transforms(0, + args->texture_transform_array[j].mat); + break; + } + } + + if (vertex_format & OBJ_VERTEX_BONE_DATA) + uniform->arr[U_BONE_MAT] = 1; + else + uniform->arr[U_BONE_MAT] = 0; + + if (args->morph_vertex_buffer) { + uniform->arr[U_MORPH] = 1; + + if (vertex_format & OBJ_VERTEX_COLOR0) + uniform->arr[U_MORPH_COLOR] = 1; + else + uniform->arr[U_MORPH_COLOR] = 0; + + rctx->obj_batch.g_morph_weight = { args->morph_weight, 1.0f - args->morph_weight, 0.0f, 0.0f }; + } + else { + uniform->arr[U_MORPH] = 0; + uniform->arr[U_MORPH_COLOR] = 0; + } +} diff --git a/src/DivaGL/mdl/draw_object.hpp b/src/DivaGL/mdl/draw_object.hpp new file mode 100644 index 0000000..d71fc1b --- /dev/null +++ b/src/DivaGL/mdl/draw_object.hpp @@ -0,0 +1,32 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/mat.hpp" +#include "../../KKdLib/vec.hpp" +#include "../object.hpp" +#include "../render_context.hpp" + +namespace mdl { + extern void draw(obj_primitive_type primitive_type, uint32_t count, + uint16_t start, uint16_t end, obj_index_format index_format, size_t indices); + extern void draw_etc_obj(mdl::EtcObj* etc); + extern void draw_sub_mesh(const ObjSubMeshArgs* args, const mat4* model, + void(*func)(const ObjSubMeshArgs* args)); + extern void draw_sub_mesh_show_vector(const ObjSubMeshArgs* args, const mat4* model, int32_t show_vector); + extern void draw_sub_mesh_default(const ObjSubMeshArgs* args); + extern void draw_sub_mesh_default_instanced(const ObjSubMeshArgs* args, const mat4* mat); + extern void draw_sub_mesh_sss(const ObjSubMeshArgs* args); + extern void draw_sub_mesh_reflect(const ObjSubMeshArgs* args); + extern void draw_sub_mesh_reflect_reflect_map(const ObjSubMeshArgs* args); + extern void draw_sub_mesh_shadow(const ObjSubMeshArgs* args); + extern void draw_sub_mesh_translucent(const ObjSubMeshArgs* args); +}; + +extern void draw_object_model_mat_load(const mat4& mat); +extern void model_mat_face_camera_position(const mat4* view, const mat4* src, mat4* dst); +extern void model_mat_face_camera_view(const mat4* view, const mat4* src, mat4* dst); diff --git a/src/DivaGL/object.cpp b/src/DivaGL/object.cpp new file mode 100644 index 0000000..20abfed --- /dev/null +++ b/src/DivaGL/object.cpp @@ -0,0 +1,116 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "object.hpp" +#include "gl_state.hpp" +#include "wrap.hpp" +#include + +uint32_t(FASTCALL* obj_database_get_object_info)(const char* name) + = (uint32_t(FASTCALL*)(const char* name))0x0000000140459F80; +obj* (FASTCALL* object_info_get_object)(object_info obj_info) + = (obj * (FASTCALL*)(object_info obj_info))0x000000014045A140; +obj_mesh_index_buffer* (FASTCALL* object_info_get_mesh_index_buffer)(object_info obj_info, int32_t a2) + = (obj_mesh_index_buffer * (FASTCALL*)(object_info obj_info, int32_t a2))0x000000014045A250; +obj_skin* (FASTCALL* obj_database_get_object_skin)(object_info obj_info) + = (obj_skin * (FASTCALL*)(object_info obj_info))0x000000014045A3E0; +obj_mesh_vertex_buffer* (FASTCALL* object_info_get_mesh_vertex_buffer)(object_info obj_info, int32_t a2) + = (obj_mesh_vertex_buffer * (FASTCALL*)(object_info obj_info, int32_t a2))0x000000014045A480; +GLuint(FASTCALL* obj_database_get_obj_set_texture)(int32_t set, int32_t tex_id) + = (GLuint(FASTCALL*)(int32_t set, int32_t tex_id))0x000000014045A8F0; +prj::vector* (FASTCALL* obj_database_get_obj_set_textures)(int32_t set) + = (prj::vector * (FASTCALL*)(int32_t set))0x000000014045A9E0; + +void obj_mesh_vertex_buffer::cycle_index() { + if (++index >= count) + index = 0; +} + +GLuint obj_mesh_vertex_buffer::get_buffer() { + if (index < count) + return buffers[index]; + return 0; +} + +GLsizeiptr obj_mesh_vertex_buffer::get_size() { + if (buffers[0]) { + GLint buffer; + GLint size; + glGetIntegervDLL(GL_ARRAY_BUFFER_BINDING, &buffer); + glBindBuffer(target, buffers[0]); + glGetBufferParameterivARB(target, GL_BUFFER_SIZE, &size); + glBindBuffer(target, buffer); + return size; + } + return 0; +} + +inline int32_t obj_material_texture_type_get_texcoord_index( + obj_material_texture_type type, int32_t index) { + switch (type) { + case OBJ_MATERIAL_TEXTURE_COLOR: + if (index < 2) + return index; + case OBJ_MATERIAL_TEXTURE_NORMAL: + case OBJ_MATERIAL_TEXTURE_SPECULAR: + return 0; + case OBJ_MATERIAL_TEXTURE_TRANSLUCENCY: + case OBJ_MATERIAL_TEXTURE_TRANSPARENCY: + return 1; + } + return -1; +} + +inline int32_t obj_material_texture_type_get_texture_index( + obj_material_texture_type type, int32_t base_index) { + switch (type) { + case OBJ_MATERIAL_TEXTURE_COLOR: + if (base_index < 2) + return base_index; + case OBJ_MATERIAL_TEXTURE_NORMAL: + return 2; + case OBJ_MATERIAL_TEXTURE_SPECULAR: + return 3; + case OBJ_MATERIAL_TEXTURE_TRANSLUCENCY: + return 1; + case OBJ_MATERIAL_TEXTURE_TRANSPARENCY: + return 4; + case OBJ_MATERIAL_TEXTURE_ENVIRONMENT_SPHERE: // AFT + case OBJ_MATERIAL_TEXTURE_ENVIRONMENT_CUBE: + return 5; + } + return -1; +} + +void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices, + mat4* ex_data_matrices, mat4* matrix_buffer, const mat4* mat, const mat4* global_mat) { + if (!s->num_bone) + return; + + if (mat) + for (uint32_t i = 0; i < s->num_bone; i++) { + mat4 temp; + int32_t bone_id = s->bone_id_array[i]; + if (bone_id & 0x8000) + mat4_mul(&ex_data_matrices[bone_id & 0x7FFF], mat, &temp); + else + mat4_mul(&matrices[bone_id], mat, &temp); + + mat4_mul(global_mat, &temp, &temp); + mat4_mul(&temp, &s->bone_matrix_array[i], &matrix_buffer[i]); + } + else + for (uint32_t i = 0; i < s->num_bone; i++) { + mat4 temp; + int32_t bone_id = s->bone_id_array[i]; + if (bone_id & 0x8000) + temp = ex_data_matrices[bone_id & 0x7FFF]; + else + temp = matrices[bone_id]; + + mat4_mul(global_mat, &temp, &temp); + mat4_mul(&temp, &s->bone_matrix_array[i], &matrix_buffer[i]); + } +} diff --git a/src/DivaGL/object.hpp b/src/DivaGL/object.hpp new file mode 100644 index 0000000..9642347 --- /dev/null +++ b/src/DivaGL/object.hpp @@ -0,0 +1,529 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "texture.hpp" +#include "types.hpp" + +enum obj_index_format : uint32_t { + OBJ_INDEX_U8 = 0x00, + OBJ_INDEX_U16 = 0x01, + OBJ_INDEX_U32 = 0x02, +}; + +enum obj_material_aniso_direction : uint32_t { + OBJ_MATERIAL_ANISO_DIRECTION_NORMAL = 0, + OBJ_MATERIAL_ANISO_DIRECTION_U = 1, + OBJ_MATERIAL_ANISO_DIRECTION_V = 2, + OBJ_MATERIAL_ANISO_DIRECTION_RADIAL = 3, +}; + +enum obj_material_blend_factor : uint32_t { + OBJ_MATERIAL_BLEND_ZERO = 0, + OBJ_MATERIAL_BLEND_ONE = 1, + OBJ_MATERIAL_BLEND_SRC_COLOR = 2, + OBJ_MATERIAL_BLEND_INVERSE_SRC_COLOR = 3, + OBJ_MATERIAL_BLEND_SRC_ALPHA = 4, + OBJ_MATERIAL_BLEND_INVERSE_SRC_ALPHA = 5, + OBJ_MATERIAL_BLEND_DST_ALPHA = 6, + OBJ_MATERIAL_BLEND_INVERSE_DST_ALPHA = 7, + OBJ_MATERIAL_BLEND_DST_COLOR = 8, + OBJ_MATERIAL_BLEND_INVERSE_DST_COLOR = 9, + OBJ_MATERIAL_BLEND_ALPHA_SATURATE = 10, +}; + +enum obj_material_bump_map_type : uint32_t { + OBJ_MATERIAL_BUMP_MAP_NONE = 0, + OBJ_MATERIAL_BUMP_MAP_DOT = 1, + OBJ_MATERIAL_BUMP_MAP_ENV = 2, +}; + +enum obj_material_color_source_type : uint32_t { + OBJ_MATERIAL_COLOR_SOURCE_MATERIAL_COLOR = 0, + OBJ_MATERIAL_COLOR_SOURCE_VERTEX_COLOR = 1, + OBJ_MATERIAL_COLOR_SOURCE_VERTEX_MORPH = 2, +}; + +enum obj_material_shader_lighting_type : uint32_t { + OBJ_MATERIAL_SHADER_LIGHTING_LAMBERT = 0x00, + OBJ_MATERIAL_SHADER_LIGHTING_CONSTANT = 0x01, + OBJ_MATERIAL_SHADER_LIGHTING_PHONG = 0x02, +}; + +enum obj_material_specular_quality : uint32_t { + OBJ_MATERIAL_SPECULAR_QUALITY_LOW = 0, + OBJ_MATERIAL_SPECULAR_QUALITY_HIGH = 1, +}; + +enum obj_material_texture_type : uint32_t { + OBJ_MATERIAL_TEXTURE_NONE = 0x00, + OBJ_MATERIAL_TEXTURE_COLOR = 0x01, + OBJ_MATERIAL_TEXTURE_NORMAL = 0x02, + OBJ_MATERIAL_TEXTURE_SPECULAR = 0x03, + OBJ_MATERIAL_TEXTURE_HEIGHT = 0x04, + OBJ_MATERIAL_TEXTURE_REFLECTION = 0x05, + OBJ_MATERIAL_TEXTURE_TRANSLUCENCY = 0x06, + OBJ_MATERIAL_TEXTURE_TRANSPARENCY = 0x07, + OBJ_MATERIAL_TEXTURE_ENVIRONMENT_SPHERE = 0x08, + OBJ_MATERIAL_TEXTURE_ENVIRONMENT_CUBE = 0x09, +}; + +enum obj_material_texture_coordinate_translation_type : uint32_t { + OBJ_MATERIAL_TEXTURE_COORDINATE_TRANSLATION_NONE = 0x00, + OBJ_MATERIAL_TEXTURE_COORDINATE_TRANSLATION_UV = 0x01, + OBJ_MATERIAL_TEXTURE_COORDINATE_TRANSLATION_SPHERE = 0x02, + OBJ_MATERIAL_TEXTURE_COORDINATE_TRANSLATION_CUBE = 0x03, +}; + +enum obj_material_vertex_translation_type : uint32_t { + OBJ_MATERIAL_VERTEX_TRANSLATION_DEFAULT = 0, + OBJ_MATERIAL_VERTEX_TRANSLATION_ENVELOPE = 1, + OBJ_MATERIAL_VERTEX_TRANSLATION_MORPHING = 2, +}; + +enum obj_primitive_type : uint32_t { + OBJ_PRIMITIVE_POINTS = 0x00, + OBJ_PRIMITIVE_LINES = 0x01, + OBJ_PRIMITIVE_LINE_STRIP = 0x02, + OBJ_PRIMITIVE_LINE_LOOP = 0x03, + OBJ_PRIMITIVE_TRIANGLES = 0x04, + OBJ_PRIMITIVE_TRIANGLE_STRIP = 0x05, + OBJ_PRIMITIVE_TRIANGLE_FAN = 0x06, + OBJ_PRIMITIVE_QUADS = 0x07, + OBJ_PRIMITIVE_QUAD_STRIP = 0x08, + OBJ_PRIMITIVE_POLYGON = 0x09, +}; + +enum obj_vertex_format : uint32_t { + OBJ_VERTEX_NONE = 0x0000, + OBJ_VERTEX_POSITION = 0x0001, + OBJ_VERTEX_NORMAL = 0x0002, + OBJ_VERTEX_TANGENT = 0x0004, + OBJ_VERTEX_BINORMAL = 0x0008, + OBJ_VERTEX_TEXCOORD0 = 0x0010, + OBJ_VERTEX_TEXCOORD1 = 0x0020, + OBJ_VERTEX_TEXCOORD2 = 0x0040, + OBJ_VERTEX_TEXCOORD3 = 0x0080, + OBJ_VERTEX_COLOR0 = 0x0100, + OBJ_VERTEX_COLOR1 = 0x0200, + OBJ_VERTEX_BONE_WEIGHT = 0x0400, + OBJ_VERTEX_BONE_INDEX = 0x0800, + OBJ_VERTEX_BONE_DATA = 0x0C00, + OBJ_VERTEX_UNKNOWN = 0x1000, +}; + +struct obj_axis_aligned_bounding_box { + vec3 center; + vec3 size; +}; + +struct obj_bounding_box { + vec3 center; + vec3 size; +}; + +struct obj_bounding_sphere { + vec3 center; + float_t radius; +}; + +struct obj_shader_compo_member { + uint32_t color : 1; + uint32_t color_a : 1; + uint32_t color_l1 : 1; + uint32_t color_l1_a : 1; + uint32_t color_l2 : 1; + uint32_t color_l2_a : 1; + uint32_t transparency : 1; + uint32_t specular : 1; + uint32_t normal_01 : 1; + uint32_t normal_02 : 1; + uint32_t envmap : 1; + uint32_t color_l3 : 1; + uint32_t color_l3_a : 1; + uint32_t translucency : 1; + uint32_t flag_14 : 1; + uint32_t override_ibl : 1; + uint32_t dummy : 16; +}; + +union obj_shader_compo { + obj_shader_compo_member m; + uint32_t w; +}; + +struct obj_material_shader_attrib_member { + obj_material_vertex_translation_type vtx_trans_type : 2; + obj_material_color_source_type col_src : 2; + uint32_t is_lgt_diffuse : 1; + uint32_t is_lgt_specular : 1; + uint32_t is_lgt_per_pixel : 1; + uint32_t is_lgt_double : 1; + obj_material_bump_map_type bump_map_type : 2; + uint32_t fresnel_type : 4; + uint32_t line_light : 4; + uint32_t recieve_shadow : 1; + uint32_t cast_shadow : 1; + obj_material_specular_quality specular_quality : 1; + obj_material_aniso_direction aniso_direction : 2; + uint32_t dummy : 9; +}; + +union obj_material_shader_attrib { + obj_material_shader_attrib_member m; + uint32_t w; + + obj_material_shader_lighting_type get_lighting_type() const; +}; + +struct obj_texture_attrib_member { + uint32_t repeat_u : 1; + uint32_t repeat_v : 1; + uint32_t mirror_u : 1; + uint32_t mirror_v : 1; + uint32_t ignore_alpha : 1; + uint32_t blend : 5; + uint32_t alpha_blend : 5; + uint32_t border : 1; + uint32_t clamp2edge : 1; + uint32_t filter : 3; + uint32_t mipmap : 2; + uint32_t mipmap_bias : 7; + uint32_t flag_29 : 1; + uint32_t anisotropic_filter : 2; +}; + +union obj_texture_attrib { + obj_texture_attrib_member m; + uint32_t w; + + int32_t get_blend() const; +}; + +struct obj_texture_shader_attrib_member { + obj_material_texture_type tex_type : 4; + int32_t uv_idx : 4; + obj_material_texture_coordinate_translation_type texcoord_trans : 3; + uint32_t dummy : 21; +}; + +union obj_texture_shader_attrib { + obj_texture_shader_attrib_member m; + uint32_t w; +}; + +struct obj_material_texture_data { + obj_texture_attrib attrib; + uint32_t tex_index; + obj_texture_shader_attrib shader_info; + char ex_shader[8]; + float_t weight; + mat4 tex_coord_mat; + uint32_t reserved[8]; +}; + +struct obj_material_attrib_member { + uint32_t alpha_texture : 1; + uint32_t alpha_material : 1; + uint32_t punch_through : 1; + uint32_t double_sided : 1; + uint32_t normal_dir_light : 1; + obj_material_blend_factor src_blend_factor : 4; + obj_material_blend_factor dst_blend_factor : 4; + uint32_t blend_operation : 3; + uint32_t zbias : 4; + uint32_t no_fog : 1; + uint32_t translucent_priority : 6; + uint32_t has_fog_height : 1; + uint32_t flag_28 : 1; + uint32_t fog_height : 1; + uint32_t flag_30 : 1; + uint32_t flag_31 : 1; +}; + +union obj_material_attrib { + obj_material_attrib_member m; + uint32_t w; +}; + +struct obj_material_color { + vec4 diffuse; + vec4 ambient; + vec4 specular; + vec4 emission; + float_t shininess; + float_t intensity; +}; + +struct obj_material { + obj_shader_compo shader_compo; + union { + char name[8]; + int32_t index; + } shader; + obj_material_shader_attrib shader_info; + obj_material_texture_data texdata[8]; + obj_material_attrib attrib; + obj_material_color color; + vec3 center; + float_t radius; + char name[64]; + float_t bump_depth; + uint32_t reserved[15]; +}; + +struct obj_material_data { + uint32_t num_of_textures; + obj_material material; +}; + +struct obj_sub_mesh_attrib_member { + uint32_t recieve_shadow : 1; + uint32_t cast_shadow : 1; + uint32_t transparent : 1; + uint32_t cloth : 1; + uint32_t dummy : 28; +}; + +union obj_sub_mesh_attrib { + obj_sub_mesh_attrib_member m; + uint32_t w; +}; + +struct obj_sub_mesh { + uint32_t flags; + obj_bounding_sphere bounding_sphere; + uint32_t material_index; + uint8_t uv_index[8]; + uint32_t num_bone_index; + uint16_t* bone_index_array; + uint32_t bones_per_vertex; + obj_primitive_type primitive_type; + obj_index_format index_format; + uint32_t num_index; + uint16_t* index_array; + obj_sub_mesh_attrib attrib; + uint32_t reserved[4]; + obj_axis_aligned_bounding_box* axis_aligned_bounding_box; + uint16_t first_index; + uint16_t last_index; + uint32_t index_offset; +}; + +static_assert(sizeof(obj_sub_mesh) == 0x70, "\"obj_sub_mesh\" struct should have a size of 0x70"); + +struct obj_vertex_data { + vec3 position; + vec3 normal; + vec4 tangent; + vec3 binormal; + vec2 texcoord0; + vec2 texcoord1; + vec2 texcoord2; + vec2 texcoord3; + vec4 color0; + vec4 color1; + vec4 bone_weight; + vec4i16 bone_index; + vec4 unknown; +}; + +struct obj_mesh_attrib_member { + uint32_t double_buffer : 1; + uint32_t billboard_y_axis : 1; + uint32_t translucent_no_shadow : 1; + uint32_t billboard : 1; + uint32_t dummy : 28; +}; + +union obj_mesh_attrib { + obj_mesh_attrib_member m; + uint32_t w; +}; + +struct obj_mesh_vertex_array { + vec3* position; + vec3* normal; + vec4* tangent; + vec3* binormal; + vec2* texcoord0; + vec2* texcoord1; + vec2* texcoord2; + vec2* texcoord3; + vec4* color0; + vec4* color1; + vec4* bone_weight; + vec4* bone_index; + void* field_60; + void* field_68; + void* field_70; + void* field_78; + void* field_80; + void* field_88; + void* field_90; + void* field_98; +}; + +struct obj_mesh { + uint32_t flags; + obj_bounding_sphere bounding_sphere; + uint32_t num_submesh; + obj_sub_mesh* submesh_array; + obj_vertex_format vertex_format; + uint32_t size_vertex; + uint32_t num_vertex; + union { + obj_mesh_vertex_array vertex_array; + void* vertex_array_ptr[20]; + }; + obj_mesh_attrib attrib; + uint32_t vertex_flags; + uint32_t reserved[6]; + char name[0x40]; +}; + +static_assert(sizeof(obj_mesh) == 0x130, "\"obj_mesh\" struct should have a size of 0x130"); + +struct obj { + uint32_t version; + uint32_t flags; + obj_bounding_sphere bounding_sphere; + uint32_t num_mesh; + obj_mesh* mesh_array; + uint32_t num_material; + obj_material_data* material_array; + uint32_t reserved[10]; +}; + +struct obj_skin_ex_data { + uint32_t num_osage_name; + uint32_t num_osage_node; + const char** field_8; + struct obj_skin_osage_node* osage_node_array; + const char** osage_name_array; + struct obj_skin_block* block_array; + uint32_t num_bone_name; + const char** bone_name_array; + struct obj_skin_osage_sibling_info* osage_sibling_infos; + uint32_t cloth_count; + uint32_t reserved[7]; +}; + +struct obj_skin { + uint32_t* bone_id_array; + mat4* bone_matrix_array; + const char** bone_name_array; + obj_skin_ex_data* ex_data; + uint32_t num_bone; + int32_t bone_parent_ids_offset; + int32_t field_28; + int32_t field_2C; + int32_t field_30; +}; + +struct object_info { + uint16_t id; + uint16_t set_id; + + inline object_info() { + this->id = (uint16_t)-1; + this->set_id = (uint16_t)-1; + } + + inline object_info(uint16_t id, uint16_t set_id) { + this->id = id; + this->set_id = set_id; + } + + inline object_info(uint32_t data) { + this->id = (uint16_t)data; + this->set_id = (uint16_t)(data >> 16); + } + + inline bool is_null() const { + return id == (uint16_t)-1 && set_id == (uint16_t)-1; + } + + inline bool not_null() const { + return id != (uint16_t)-1 || set_id != (uint16_t)-1; + } +}; + +inline bool operator >(const object_info& left, const object_info& right) { + return *(uint32_t*)&left > *(uint32_t*)&right; +} + +inline bool operator <(const object_info& left, const object_info& right) { + return *(uint32_t*)&left < *(uint32_t*)&right; +} + +inline bool operator >=(const object_info& left, const object_info& right) { + return *(uint32_t*)&left >= *(uint32_t*)&right; +} + +inline bool operator <=(const object_info& left, const object_info& right) { + return *(uint32_t*)&left <= *(uint32_t*)&right; +} + +inline bool operator ==(const object_info& left, const object_info& right) { + return *(uint32_t*)&left == *(uint32_t*)&right; +} + +inline bool operator !=(const object_info& left, const object_info& right) { + return *(uint32_t*)&left != *(uint32_t*)&right; +} + +struct obj_mesh_index_buffer { + GLuint buffer; +}; + +static_assert(sizeof(obj_mesh_index_buffer) == 0x04, "\"obj_mesh_index_buffer\" struct should have a size of 0x04"); + +struct obj_mesh_vertex_buffer { + int32_t count; + GLuint buffers[3]; + int32_t index; + GLenum target; + + void cycle_index(); + GLuint get_buffer(); + GLsizeiptr get_size(); +}; + +static_assert(sizeof(obj_mesh_vertex_buffer) == 0x18, "\"obj_mesh_vertex_buffer\" struct should have a size of 0x18"); + +struct obj_index_buffer { + uint32_t mesh_num; + obj_mesh_index_buffer* mesh_data; +}; + +static_assert(sizeof(obj_index_buffer) == 0x10, "\"obj_index_buffer\" struct should have a size of 0x10"); + +struct obj_vertex_buffer { + uint32_t mesh_num; + obj_mesh_vertex_buffer* mesh_data; +}; + +static_assert(sizeof(obj_vertex_buffer) == 0x10, "\"obj_vertex_buffer\" struct should have a size of 0x10"); + +extern uint32_t(FASTCALL* obj_database_get_object_info)(const char* name); +extern obj* (FASTCALL* object_info_get_object)(object_info obj_info); +extern obj_mesh_index_buffer* (FASTCALL* object_info_get_mesh_index_buffer)(object_info obj_info, int32_t a2); +extern obj_skin* (FASTCALL* obj_database_get_object_skin)(object_info obj_info); +extern obj_mesh_vertex_buffer* (FASTCALL* object_info_get_mesh_vertex_buffer)(object_info obj_info, int32_t a2); +extern GLuint(FASTCALL* obj_database_get_obj_set_texture)(int32_t set, int32_t tex_id); +extern prj::vector* (FASTCALL* obj_database_get_obj_set_textures)(int32_t set); + +extern int32_t obj_material_texture_type_get_texcoord_index( + obj_material_texture_type type, int32_t index); +extern int32_t obj_material_texture_type_get_texture_index( + obj_material_texture_type type, int32_t base_index); + +extern void obj_skin_set_matrix_buffer(obj_skin* s, mat4* matrices, + mat4* ex_data_matrices, mat4* matrix_buffer, const mat4* mat, const mat4* global_mat); diff --git a/src/DivaGL/print.cpp b/src/DivaGL/print.cpp new file mode 100644 index 0000000..145b2f6 --- /dev/null +++ b/src/DivaGL/print.cpp @@ -0,0 +1,22 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "print.hpp" + +void printf_divagl(const char* fmt, ...) { + printf("[DivaGL] "); + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + printf("\n"); +} + +void printf_proxy(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} diff --git a/src/DivaGL/print.hpp b/src/DivaGL/print.hpp new file mode 100644 index 0000000..cfd4939 --- /dev/null +++ b/src/DivaGL/print.hpp @@ -0,0 +1,11 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" + +extern void printf_divagl(const char* fmt, ...); +extern void printf_proxy(const char* fmt, ...); diff --git a/src/DivaGL/render.cpp b/src/DivaGL/render.cpp new file mode 100644 index 0000000..2c3247b --- /dev/null +++ b/src/DivaGL/render.cpp @@ -0,0 +1,1763 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "render.hpp" +#include "rob/rob.hpp" +#include "gl_state.hpp" +#include "render_context.hpp" +#include "render_context.hpp" +#include "shader_glsl_ft.hpp" +#include "texture.hpp" + +extern bool task_stage_is_modern; + +extern render_context* rctx; + +rndr::Render* render = (rndr::Render*)0x00000001411AB670; + +#define MLAA_MAX_EDGE_DETECTION_LEN (3) +#define MLAA_GRID_SIDE_LEN (2 * MLAA_MAX_EDGE_DETECTION_LEN + 1) +#define MLAA_SIDE_LEN (5 * MLAA_GRID_SIDE_LEN) + +#define TONE_MAP_SAT_GAMMA_SAMPLES 32 + +namespace rndr { + static void generate_mlaa_area_texture(Render* rend); + static void calculate_mlaa_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2); + static void calculate_mlaa_area_texture_data_inner(float_t* val_left, + float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright); + + void Render::ExposureCharaData::reset() { + for (GLuint& i : query_data) + i = -1; + spot_weight = 0.0f; + } + + void Render::apply_post_process() { + for (int32_t i = 0; i < 8; i++) + gl_state_bind_sampler(i, 0); + + gl_state_disable_depth_test(); + gl_state_disable_blend(); + + dof->apply(&rend_texture[0]); + + draw_lens_ghost(); + + downsample(); + + reduce_tex_draw = 0; + get_blur(); + + calc_exposure(); + apply_tone_map(); + + if (mlaa) + apply_mlaa(ss_alpha_mask); + + for (int32_t i = 0; i < 16; i++) { + if (!render_textures_data[i]) + continue; + + render_textures[i].Bind(); + + texture* t = render_textures_data[i]; + if (render_width[0] > t->width * 2 || render_height[0] > t->height * 2) + uniform->arr[U_REDUCE] = 1; + else + uniform->arr[U_REDUCE] = 0; + + glViewportDLL(0, 0, t->width, t->height); + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + shaders_ft.set(SHADER_FT_REDUCE); + draw_quad(render_post_width[0], render_post_height[0], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + } + + copy_to_frame_texture(rend_texture[0].GetColorTex(), + render_width[0], render_height[0], taa_tex[taa_texture_selector]->tex); + + rctx->screen_buffer.Bind(); + glViewportDLL(0, 0, rctx->sprite_width, rctx->sprite_height); + if (ssaa) { + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + uniform->arr[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + uniform->arr[U_REDUCE] = 0; + shaders_ft.set(SHADER_FT_REDUCE); + draw_quad(render_post_width[0], render_post_height[0], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + uniform->arr[U_ALPHA_MASK] = 0; + } + else { + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + if (mag_filter == MAG_FILTER_NEAREST) + gl_state_bind_sampler(0, rctx->render_samplers[1]); + else + gl_state_bind_sampler(0, rctx->render_samplers[0]); + + switch (mag_filter) { + case MAG_FILTER_NEAREST: + case MAG_FILTER_BILINEAR: + default: + uniform->arr[U_MAGNIFY] = 0; + break; + case MAG_FILTER_SHARPEN_5_TAP: + uniform->arr[U_MAGNIFY] = 2; + break; + case MAG_FILTER_SHARPEN_4_TAP: + uniform->arr[U_MAGNIFY] = 3; + break; + case MAG_FILTER_CONE_4_TAP: + uniform->arr[U_MAGNIFY] = 4; + break; + case MAG_FILTER_CONE_2_TAP: + uniform->arr[U_MAGNIFY] = 5; + break; + } + + shaders_ft.set(SHADER_FT_MAGNIFY); + draw_quad(render_post_width[0], render_post_height[0], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + } + shader_glsl::unbind(); + + for (int32_t i = 0; i < 8; i++) + gl_state_bind_sampler(i, 0); + + gl_state_bind_framebuffer(0); + } + + void Render::bind_render_texture(bool aet_back) { + if (aet_back) { + aet_back_texture.Bind(); + this->aet_back = 1; + } + else + rend_texture[0].Bind(); + glViewportDLL(0, 0, render_width[0], render_height[0]); + } + + void Render::calc_exposure_chara_data() { + shader_glsl::unbind(); + + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + gl_state_set_depth_mask(GL_FALSE); + gl_state_disable_cull_face(); + + shaders_ft.set(SHADER_FT_SUN_NO_TEXTURED); + gl_state_bind_vertex_array(rctx->common_vao); + rctx->sun_quad_ubo.Bind(0); + + mat4 view_matrix; + mat4_transpose(&camera_data->view_matrix, &view_matrix); + mat4 projection_matrix; + mat4_transpose(&camera_data->projection_matrix, &projection_matrix); + + ExposureCharaData* chara_data = exposure_chara_data; + int32_t query_index = (this->exposure_query_index + 1) % 3; + this->exposure_query_index = query_index; + int32_t next_query_index = (query_index + 2) % 3; + size_t rob_chara_smth = get_rob_chara_smth(); + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++, chara_data++) { + size_t rob_chr = rob_chara_array_get(rob_chara_smth, i); + if (!rob_chr || !(*(uint8_t*)(rob_chara_smth + 0x440) & 1)) + continue; + + float_t max_face_depth = rob_chara_get_max_face_depth(rob_chr); + + mat4 mat = mat4_identity; + sub_1405163C0(rob_chr, 4, &mat); + mat4_mul(&mat, &view_matrix, &mat); + mat4_mul_translate(&mat, max_face_depth + 0.1f, 0.0f, -0.06f, &mat); + mat4_clear_rot(&mat, &mat); + mat4_scale_rot(&mat, 0.0035f, &mat); + mat4_mul(&mat, &projection_matrix, &mat); + + sun_quad_shader_data shader_data = {}; + mat4_transpose(&mat, &mat); + shader_data.g_transform[0] = mat.row0; + shader_data.g_transform[1] = mat.row1; + shader_data.g_transform[2] = mat.row2; + shader_data.g_transform[3] = mat.row3; + shader_data.g_emission = 0.0f; + rctx->sun_quad_ubo.WriteMemory(shader_data); + + glBeginQuery(GL_SAMPLES_PASSED, chara_data->query[next_query_index]); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + glEndQuery(GL_SAMPLES_PASSED); + + if (chara_data->query_data[next_query_index] == -1) + chara_data->query_data[next_query_index] = 0; + + if (chara_data->query_data[query_index] != -1) { + int32_t res = 0; + glGetQueryObjectiv(chara_data->query[query_index], + GL_QUERY_RESULT_AVAILABLE, &res); + if (res) + glGetQueryObjectuiv(chara_data->query[query_index], + GL_QUERY_RESULT, chara_data->query_data); + else + chara_data->query_data[query_index] = 0; + } + } + + gl_state_bind_vertex_array(0); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl_state_set_depth_mask(GL_TRUE); + gl_state_enable_cull_face(); + } + + void Render::calc_projection_matrix(mat4* mat, double_t fov, double_t aspect, double_t z_near, double_t z_far, + double_t left_scale, double_t right_scale, double_t bottom_scale, double_t top_scale) { + double_t tan_fov = tan(fov * DEG_TO_RAD * 0.5) * z_near; + double_t left = -tan_fov * aspect + tan_fov * aspect * left_scale; + double_t right = tan_fov * aspect + tan_fov * aspect * right_scale; + double_t bottom = -tan_fov + tan_fov * bottom_scale; + double_t top = tan_fov + tan_fov * top_scale; + + if (taa) { + double_t offset = taa_texture_selector == 1 ? -0.25 : 0.25; + double_t left_right_offset = (right - left) * offset / (double_t)render_width[0]; + double_t bottom_top_offset = (top - bottom) * offset / (double_t)render_height[0]; + left += left_right_offset; + right += left_right_offset; + bottom += bottom_top_offset; + top += bottom_top_offset; + } + + mat4_frustrum(left, right, bottom, top, z_near, z_far, mat); + mat4_transpose(mat, mat); + } + + void Render::ctrl() { + static int32_t(FASTCALL * task_stage_get_current_stage_index)() + = (int32_t(FASTCALL*)())0x000000014064ADA0; + + view_point_prev = view_point; + interest_prev = interest; + view_point = camera_data->view_point; + interest = camera_data->interest; + + stage_index_prev = stage_index; + stage_index = task_stage_get_current_stage_index(); + + cam_view_projection_prev = cam_view_projection; + cam_view_projection = camera_data->view_projection_matrix; + + reset_exposure = camera_data->fast_change_hist1 && !camera_data->fast_change_hist0; + if (reset_exposure) { + float_t view_point_dist = vec3::distance(view_point, view_point_prev); + + vec3 dir = vec3::normalize(interest - view_point); + vec3 dir_prev = vec3::normalize(interest_prev - view_point_prev); + + float_t dir_diff_angle = vec3::dot(dir, dir_prev); + if (dir_diff_angle < 0.5f) + dir_diff_angle = 0.0f; + if (view_point_dist < dir_diff_angle * 0.4f) + reset_exposure = false; + } + else if (stage_index != stage_index_prev) + reset_exposure = true; + + if (movie_textures_data[0]) { + static size_t(FASTCALL * task_movie_get)(int32_t index) + = (size_t(FASTCALL*)(int32_t index))0x000000014041ED30; + size_t task_movie = task_movie_get(0); + if (task_movie) { + static texture*(FASTCALL * sub_14041ED80)(size_t task_movie) + = (texture*(FASTCALL*)(size_t task_movie))0x000000014041ED80; + texture* movie_texture = sub_14041ED80(task_movie); + if (movie_texture) { + movie_textures[0].Bind(); + glViewportDLL(0, 0, movie_textures_data[0]->width, movie_textures_data[0]->height); + gl_state_active_bind_texture_2d(0, movie_texture->tex); + uniform->arr[U_REDUCE] = 0; + shaders_ft.set(SHADER_FT_REDUCE); + draw_quad(movie_texture->width, movie_texture->height, + 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + gl_state_bind_framebuffer(0); + } + } + } + } + void Render::draw_quad(int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, + float_t scale, float_t param_x, float_t param_y, float_t param_z, float_t param_w) { + s0 -= s1; + t0 -= t1; + + float_t w = (float_t)max_def(width, 1); + float_t h = (float_t)max_def(height, 1); + quad_shader_data quad = {}; + quad.g_texcoord_modifier = { 0.5f * s0, 0.5f * t0, 0.5f * s0 + s1, 0.5f * t0 + t1 }; // x * 0.5 * y0 + 0.5 * y0 + y1 + quad.g_texel_size = { scale / w, scale / h, w, h }; + quad.g_color = { param_x, param_y, param_z, param_w }; + quad.g_texture_lod = 0.0f; + + rctx->quad_ubo.WriteMemory(quad); + rctx->quad_ubo.Bind(0); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + } + + void Render::draw_lens_flare() { + static float_t flt_1411ACB84 = sinf(0.01365909819f); + static float_t flt_1411ACB8C = tanf(0.01365909819f) * 2.0f * 0.94f; + + if (!lens_flare_texture) + return; + + GLuint tex = obj_database_get_obj_set_texture(5, 4549); + if (!tex) + return; + + mat4 view_matrix; + mat4_transpose(&camera_data->view_matrix, &view_matrix); + mat4 projection_matrix; + mat4_transpose(&camera_data->projection_matrix, &projection_matrix); + + mat4 view_projection_matrix; + mat4 inverse_view_projection_matrix; + mat4_transpose(&camera_data->view_projection_matrix, &view_projection_matrix); + mat4_invert(&view_projection_matrix, &inverse_view_projection_matrix); + + float_t v5 = tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT); + light_set* set = &light_set_data[LIGHT_SET_MAIN]; + light_data* data = &set->lights[LIGHT_SUN]; + + vec3 position; + vec4 emission; + if (data->get_type() == LIGHT_PARALLEL) { + data->get_position(position); + data->get_diffuse(emission); + } + else { + set->lights[LIGHT_STAGE].get_position(position); + position = vec3::normalize(position) * 500.0f; + set->lights[LIGHT_STAGE].get_ibl_color0(emission); + data->set_type(LIGHT_PARALLEL); + data->set_position(position); + data->set_diffuse(emission); + } + + vec4 v44; + *(vec3*)&v44 = position; + v44.w = 1.0f; + + mat4_transform_vector(&view_projection_matrix, &v44, &v44); + + float_t v13 = 1.0f / v44.w; + float_t v14 = v44.x * v13; + float_t v15 = v44.y * v13; + float_t v16 = (float_t)width * 0.01f / (float_t)height; + v14 = clamp_def(v14, -0.99f, 0.99f); + v15 = clamp_def(v15, v16 - 1.0f, 1.0f - v16); + v44.x = v14 * v44.w; + v44.y = v15 * v44.w; + + mat4_transform_vector(&inverse_view_projection_matrix, &v44, &v44); + + void (FASTCALL * pos_scale__get_screen_pos_scale)(vec3 * data, vec3 * trans, __int64 r8, bool apply_offset) + = (void(FASTCALL*)(vec3 * data, vec3 * trans, __int64 r8, bool apply_offset))0x00000001401F7EE0; + pos_scale__get_screen_pos_scale(&lens_flare_pos, &position, 0, false); + + float_t v17 = lens_flare_pos.x - (float_t)width * 0.5f; + float_t v19 = v5 / (float_t)height * 0.5f; + float_t v20 = lens_flare_pos.y - (float_t)height * 0.5f; + + float_t v22 = sqrtf(v17 * v19 * v17 * v19 + v20 * v19 * v20 * v19 + 1.0f); + float_t v23 = ((float_t)render_width[0] * (flt_1411ACB8C / v5)) * (v22 * v22 * 0.5f) + * ((float_t)render_height[0] * (flt_1411ACB8C / v5)); + float_t v24 = vec3::distance(position, view_point) * flt_1411ACB84; + emission *= 1.0f / (float_t)(1.0f - cosf((float_t)(3.0 * DEG_TO_RAD))); + + sun_quad_shader_data shader_data = {}; + shader_data.g_emission = emission; + + gl_state_active_bind_texture_2d(0, tex); + shaders_ft.set(SHADER_FT_SUN); + gl_state_bind_vertex_array(rctx->common_vao); + rctx->sun_quad_ubo.Bind(0); + + int32_t query_index = (lens_flare_query_index + 1) % 3; + lens_flare_query_index = query_index; + int32_t next_query_index = (query_index + 2) % 3; + + if (lens_shaft_query_data[next_query_index] == -1) + lens_shaft_query_data[next_query_index] = 0; + + if (lens_flare_query_data[next_query_index] == -1) + lens_flare_query_data[next_query_index] = 0; + + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + gl_state_set_depth_mask(GL_FALSE); + gl_state_disable_cull_face(); + + mat4 mat; + mat4_mul_translate(&view_matrix, &position, &mat); + mat4_clear_rot(&mat, &mat); + mat4_scale_rot(&mat, v24 * 0.2f, &mat); + mat4_mul(&mat, &projection_matrix, &mat); + + mat4_transpose(&mat, &mat); + shader_data.g_transform[0] = mat.row0; + shader_data.g_transform[1] = mat.row1; + shader_data.g_transform[2] = mat.row2; + shader_data.g_transform[3] = mat.row3; + rctx->sun_quad_ubo.WriteMemory(shader_data); + + glBeginQuery(GL_SAMPLES_PASSED, lens_shaft_query[next_query_index]); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + glEndQuery(GL_SAMPLES_PASSED); + + mat4_mul_translate(&view_matrix, (vec3*)&v44, &mat); + mat4_clear_rot(&mat, &mat); + mat4_scale_rot(&mat, v24 * 2.0f, &mat); + mat4_mul(&mat, &projection_matrix, &mat); + + mat4_transpose(&mat, &mat); + shader_data.g_transform[0] = mat.row0; + shader_data.g_transform[1] = mat.row1; + shader_data.g_transform[2] = mat.row2; + shader_data.g_transform[3] = mat.row3; + rctx->sun_quad_ubo.WriteMemory(shader_data); + + glBeginQuery(GL_SAMPLES_PASSED, lens_flare_query[next_query_index]); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + glEndQuery(GL_SAMPLES_PASSED); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl_state_set_depth_mask(GL_TRUE); + gl_state_enable_cull_face(); + + if (lens_shaft_query_data[query_index] != -1) { + int32_t res = 0; + glGetQueryObjectiv(lens_shaft_query[query_index], GL_QUERY_RESULT_AVAILABLE, &res); + if (res) + glGetQueryObjectuiv(lens_shaft_query[query_index], GL_QUERY_RESULT, &lens_shaft_query_data[query_index]); + } + + if (lens_flare_query_data[query_index] != -1) { + int32_t res = 0; + glGetQueryObjectiv(lens_flare_query[query_index], GL_QUERY_RESULT_AVAILABLE, &res); + if (res) + glGetQueryObjectuiv(lens_flare_query[query_index], GL_QUERY_RESULT, &lens_flare_query_data[query_index]); + } + + if (emission.x + emission.y + emission.z > 0.0f) { + gl_state_enable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ONE); + gl_state_set_depth_mask(GL_FALSE); + + mat4_mul_translate(&view_matrix, &position, &mat); + mat4_clear_rot(&mat, &mat); + mat4_scale_rot(&mat, v24 * 1.1f, &mat); + mat4_mul(&mat, &projection_matrix, &mat); + + mat4_transpose(&mat, &mat); + shader_data.g_transform[0] = mat.row0; + shader_data.g_transform[1] = mat.row1; + shader_data.g_transform[2] = mat.row2; + shader_data.g_transform[3] = mat.row3; + rctx->sun_quad_ubo.WriteMemory(shader_data); + + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + + gl_state_disable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + gl_state_set_depth_mask(GL_TRUE); + } + + gl_state_active_bind_texture_2d(0, 0); + gl_state_bind_vertex_array(0); + + if (lens_flare_appear_power <= 0.01f) + lens_flare_appear_power = 0.0; + else + lens_flare_appear_power *= 0.93f; + lens_shaft_scale = 100.0f; + lens_flare_power = 0.0f; + + float_t v34 = lens_flare_pos.x; + float_t v35 = lens_flare_pos.y; + float_t v32 = lens_flare_pos.z; + + float_t v33 = 0.0f; + if (v32 >= 0.0f + || v34 < (float_t)-width || v34 >(float_t)(2 * width) + || v35 < (float_t)-height || v35 >(float_t)(2 * height)) + lens_flare_texture = 0; + else { + for (GLuint& i : lens_flare_query_data) + if (i != -1) + v33 += min_def((float_t)i, v23); + v33 /= (v23 * 3.0f); + lens_flare_power = powf(v33, 0.7f); + + if (v33 > 0.0f && lens_shaft_query_data[query_index]) { + float_t v41 = max_def(v33 - 0.4f, 0.005f); + lens_shaft_scale = ((0.6f / v41) * lens_shaft_inv_scale) * (v5 * 3.4f); + } + } + + if (v32 >= 0.0f + || v34 < -12.0f || v34 >(float_t)(width + 12) + || v35 < -12.0f || v35 >(float_t)(height + 12)) { + field_A10 = 0.0f; + } + else if (v34 > -2.0f && v34 < (float_t)(width + 2) + && v35 > -2.0f && v35 < (float_t)(height + 2)) { + if (v33 > 0.4f && field_A10 == 0.0f && lens_flare_appear_power < 0.02f && !reset_exposure) + lens_flare_appear_power = 8.0f; + field_A10 = 1.0f; + } + } + + void Render::free() { + if (transparency) { + delete transparency; + transparency = 0; + } + + for (int32_t i = 0; i < 1; i++) + if (transparency_tex[i]) { + texture_free(transparency_tex[i]); + transparency_tex[i] = 0; + texture_counter--; + } + + if (dof) { + delete dof; + dof = 0; + } + + if (!texture_counter) + return; + + for (int32_t i = 0; i < downsample_max_count; i++) + rend_texture[i].Free(); + + for (int32_t i = 0; i < 3; i++) { + taa_buffer[i].Free(); + + if (taa_tex[i]) { + texture_free(taa_tex[i]); + taa_tex[i] = 0; + texture_counter--; + } + } + + aet_back_texture.Free(); + + if (aet_back_tex) { + texture_free(aet_back_tex); + aet_back_tex = 0; + texture_counter--; + } + + mlaa_buffer.Free(); + temp_buffer.Free(); + + sss_contour_texture = 0; + + downsample_texture.Free(); + field_3E8.Free(); + + for (int32_t i = 0; i < 5; i++) + reduce_texture->Free(); + + for (int32_t i = 0; i < 5; i++) + if (reduce_tex[i]) { + texture_free(reduce_tex[i]); + reduce_tex[i] = 0; + texture_counter--; + } + + if (exposure_history) { + texture_free(exposure_history); + exposure_history = 0; + texture_counter--; + } + + exposure_texture.Free(); + + if (exposure_tex) { + glDeleteTextures(1, &exposure_tex); + exposure_tex = 0; + } + + if (tonemap_lut_texture) { + glDeleteTextures(1, &tonemap_lut_texture); + tonemap_lut_texture = 0; + } + if (mlaa_area_texture) { + glDeleteTextures(1, &mlaa_area_texture); + mlaa_area_texture = 0; + } + + glDeleteQueries(3, lens_shaft_query); + glDeleteQueries(3, lens_flare_query); + + for (ExposureCharaData& i : exposure_chara_data) { + glDeleteQueries(3, i.query); + i.query[0] = 0; + } + } + + void Render::init_render_buffers(int32_t width, int32_t height, + int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask) { + this->ssaa = ssaa; + this->hd_res = hd_res; + this->ss_alpha_mask = ss_alpha_mask; + + mlaa = 1; + taa = ssaa || ss_alpha_mask ? 0 : 1; + mag_filter = hd_res ? MAG_FILTER_SHARPEN_4_TAP : MAG_FILTER_BILINEAR; + + this->width = width; + this->height = height; + + if (ssaa) { + inner_width = 2 * width; + inner_height = 2 * height; + } + else { + inner_width = width; + inner_height = height; + } + + screen_x_offset = 0; + screen_y_offset = 0; + + screen_width = width; + screen_height = height; + reduce_width[0] = 256; + reduce_height[0] = 144; + reduce_width[1] = 128; + reduce_height[1] = 72; + reduce_width[2] = 64; + reduce_height[2] = 36; + reduce_width[3] = 32; + reduce_height[3] = 18; + reduce_width[4] = 8; + reduce_height[4] = 8; + + update_res(true, 1); + + rend_texture[0].Init(render_post_width[0], render_post_height[0], 0, GL_RGBA16F, GL_DEPTH_COMPONENT24); + + gl_state_bind_texture_2d(rend_texture[0].GetColorTex()); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + gl_state_bind_texture_2d(rend_texture[0].GetDepthTex()); + GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + + for (int32_t i = 0; i < 3; i++) { + taa_tex[i] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + taa_buffer[i].SetColorDepthTextures(taa_tex[i]->tex, 0, rend_texture[0].GetDepthTex()); + } + + aet_back_tex = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + aet_back_texture.SetColorDepthTextures(aet_back_tex->tex, 0, rend_texture[0].GetDepthTex()); + + mlaa_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_DEPTH_COMPONENT24); + temp_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_ZERO); + sss_contour_texture = &mlaa_buffer; + + gl_state_bind_texture_2d(mlaa_buffer.GetDepthTex()); + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + + for (int32_t i = 1; i < downsample_count; i++) { + rend_texture[i].Init(render_post_width[i], render_post_height[i], 0, GL_RGBA16F, GL_ZERO); + + gl_state_bind_texture_2d(rend_texture[i].GetColorTex()); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + downsample_texture.Init(reduce_width[0], reduce_height[0], 0, GL_RGBA16F, GL_ZERO); + + gl_state_bind_texture_2d(downsample_texture.GetColorTex()); + + const vec4 border_color = 0.0f; + glTexParameterfvDLL(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + + field_3E8.Init(512, 256, 0, GL_RGBA8, GL_ZERO); + + renderer::DOF3* (FASTCALL * renderer__DOF3__DOF3)(renderer::DOF3 * dof, int32_t width, int32_t height) + = (renderer::DOF3 * (FASTCALL*)(renderer::DOF3 * dof, int32_t width, int32_t height))0x00000001404A81F0; + renderer::DOF3* dof = new renderer::DOF3; + this->dof = renderer__DOF3__DOF3(dof, render_post_width[0], render_post_height[0]); + + transparency_tex[0] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA16F, render_post_width[0], render_post_height[0], 0, 0, 0); + + renderer::Transparency* (FASTCALL * renderer__Transparency__Transparency)( + renderer::Transparency * transparency, GLuint color_texture, + GLuint depth_texture, int32_t width, int32_t height) + = (renderer::Transparency * (FASTCALL*)(renderer::Transparency * transparency, + GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height))0x00000001404A88F0; + renderer::Transparency* transparency = new renderer::Transparency; + memset(transparency, 0, sizeof(*transparency)); + this->transparency = renderer__Transparency__Transparency(transparency, transparency_tex[0]->tex, + rend_texture[0].GetDepthTex(), render_post_width[0], render_post_height[0]); + } + + void Render::init_tone_map_buffers() { + for (int32_t i = 0; i < 5; i++) { + reduce_tex[i] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA16F, reduce_width[i], reduce_height[i], 0, 0, 0); + gl_state_bind_texture_2d(reduce_tex[i]->tex); + + const vec4 border_color = 0.0f; + glTexParameterfvDLL(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + } + + reduce_texture[0].SetColorDepthTextures(reduce_tex[0]->tex); + + exposure_history = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_R32F, 32, 1, 0, 0, 0); + + glGenTextures(1, &exposure_tex); + gl_state_bind_texture_2d(exposure_tex); + glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_R32F, 2, 2, 0, GL_RED, GL_FLOAT, 0); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_state_bind_texture_2d(0); + + exposure_texture.SetColorDepthTextures(exposure_tex); + + glGenTextures(1, &tonemap_lut_texture); + gl_state_bind_texture_2d(tonemap_lut_texture); + glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_RG16F, 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, 0, GL_RG, GL_HALF_FLOAT, 0); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + const GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + gl_state_bind_texture_2d(0); + + generate_mlaa_area_texture(this); + + glGenQueries(3, lens_shaft_query); + glGenQueries(3, lens_flare_query); + + for (GLuint& i : lens_shaft_query_data) + i = -1; + + for (GLuint& i : lens_flare_query_data) + i = -1; + + for (ExposureCharaData& i : exposure_chara_data) { + glGenQueries(3, i.query); + for (GLuint& j : i.query_data) + j = -1; + } + } + + void Render::resize(int32_t width, int32_t height) { + this->width = width; + this->height = height; + + if (ssaa) { + inner_width = 2 * width; + inner_height = 2 * height; + } + else { + inner_width = width; + inner_height = height; + } + + screen_x_offset = 0; + screen_y_offset = 0; + + screen_width = width; + screen_height = height; + + update_res(true, 1); + + rend_texture[0].Init(render_post_width[0], render_post_height[0], 0, GL_RGBA16F, GL_DEPTH_COMPONENT24); + + gl_state_bind_texture_2d(rend_texture[0].GetColorTex()); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + gl_state_bind_texture_2d(rend_texture[0].GetDepthTex()); + GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + + for (int32_t i = 0; i < 3; i++) { + texture_free(taa_tex[i]); + taa_tex[i] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + taa_buffer[i].SetColorDepthTextures(taa_tex[i]->tex, 0, rend_texture[0].GetDepthTex()); + } + + texture_free(aet_back_tex); + aet_back_tex = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA8, render_post_width[0], render_post_height[0], 0, 0, 0); + aet_back_texture.SetColorDepthTextures(aet_back_tex->tex, 0, rend_texture[0].GetDepthTex()); + + mlaa_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_DEPTH_COMPONENT24); + temp_buffer.Init(render_post_width[0], render_post_height[0], 0, GL_RGBA8, GL_ZERO); + sss_contour_texture = &mlaa_buffer; + + gl_state_bind_texture_2d(mlaa_buffer.GetDepthTex()); + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + + for (int32_t i = 1; i < downsample_count; i++) { + rend_texture[i].Init(render_post_width[i], render_post_height[i], 0, GL_RGBA16F, GL_ZERO); + + gl_state_bind_texture_2d(rend_texture[i].GetColorTex()); + glTexParameteriDLL(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + dof->resize(render_post_width[0], render_post_height[0]); + + for (int32_t i = 0; i < 1; i++) + if (transparency_tex[i]) { + texture_free(transparency_tex[i]); + transparency_tex[i] = 0; + texture_counter--; + } + + transparency_tex[0] = texture_load_tex_2d(texture_id(0x25, texture_counter++), + GL_RGBA16F, render_post_width[0], render_post_height[0], 0, 0, 0); + transparency->resize(transparency_tex[0]->tex, rend_texture[0].GetDepthTex(), + render_post_width[0], render_post_height[0]); + } + + void Render::downsample() { + uniform->arr[U_REDUCE] = 1; + shaders_ft.set(SHADER_FT_REDUCE); + for (int32_t i = 1; i < downsample_count - 1; i++) { + rend_texture[i].Bind(); + gl_state_active_bind_texture_2d(0, rend_texture[i - 1].GetColorTex()); + glViewportDLL(0, 0, render_width[i], render_height[i]); + draw_quad( + render_post_width[i - 1], render_post_height[i - 1], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + } + + uniform->arr[U_REDUCE] = 3; + shaders_ft.set(SHADER_FT_REDUCE); + + int32_t downsample = max_def(downsample_count - 2, 0); + glViewportDLL(0, 0, reduce_width[0], reduce_height[0]); + reduce_texture[0].Bind(); + gl_state_active_bind_texture_2d(0, rend_texture[downsample].GetColorTex()); + draw_quad( + render_post_width[downsample], render_post_height[downsample], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.1f, 1.1f, 1.1f, 0.0f); + + downsample_texture.Bind(); + gl_state_active_bind_texture_2d(0, reduce_tex[0]->tex); + for (int32_t i = 1; i < 5; i++) { + float_t scale; + if (i == 4) { + scale = 1.0f; + uniform->arr[U_EXPOSURE] = 0; + shaders_ft.set(SHADER_FT_EXPOSURE); + } + else + { + scale = 0.75; + uniform->arr[U_REDUCE] = 1; + shaders_ft.set(SHADER_FT_REDUCE); + } + + glViewportDLL(0, 0, reduce_width[i], reduce_height[i]); + draw_quad(reduce_width[i - 1], reduce_height[i - 1], + 1.0f, 1.0f, 0.0f, 0.0f, scale, 1.0f, 1.0f, 1.0f, 1.0f); + gl_state_active_bind_texture_2d(0, reduce_tex[i]->tex); + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + } + } + + void Render::transparency_combine(float_t alpha) { + transparency->combine(rend_texture, alpha); + } + + void Render::transparency_copy() { + transparency->copy(rend_texture[0].GetColorTex()); + } + + void Render::update_res(bool set, int32_t base_downsample) { + int32_t hd_res_widths[4]; + int32_t hd_res_heights[4]; + hd_res_widths[0] = 1280; + hd_res_heights[0] = 720; + hd_res_widths[1] = 1024; + hd_res_heights[1] = 576; + hd_res_widths[2] = 1024; + hd_res_heights[2] = 576; + hd_res_widths[3] = 960; + hd_res_heights[3] = 544; + + base_downsample = min_def(base_downsample, 3); + + if (set) + this->base_downsample = base_downsample; + else + base_downsample = max_def(base_downsample, this->base_downsample); + + base_downsample = clamp_def(base_downsample, 0, 3); + + int32_t hd_res_width = hd_res_widths[base_downsample]; + int32_t hd_res_height = hd_res_heights[base_downsample]; + if (hd_res && (screen_width > hd_res_width || screen_height > hd_res_height)) { + render_width[0] = hd_res_width; + render_height[0] = hd_res_height; + + if (set) { + inner_width = render_width[0]; + inner_height = render_height[0]; + } + } + else { + /*float_t round_val = ssaa ? 1.0f : 16.0f; + render_width[0] = (int32_t)(prj::ceilf((float_t)screen_width + * (float_t)inner_width / (float_t)width * (1.0f / round_val)) * round_val); + render_height[0] = (int32_t)(prj::ceilf((float_t)screen_height + * (float_t)inner_height / (float_t)height * (1.0f / round_val)) * round_val);*/ + + render_width[0] = (int32_t)prj::ceilf((float_t)screen_width + * (float_t)inner_width / (float_t)width); + render_height[0] = (int32_t)prj::ceilf((float_t)screen_height + * (float_t)inner_height / (float_t)height); + } + + int32_t downsample = 1; + for (int32_t i = 0; i < 4; i++) { + int32_t width = (render_width[i] + 1) / 2; + int32_t height = (render_height[i] + 1) / 2; + if (width <= reduce_width[0] && height <= reduce_height[0]) + break; + + render_width[i + 1] = width; + render_height[i + 1] = height; + downsample++; + } + this->downsample_count = downsample; + + if (set) { + downsample_max_count = downsample; + for (int32_t i = 0; i < downsample; i++) { + render_post_width[i] = render_width[i]; + render_post_height[i] = render_height[i]; + } + } + + render_post_width_scale = (float_t)render_width[0] / (float_t)render_post_width[0]; + render_post_height_scale = (float_t)render_height[0] / (float_t)render_post_height[0]; + + taa_blend = -1.0f; + } + + void Render::apply_mlaa(int32_t ss_alpha_mask) { + gl_state_begin_event("PostProcess::mlaa"); + mlaa_buffer.Bind(); + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_bind_sampler(0, rctx->render_samplers[1]); + uniform->arr[U_MLAA] = 0; + shaders_ft.set(SHADER_FT_MLAA); + draw_quad(render_post_width[0], render_post_height[0], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + + temp_buffer.Bind(); + gl_state_active_bind_texture_2d(0, mlaa_buffer.GetColorTex()); + gl_state_active_bind_texture_2d(1, mlaa_area_texture); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + gl_state_bind_sampler(1, rctx->render_samplers[1]); + uniform->arr[U_MLAA] = 1; + uniform->arr[U_MLAA_SEARCH] = 2; + shaders_ft.set(SHADER_FT_MLAA); + draw_quad(render_post_width[0], render_post_height[0], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + + RenderTexture& buf_texture = rctx->render_buffer; + buf_texture.Bind(); + gl_state_active_bind_texture_2d(0, taa_tex[2]->tex); + gl_state_active_bind_texture_2d(1, temp_buffer.GetColorTex()); + gl_state_bind_sampler(0, rctx->render_samplers[1]); + uniform->arr[U_MLAA] = 2; + uniform->arr[U_ALPHA_MASK] = ss_alpha_mask ? 1 : 0; + shaders_ft.set(SHADER_FT_MLAA); + draw_quad(render_post_width[0], render_post_height[0], + render_post_width_scale, render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + uniform->arr[U_ALPHA_MASK] = 0; + gl_state_active_bind_texture_2d(0, 0); + gl_state_active_bind_texture_2d(1, 0); + + fbo_blit(buf_texture.fbos[0], taa_buffer[2].fbos[0], + 0, 0, buf_texture.GetWidth(), buf_texture.GetHeight(), + 0, 0, taa_tex[2]->width, taa_tex[2]->height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + gl_state_end_event(); + } + + void Render::apply_tone_map() { + if (!this) + return; + + gl_state_begin_event("PostProcess::tone_map"); + + update_tone_map_lut(); + + uniform->arr[U_TONE_MAP] = (int32_t)tone_map; + uniform->arr[U_FLARE] = 0; + uniform->arr[U_SCENE_FADE] = scene_fade_alpha[scene_fade_index] > 0.01f ? 1 : 0; + uniform->arr[U_AET_BACK] = 0; + uniform->arr[U_LIGHT_PROJ] = 0; + //uniform->arr[U25] = 0; + + gl_state_active_bind_texture_2d(0, rend_texture[0].GetColorTex()); + gl_state_active_bind_texture_2d(1, reduce_tex_draw); + gl_state_active_bind_texture_2d(2, tonemap_lut_texture); + gl_state_active_bind_texture_2d(3, exposure_tex); + gl_state_active_bind_texture_2d(4, rctx->empty_texture_2d); + gl_state_active_bind_texture_2d(5, rctx->empty_texture_2d); + gl_state_active_bind_texture_2d(6, rctx->empty_texture_2d); + + if (aet_back) { + gl_state_active_bind_texture_2d(6, aet_back_tex->tex); + uniform->arr[U_AET_BACK] = 1; + } + + static texture* (FASTCALL * litproj_texture_get)() = (texture * (FASTCALL*)())0x0000000140350600; + texture* light_proj_tex = litproj_texture_get(); + if (light_proj_tex) { + gl_state_active_bind_texture_2d(6, light_proj_tex->tex); + uniform->arr[U_LIGHT_PROJ] = 1; + } + + int32_t scene_fade_blend_func = this->scene_fade_blend_func[scene_fade_index]; + + tone_map_shader_data shader_data; + shader_data.g_exposure.x = exposure * exposure_rate; + shader_data.g_exposure.y = 0.0625f; + shader_data.g_exposure.z = exposure * exposure_rate * 0.5f; + shader_data.g_exposure.w = auto_exposure ? 1.0f : 0.0f; + shader_data.g_flare_coef.x = (lens_flare * 2.0f) * (lens_flare_appear_power + lens_flare_power); + shader_data.g_flare_coef.y = lens_shaft * 2.0f; + shader_data.g_flare_coef.z = 0.0f; + shader_data.g_flare_coef.w = 0.0f; + *(vec3*)&shader_data.g_fade_color = scene_fade_color[scene_fade_index]; + shader_data.g_fade_color.w = scene_fade_alpha[scene_fade_index]; + if (scene_fade_blend_func == 1 || scene_fade_blend_func == 2) + *(vec3*)&shader_data.g_fade_color *= shader_data.g_fade_color.w; + *(vec3*)&shader_data.g_tone_scale = tone_trans_scale[tone_trans_index]; + *(vec3*)&shader_data.g_tone_offset = tone_trans_offset[tone_trans_index]; + shader_data.g_tone_scale.w = (float_t)scene_fade_blend_func; + shader_data.g_tone_offset.w = gamma > 0.0f ? 2.0f / (gamma * 3.0f) : 0.0f; + + shader_data.g_texcoord_transforms[0] = { 1.0f, 0.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[1] = { 0.0f, 1.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[2] = { 1.0f, 0.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[3] = { 0.0f, 1.0f, 0.0f, 0.0f }; + + if (lens_flare_texture) { + static const vec4 border_color = 0.0f; + + const float_t aspect = (float_t)height / (float_t)width; + + uniform->arr[U_FLARE] = 1; + gl_state_active_bind_texture_2d(4, lens_flare_texture); + gl_state_bind_sampler(4, rctx->render_samplers[2]); + mat4 mat; + mat4_translate(0.5f, 0.5f, 0.0f, &mat); + mat4_scale_rot(&mat, 0.75f, 0.75f, 1.0f, &mat); + mat4_mul_rotate_z(&mat, (lens_flare_pos.x / (float_t)width) + * 25.0f * DEG_TO_RAD_FLOAT, &mat); + mat4_mul_translate(&mat, -((1.0f / (float_t)width) * lens_flare_pos.x), + (lens_flare_pos.y - (float_t)height) * (1.0f / (float_t)width), 0.0f, &mat); + mat4_scale_rot(&mat, 1.0f, aspect, 1.0f, &mat); + mat4_transpose(&mat, &mat); + shader_data.g_texcoord_transforms[4] = mat.row0; + shader_data.g_texcoord_transforms[5] = mat.row1; + + if (lens_shaft_scale < 50.0f) { + uniform->arr[U_FLARE] = 2; + gl_state_active_bind_texture_2d(5, lens_shaft_texture); + gl_state_bind_sampler(5, rctx->render_samplers[2]); + mat4_translate(0.5f, 0.5f, 0.0f, &mat); + mat4_scale_rot(&mat, lens_shaft_scale, lens_shaft_scale, 1.0f, &mat); + mat4_mul_rotate_z(&mat, (lens_flare_pos.x / (float_t)width) + * 60.0f * DEG_TO_RAD_FLOAT, &mat); + mat4_mul_translate(&mat, -((1.0f / (float_t)width) * lens_flare_pos.x), + (lens_flare_pos.y - (float_t)height) * (1.0f / (float_t)width), 0.0f, &mat); + mat4_scale_rot(&mat, 1.0f, aspect, 1.0f, &mat); + mat4_transpose(&mat, &mat); + shader_data.g_texcoord_transforms[6] = mat.row0; + shader_data.g_texcoord_transforms[7] = mat.row1; + } + else { + shader_data.g_texcoord_transforms[6] = { 1.0f, 0.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[7] = { 0.0f, 1.0f, 0.0f, 0.0f }; + } + } + else { + shader_data.g_texcoord_transforms[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[5] = { 0.0f, 1.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[6] = { 1.0f, 0.0f, 0.0f, 0.0f }; + shader_data.g_texcoord_transforms[7] = { 0.0f, 1.0f, 0.0f, 0.0f }; + } + + if (render_manager->npr_param == 1) { + /*gl_state_active_bind_texture_2d(16, sss_contour_texture->GetColorTex()); + gl_state_bind_sampler(16, rctx->render_samplers[1]); + gl_state_active_bind_texture_2d(17, sss_contour_texture->GetDepthTex()); + gl_state_bind_sampler(17, rctx->render_samplers[1]);*/ + gl_state_active_bind_texture_2d(14, rend_texture[0].GetDepthTex()); + gl_state_bind_sampler(14, rctx->render_samplers[1]); + } + + rctx->tone_map_ubo.WriteMemory(shader_data); + + glViewportDLL(0, 0, render_width[0], render_height[0]); + taa_buffer[2].Bind(); + shaders_ft.set(SHADER_FT_TONEMAP); + rctx->tone_map_ubo.Bind(1); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + gl_state_active_bind_texture_2d(2, 0); + gl_state_end_event(); + } + + + void Render::calc_exposure() { + bool v2 = false; + if (!reset_exposure) { + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) + exposure_chara_data[i].reset(); + + ExposureCharaData* chara_data = exposure_chara_data; + float_t v18 = (float_t)height / (float_t)width; + float_t v20 = powf(tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT) * 3.4f, 2.0f); + size_t rob_chara_smth = get_rob_chara_smth(); + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++, chara_data++) { + size_t rob_chr = rob_chara_array_get(rob_chara_smth, i); + if (!rob_chr || !(*(uint8_t*)(rob_chara_smth + 0x440) & 1)) + continue; + + vec4 v34 = { 0.05f, 0.0f, -0.04f, 1.0f }; + vec4 v33 = { 1.0f, 0.0f, 0.0f, 0.0f }; + + mat4 v44 = mat4_identity; + sub_1405163C0(rob_chr, 4, &v44); + + mat4 v42; + mat4 v43; + mat4_mul(&camera_data->view_matrix, &v44, &v42); + mat4_mul(&camera_data->projection_matrix, &v42, &v43); + + vec4 v41; + vec4 v40; + mat4_transform_vector(&v42, &v34, &v41); + mat4_transform_vector(&v43, &v34, &v40); + + float_t v12 = 1.0f / v40.w; + float_t v13 = v40.x * v12; + float_t v14 = v40.y * v12; + if (v41.z >= 0.0f || fabsf(v13) >= 1.0f || fabsf(v14) >= 1.0f) + continue; + + float_t v31 = 0.5f - (fabsf(v14) - 1.0f) * 2.5f; + float_t v32 = 0.5f - (fabsf(v13) - 1.0f) * 2.5f; + + float_t v16; + if (v32 <= v31) + v16 = v32; + else + v16 = v31; + + if (v16 > 1.0f) + v16 = 1.0f; + + vec4 v39; + mat4_transform_vector(&v42, &v33, &v39); + + float_t v17 = (v39.z + 1.0f) * 0.5f; + if (v17 > 0.8f) + v17 = 0.8f; + else if (v17 < 0.2f) + v17 = 0.0f; + + float_t v21 = 0.25f / sqrtf(powf(v20 * 3.4f, 2.0f) * (v41.z * v41.z)); + float_t v22; + if (v21 < 0.055f) { + v22 = (v21 - 0.035f) * 50.0f; + if (v22 < 0.0f) + v22 = 0.0f; + } + else if (v21 > 0.5f) { + v22 = 1.0f - (v21 - 0.5f) * 3.3333333f; + if (v22 < 0.0f) + v22 = 0.0f; + } + else + v22 = 1.0f; + + chara_data->spot_coefficients[0].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[0].y = (v14 + v21 * 0.1f + 1.0f) * 0.5f; + chara_data->spot_coefficients[0].z = 0.0f; + chara_data->spot_coefficients[0].w = 4.0f; + chara_data->spot_coefficients[1].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[1].y = (v14 - v21 * 0.3f + 1.0f) * 0.5f; + chara_data->spot_coefficients[1].z = 0.0f; + chara_data->spot_coefficients[1].w = 4.0f; + chara_data->spot_coefficients[2].x = (v13 + v21 * -0.5f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[2].y = (v14 + v21 * -0.5f + 1.0f) * 0.5f; + chara_data->spot_coefficients[2].z = 0.0f; + chara_data->spot_coefficients[2].w = 3.0f; + chara_data->spot_coefficients[3].x = (v13 - v21 * 0.6f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[3].y = (v14 - v21 * 0.1f + 1.0f) * 0.5f; + chara_data->spot_coefficients[3].z = 0.0f; + chara_data->spot_coefficients[3].w = 2.0f; + chara_data->spot_coefficients[4].x = (v13 + v21 * 0.6f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[4].y = (v14 - v21 * 0.1f + 1.0f) * 0.5f; + chara_data->spot_coefficients[4].z = 0.0f; + chara_data->spot_coefficients[4].w = 2.0f; + chara_data->spot_coefficients[5].x = (v13 + v21 * 0.5f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[5].y = (v14 + v21 * -0.5f + 1.0f) * 0.5f; + chara_data->spot_coefficients[5].z = 0.0f; + chara_data->spot_coefficients[5].w = 3.0f; + chara_data->spot_coefficients[6].x = (v13 + v21 * 0.0f * v18 + 1.0f) * 0.5f; + chara_data->spot_coefficients[6].y = (v14 - v21 * 0.8f + 1.0f) * 0.5f; + chara_data->spot_coefficients[6].z = 0.0f; + chara_data->spot_coefficients[6].w = 3.0f; + chara_data->spot_weight = v16 * 1.6f * v17 * v22; + if (chara_data->spot_weight > 0.0f && !chara_data->query_data[exposure_query_index]) + v2 = true; + } + } + + if (!v2 || reset_exposure) { + exposure_measure_shader_data exposure_measure = {}; + exposure_measure.g_spot_weight = { + exposure_chara_data[0].spot_weight, + exposure_chara_data[1].spot_weight, + exposure_chara_data[2].spot_weight, + exposure_chara_data[3].spot_weight + }; + + ExposureCharaData* chara_data = exposure_chara_data; + for (int32_t i = 0; i < 4 && i < ROB_CHARA_COUNT; i++, chara_data++) + for (int32_t j = 0; j < 8; j++) + exposure_measure.g_spot_coefficients[i * 8 + j] = chara_data->spot_coefficients[j]; + rctx->exposure_measure_ubo.WriteMemory(exposure_measure); + + glViewportDLL(0, 0, 1, 1); + downsample_texture.Bind(); + + uniform->arr[U_EXPOSURE] = 1; + shaders_ft.set(SHADER_FT_EXPOSURE); + rctx->exposure_measure_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, reduce_tex[4]->tex); + gl_state_active_bind_texture_2d(1, reduce_tex[2]->tex); + draw_quad(1, 1, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + + gl_state_active_bind_texture_2d(0, exposure_history->tex); + if (reset_exposure) + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 32, 1); + else + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, exposure_history_counter, 0, 0, 0, 1, 1); + exposure_history_counter = (exposure_history_counter + 1) % 32; + } + + glViewportDLL(0, 0, 1, 1); + exposure_texture.Bind(); + uniform->arr[U_EXPOSURE] = 2; + shaders_ft.set(SHADER_FT_EXPOSURE); + gl_state_active_bind_texture_2d(0, exposure_history->tex); + draw_quad(1, 1, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + } + + void Render::calc_gaussian_blur(float_t start, float_t step, + int32_t kernel_size, float_t radius_scale, float_t intensity_scale) { + auto calculate_gaussian_kernel = [&](float_t* gaussian_kernel, + float_t radius, int32_t stride, int32_t offset) { + float_t first_val = (start - step * 0.5f) * 2.0f; + for (int32_t i = 0; i < kernel_size; i++) + gaussian_kernel[i * stride + offset] = 0.0f; + + float_t temp_gaussian_kernel[20]; + float_t s = radius * radius_scale; + s = 1.0f / (2.0f * s * s); + + double_t sum = first_val; + temp_gaussian_kernel[0] = first_val; + float_t val = start; + for (size_t i = 1; i < kernel_size; i++) { + sum += temp_gaussian_kernel[i] = expf(-(val * val * s)) * step; + val += step; + } + + sum = 1.0f / sum; + for (size_t i = 0; i < kernel_size; i++) + gaussian_kernel[i * stride + offset] = (float_t)(temp_gaussian_kernel[i] * sum); + }; + + vec3 gauss[20]; + calculate_gaussian_kernel((float_t*)gauss, radius.x, 3, 0); + calculate_gaussian_kernel((float_t*)gauss, radius.y, 3, 1); + calculate_gaussian_kernel((float_t*)gauss, radius.z, 3, 2); + + vec3 intensity = this->intensity * (intensity_scale * 0.5f); + + gaussian_coef_shader_data gaussian_coef = {}; + for (int32_t i = 0; i < kernel_size && i < 8; i++) { + *(vec3*)&gaussian_coef.g_coef[i] = gauss[i] * intensity; + gaussian_coef.g_coef[i].w = 0.0f; + } + rctx->gaussian_coef_ubo.WriteMemory(gaussian_coef); + } + + static void make_ghost_quad(uint8_t flags, float_t opacity, mat4* mat, float_t*& data) { + const float_t x0 = flags & 0x01 ? 0.5f : 0.0f; + const float_t x1 = flags & 0x01 ? 1.0f : 0.5f; + const float_t y0 = flags & 0x02 ? 0.5f : 0.0f; + const float_t y1 = flags & 0x02 ? 1.0f : 0.5f; + + vec4 p0 = { -0.5f, -0.5f, x0, y0 }; + vec4 p1 = { 0.5f, -0.5f, x1, y0 }; + vec4 p2 = { -0.5f, 0.5f, x0, y1 }; + vec4 p3 = { 0.5f, 0.5f, x1, y1 }; + mat4_transform_point(mat, (vec2*)&p0, (vec2*)&p0); + mat4_transform_point(mat, (vec2*)&p1, (vec2*)&p1); + mat4_transform_point(mat, (vec2*)&p2, (vec2*)&p2); + mat4_transform_point(mat, (vec2*)&p3, (vec2*)&p3); + + *(vec4*)&data[0] = p0; + data[4] = opacity; + *(vec4*)&data[5] = p1; + data[9] = opacity; + *(vec4*)&data[10] = p2; + data[14] = opacity; + *(vec4*)&data[15] = p2; + data[19] = opacity; + *(vec4*)&data[20] = p1; + data[24] = opacity; + *(vec4*)&data[25] = p3; + data[29] = opacity; + data += 30; + } + + void Render::copy_to_frame_texture(GLuint pre_pp_tex, int32_t wight, int32_t height, GLuint post_pp_tex) { + for (Render::FrameTexture& i : frame_texture) { + if (!i.capture) + continue; + + for (auto& j : i.data) { + if (!j.texture || j.render_texture.Bind() < 0) + continue; + + texture* dst_tex = j.texture; + + gl_state_active_bind_texture_2d(0, j.type == FRAME_TEXTURE_PRE_PP ? pre_pp_tex : post_pp_tex); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + glViewportDLL(0, 0, dst_tex->width, dst_tex->height); + uniform->arr[U_REDUCE] = 0; + shaders_ft.set(SHADER_FT_REDUCE); + draw_quad(dst_tex->width, dst_tex->height, + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + gl_state_bind_framebuffer(0); + } + + i.capture = false; + } + } + + void Render::draw_lens_ghost() { + static const float_t v13[16] = { + -0.70f, -0.30f, 0.35f, 0.50f, + -0.45f, -0.80f, 0.20f, 0.41f, + 0.17f, -0.10f, 0.06f, 0.10f, + 0.14f, 0.04f, -0.13f, -0.22f, + }; + + static const float_t v14[16] = { + 0.8f, 1.0f, 1.0f, 1.0f, + 0.4f, 0.5f, 0.8f, 0.8f, + 0.6f, 0.7f, 0.8f, 0.7f, + 0.8f, 0.7f, 0.6f, 0.8f, + }; + + static const float_t v15[16] = { + 1.3f, 1.5f, 1.00f, 1.1f, + 2.5f, 0.8f, 0.50f, 0.5f, + 0.7f, 0.4f, 0.35f, 0.5f, + 0.4f, 0.3f, 0.60f, 0.4f, + }; + + if (!lens_flare_texture || lens_ghost_count <= 0) + return; + + if (lens_ghost_count > 16) + lens_ghost_count = 16; + + const float_t aspect = (float_t)render_width[0] / (float_t)render_height[0]; + + const float_t v7 = (lens_flare_pos.x - (float_t)(width / 2)) / (float_t)width; + const float_t v8 = -((lens_flare_pos.y - (float_t)(height / 2)) / (float_t)height); + const float_t v9 = (float_t)((1.1 - sqrtf(v8 * v8 + v7 * v7)) * lens_flare_power); + if (v9 < 0.001f) + return; + + const float_t v9a = v9 * v9; + + float_t angle = atan2f(v8, v7) - (float_t)M_PI_2; + const float_t angle_sin = sinf(angle); + const float_t angle_cos = cosf(angle); + + float_t* data = (float_t*)rctx->lens_ghost_vbo.MapMemory(); + if (!data) + return; + + const float_t lens_ghost = this->lens_ghost; + const int32_t lens_ghost_count = this->lens_ghost_count; + for (int32_t i = 0; i < lens_ghost_count; i++) { + float_t opacity = v9 * v14[i] * lens_ghost; + + float_t scale = (v9a * 0.03f + 0.02f) * v15[i]; + + mat4 mat; + mat4_translate(v13[i] * v7 + 0.5f, v13[i] * v8 + 0.5f, 0.0f, &mat); + mat4_scale_rot(&mat, scale, scale * aspect, 1.0f, &mat); + mat4_mul_rotate_z(&mat, angle_sin, angle_cos, &mat); + make_ghost_quad((uint8_t)(i & 0x03), opacity, &mat, data); + } + + rctx->lens_ghost_vbo.UnmapMemory(); + + glViewportDLL(0, 0, render_width[0], render_height[0]); + rend_texture[0].Bind(); + gl_state_enable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ONE); + + uniform->arr[U_REDUCE] = 4; + shaders_ft.set(SHADER_FT_REDUCE); + gl_state_active_bind_texture_2d(0, lens_ghost_texture); + gl_state_bind_vertex_array(rctx->lens_ghost_vao); + shaders_ft.draw_arrays(GL_TRIANGLES, 0, (GLsizei)(lens_ghost_count * 6LL)); + gl_state_bind_vertex_array(0); + + gl_state_disable_blend(); + gl_state_set_blend_func(GL_ONE, GL_ZERO); + } + + void Render::get_blur() { + uniform->arr[U_ALPHA_MASK] = 0; + uniform->arr[U_GAUSS] = 0; + shaders_ft.set(SHADER_FT_GAUSS); + calc_gaussian_blur(1.0f, 1.0f, 7, 0.8f, 1.0f); + rctx->gaussian_coef_ubo.Bind(1); + + downsample_texture.Bind(); + for (int32_t i = 1; i < 4; i++) { + glViewportDLL(0, 0, reduce_width[i], reduce_height[i]); + gl_state_active_bind_texture_2d(0, reduce_tex[i]->tex); + draw_quad(reduce_width[i], reduce_height[i], + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f); + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + } + + for (int32_t i = 1; i < 4; i++) { + glViewportDLL(0, 0, reduce_width[i], reduce_height[i]); + gl_state_active_bind_texture_2d(0, reduce_tex[i]->tex); + draw_quad(reduce_width[i], reduce_height[i], + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f); + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, reduce_width[i], reduce_height[i]); + } + + uniform->arr[U_GAUSS] = 1; + shaders_ft.set(SHADER_FT_GAUSS); + + glViewportDLL(0, 0, reduce_width[0], reduce_height[0]); + gl_state_active_bind_texture_2d(0, reduce_tex[0]->tex); + draw_quad(reduce_width[0], reduce_height[0], + 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + intensity.x * 0.5f, intensity.y * 0.5f, intensity.z * 0.5f, 1.0f); + + uniform->arr[U_REDUCE] = 7; + shaders_ft.set(SHADER_FT_REDUCE); + + glViewportDLL(0, 0, reduce_width[0], reduce_height[0]); + reduce_texture[0].Bind(); + gl_state_active_bind_texture_2d(0, downsample_texture.GetColorTex()); + gl_state_active_bind_texture_2d(1, reduce_tex[1]->tex); + gl_state_active_bind_texture_2d(2, reduce_tex[2]->tex); + gl_state_active_bind_texture_2d(3, reduce_tex[3]->tex); + draw_quad(reduce_width[3], reduce_height[3], + 1.0f, 1.0f, 0.0f, 0.0f, 0.25f, 0.15f, 0.25f, 0.25f, 0.25f); + reduce_tex_draw = reduce_tex[0]->tex; + } + + void Render::update_tone_map_lut() { + if (!update_lut) + return; + + update_lut = false; + saturate_lock = false; + + const float_t tone_map_scale = (float_t)(1.0 / (double_t)TONE_MAP_SAT_GAMMA_SAMPLES); + const int32_t tone_map_size = 16 * TONE_MAP_SAT_GAMMA_SAMPLES; + + vec2 tex_data[16 * TONE_MAP_SAT_GAMMA_SAMPLES]; + float_t gamma_power = gamma * gamma_rate * 1.5f; + int32_t saturate_power = this->saturate_power; + float_t saturate_coeff = this->saturate_coeff[saturate_index]; + + tex_data[0].x = 0.0f; + tex_data[0].y = 0.0f; + for (int32_t i = 1; i < tone_map_size; i++) { + float_t gamma = powf(1.0f - expf((float_t)-i * tone_map_scale), gamma_power); + float_t saturation = gamma * 2.0f - 1.0f; + for (int32_t j = 0; j < saturate_power; j++) { + saturation *= saturation; + saturation *= saturation; + saturation *= saturation; + saturation *= saturation; + } + + tex_data[i].x = gamma; + tex_data[i].y = gamma * saturate_coeff + * ((float_t)TONE_MAP_SAT_GAMMA_SAMPLES / (float_t)i) * (1.0f - saturation); + } + + if (GL_VERSION_4_5) + glTextureSubImage2D(tonemap_lut_texture, 0, 0, 0, + 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); + else { + gl_state_bind_texture_2d(tonemap_lut_texture); + glTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, + 16 * TONE_MAP_SAT_GAMMA_SAMPLES, 1, GL_RG, GL_FLOAT, tex_data); + } + } + + static void generate_mlaa_area_texture(Render* rend) { + uint8_t* data = (uint8_t*)malloc(MLAA_SIDE_LEN * MLAA_SIDE_LEN * 2); + if (!data) + return; + + for (int32_t cross2 = 0; cross2 < 5; cross2++) + for (int32_t cross1 = 0; cross1 < 5; cross1++) + calculate_mlaa_area_texture_data(data, cross1, cross2); + + glGenTextures(1, &rend->mlaa_area_texture); + gl_state_bind_texture_2d(rend->mlaa_area_texture); + glPixelStoreiDLL(GL_UNPACK_ALIGNMENT, 1); + glTexImage2DDLL(GL_TEXTURE_2D, 0, GL_RG8, MLAA_SIDE_LEN, MLAA_SIDE_LEN, 0, GL_RG, GL_UNSIGNED_BYTE, data); + gl_state_bind_texture_2d(0); + free(data); + } + + static void calculate_mlaa_area_texture_data(uint8_t* data, int32_t cross1, int32_t cross2) { + uint8_t* _data = &data[(MLAA_SIDE_LEN * MLAA_GRID_SIDE_LEN * cross2 + MLAA_GRID_SIDE_LEN * cross1) * 2]; + for (int32_t dright = 0; dright < MLAA_GRID_SIDE_LEN; dright++) { + for (int32_t dleft = 0; dleft < MLAA_GRID_SIDE_LEN; dleft++) { + float_t val_left = 0.0f; + float_t val_right = 0.0f; + calculate_mlaa_area_texture_data_inner(&val_left, &val_right, cross1, cross2, dleft, dright); + _data[0] = (uint8_t)(val_left * 255.9f); + _data[1] = (uint8_t)(val_right * 255.9f); + _data += 2; + } + _data += MLAA_GRID_SIDE_LEN * 4 * 2; + } + } + + static void calculate_mlaa_area_texture_data_inner(float_t* val_left, + float_t* val_right, int32_t cross1, int32_t cross2, int32_t dleft, int32_t dright) { + auto calc_area_tex_val = [&](int32_t a1, int32_t a2) { + float_t v2 = (float_t)(-0.5 / ((float_t)a2 - 0.5)); + float_t v3 = (float_t)a1 * v2 + 0.5f; + if (a1 >= a2 - 1) + return (v3 * 0.5f) * 0.5f; + else + return ((float_t)(a1 + 1) * v2 + 0.5f + v3) * 0.5f; + }; + + int32_t dist = dleft + dright + 1; + float_t _val_left = 0.0f; + float_t _val_right = 0.0f; + switch (cross2) { + case 0: + switch (cross1) { + case 1: + _val_right = calc_area_tex_val(dleft, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + case 3: + _val_left = calc_area_tex_val(dleft, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + } + break; + case 1: + switch (cross1) { + case 0: + _val_right = calc_area_tex_val(dright, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + case 1: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_right = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_right = calc_area_tex_val(dright, v12); + else + _val_right = calc_area_tex_val(v15, v12) * 2.0f; + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft >= v12) + _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + case 3: + case 4: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_left = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_right = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + } + break; + case 3: + switch (cross1) { + case 0: + _val_left = calc_area_tex_val(dright, min_def(dist, MLAA_GRID_SIDE_LEN)); + break; + case 1: + case 4: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_right = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_left = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + case 3: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_left = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_left = calc_area_tex_val(dright, v12); + else + _val_left = calc_area_tex_val(v15, v12) * 2.0f; + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + } + break; + case 4: + switch (cross1) { + case 1: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_right = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_left = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_right = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_left = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + case 3: + if (dist % 2) { + int32_t v12 = dist / 2 + 1; + int32_t v15 = dist / 2; + if (dleft < v15) + _val_left = calc_area_tex_val(dleft, v12); + else if (dright < v15) + _val_right = calc_area_tex_val(dright, v12); + else + _val_left = _val_right = calc_area_tex_val(v15, v12); + } + else { + int32_t v12 = dist / 2; + float_t v14 = -0.5f / (float_t)v12; + if (dleft < v12) + _val_left = ((float_t)(dleft * 2 + 1) * v14 + 1.0f) * 0.5f; + else + _val_right = ((float_t)(dright * 2 + 1) * v14 + 1.0f) * 0.5f; + } + break; + } + break; + } + + *val_left = _val_left; + *val_right = _val_right; + return; + } +} diff --git a/src/DivaGL/render.hpp b/src/DivaGL/render.hpp new file mode 100644 index 0000000..b86a6c6 --- /dev/null +++ b/src/DivaGL/render.hpp @@ -0,0 +1,204 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/light_param/glow.hpp" +#include "../KKdLib/vec.hpp" +#include "renderer/dof.hpp" +#include "renderer/transparency.hpp" +#include "camera.hpp" +#include "gl_uniform_buffer.hpp" + +namespace rndr { + struct Render { + enum MagFilterType { + MAG_FILTER_NEAREST = 0, + MAG_FILTER_BILINEAR, + MAG_FILTER_SHARPEN_5_TAP, + MAG_FILTER_SHARPEN_4_TAP, + MAG_FILTER_CONE_4_TAP, + MAG_FILTER_CONE_2_TAP, + MAG_FILTER_MAX, + }; + + enum FrameTextureType { + FRAME_TEXTURE_PRE_PP = 0, + FRAME_TEXTURE_POST_PP, + FRAME_TEXTURE_FB, + FRAME_TEXTURE_MAX, + }; + + struct ExposureCharaData { + vec4 spot_coefficients[8]; + float_t spot_weight; + GLuint query[3]; + GLuint query_data[3]; + + void reset(); + }; + + struct FrameTextureData { + texture* texture; + RenderTexture render_texture; + FrameTextureType type; + }; + + struct FrameTexture { + FrameTextureData data[4]; + bool capture; + }; + + int32_t downsample_count; + int32_t downsample_max_count; + int32_t ssaa; + int32_t taa; + int32_t mlaa; + int32_t cam_blur; + int32_t hd_res; + int32_t base_downsample; + int32_t ss_alpha_mask; + RenderTexture rend_texture[5]; + RenderTexture taa_buffer[3]; + texture* taa_tex[3]; + RenderTexture aet_back_texture; + texture* aet_back_tex; + RenderTexture downsample_texture; + RenderTexture reduce_texture[5]; + texture* reduce_tex[5]; + RenderTexture field_340; + GLuint reduce_tex_draw; + RenderTexture exposure_texture; + GLuint exposure_tex; + texture* exposure_history; + RenderTexture field_3B8; + RenderTexture field_3E8; + GLuint tonemap_lut_texture; + RenderTexture mlaa_buffer; + RenderTexture temp_buffer; + GLuint mlaa_area_texture; + RenderTexture* sss_contour_texture; + int32_t texture_counter; + GLuint lens_shaft_query[3]; + GLuint lens_flare_query[3]; + GLuint lens_shaft_query_data[3]; + GLuint lens_flare_query_data[3]; + int32_t lens_flare_query_index; + GLuint lens_flare_texture; + GLuint lens_shaft_texture; + GLuint lens_ghost_texture; + int32_t lens_ghost_count; + int32_t width; + int32_t height; + int32_t inner_width; + int32_t inner_height; + int32_t render_width[5]; + int32_t render_height[5]; + int32_t render_post_width[5]; + int32_t render_post_height[5]; + float_t render_post_width_scale; + float_t render_post_height_scale; + int32_t reduce_width[5]; + int32_t reduce_height[5]; + int32_t taa_texture_selector; + int32_t taa_texture; + float_t taa_blend; + vec3 view_point; + vec3 interest; + vec3 view_point_prev; + vec3 interest_prev; + mat4 cam_view_projection; + mat4 cam_view_projection_prev; + int32_t stage_index; + int32_t stage_index_prev; + bool reset_exposure; + int32_t screen_x_offset; + int32_t screen_y_offset; + int32_t screen_width; + int32_t screen_height; + int32_t update_lut; + int32_t saturate_lock; + ExposureCharaData exposure_chara_data[6]; + int32_t exposure_history_counter; + int32_t exposure_query_index; + vec3 lens_flare_pos; + float_t lens_shaft_scale; + float_t lens_shaft_inv_scale; + float_t lens_flare_power; + float_t field_A10; + float_t lens_flare_appear_power; + texture* render_textures_data[16]; + RenderTexture render_textures[16]; + texture* movie_textures_data[1]; + RenderTexture movie_textures[1]; + int32_t aet_back; + renderer::DOF3* dof; + texture* transparency_tex[1]; + renderer::Transparency* transparency; + int32_t saturate_index; + int32_t scene_fade_index; + int32_t tone_trans_index; + float_t saturate_coeff[2]; + vec3 scene_fade_color[2]; + float_t scene_fade_alpha[2]; + int32_t scene_fade_blend_func[2]; + vec3 tone_trans_scale[2]; + vec3 tone_trans_offset[2]; + vec3 tone_trans_start[2]; + vec3 tone_trans_end[2]; + tone_map_method tone_map; + float_t exposure; + float_t exposure_rate; + int32_t auto_exposure; + float_t gamma; + float_t gamma_rate; + int32_t saturate_power; + MagFilterType mag_filter; + float_t fade_alpha; + int32_t fade; + float_t lens_flare; + float_t lens_shaft; + float_t lens_ghost; + vec3 radius; + vec3 intensity; + int32_t update; + FrameTexture frame_texture[6]; + + void apply_post_process(); + void bind_render_texture(bool aet_back = false); + void calc_exposure_chara_data(); + void calc_projection_matrix(mat4* mat, double_t fov, double_t aspect, double_t z_near, double_t z_far, + double_t left_scale, double_t right_scale, double_t bottom_scale, double_t top_scale); + void ctrl(); + void draw_quad(int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, + float_t scale, float_t param_x, float_t param_y, float_t param_z, float_t param_w); + void draw_lens_flare(); + void free(); + void init_render_buffers(int32_t width, int32_t height, + int32_t ssaa, int32_t hd_res, int32_t ss_alpha_mask); + void init_tone_map_buffers(); + void resize(int32_t width, int32_t height); + void transparency_combine(float_t alpha); + void transparency_copy(); + void update_res(bool set, int32_t base_downsample); + + private: + void apply_mlaa(int32_t ss_alpha_mask); + void apply_tone_map(); + void calc_exposure(); + void calc_gaussian_blur(float_t start, float_t step, + int32_t kernel_size, float_t radius_scale, float_t intensity_scale); + void copy_to_frame_texture(GLuint pre_pp_tex, int32_t wight, int32_t height, GLuint post_pp_tex); + void draw_lens_ghost(); + void downsample(); + void get_blur(); + void update_tone_map_lut(); + }; + + static_assert(sizeof(rndr::Render) == 0x1510, "\"rndr::Render\" struct should have a size of 0x1510"); +} + +extern rndr::Render* render; diff --git a/src/DivaGL/render_context.cpp b/src/DivaGL/render_context.cpp new file mode 100644 index 0000000..9082bb4 --- /dev/null +++ b/src/DivaGL/render_context.cpp @@ -0,0 +1,516 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "render_context.hpp" +#include "render_manager.hpp" + +void draw_state_stats::reset() { + object_draw_count = 0; + object_translucent_draw_count = 0; + object_reflect_draw_count = 0; + field_C = 0; + field_10 = 0; + draw_count = 0; + draw_triangle_count = 0; + field_1C = 0; +} + +draw_state_struct* draw_state = (draw_state_struct*)0x00000001411A32B0; + +render_context* rctx; + +sss_data* (FASTCALL* sss_data_get)() + = (sss_data * (FASTCALL*)())0x0000000140641B70; + +void obj_scene_shader_data::set_g_irradiance_r_transforms(const mat4& mat) { + mat4 temp; + mat4_transpose(&mat, &temp); + g_irradiance_r_transforms[0] = temp.row0; + g_irradiance_r_transforms[1] = temp.row1; + g_irradiance_r_transforms[2] = temp.row2; + g_irradiance_r_transforms[3] = temp.row3; +} + +void obj_scene_shader_data::set_g_irradiance_g_transforms(const mat4& mat) { + mat4 temp; + mat4_transpose(&mat, &temp); + g_irradiance_g_transforms[0] = temp.row0; + g_irradiance_g_transforms[1] = temp.row1; + g_irradiance_g_transforms[2] = temp.row2; + g_irradiance_g_transforms[3] = temp.row3; +} + +void obj_scene_shader_data::set_g_irradiance_b_transforms(const mat4& mat) { + mat4 temp; + mat4_transpose(&mat, &temp); + g_irradiance_b_transforms[0] = temp.row0; + g_irradiance_b_transforms[1] = temp.row1; + g_irradiance_b_transforms[2] = temp.row2; + g_irradiance_b_transforms[3] = temp.row3; +} + +void obj_scene_shader_data::set_g_normal_tangent_transforms(const mat4& mat) { + mat4 temp; + mat4_transpose(&mat, &temp); + g_normal_tangent_transforms[0] = temp.row0; + g_normal_tangent_transforms[1] = temp.row1; + g_normal_tangent_transforms[2] = temp.row2; +} + +void obj_scene_shader_data::set_g_self_shadow_receivers(int32_t index, const mat4& mat) { + size_t _index = index * 3LL; + + mat4 temp; + mat4_transpose(&mat, &temp); + g_self_shadow_receivers[_index + 0] = temp.row0; + g_self_shadow_receivers[_index + 1] = temp.row1; + g_self_shadow_receivers[_index + 2] = temp.row2; +} + +void obj_scene_shader_data::set_g_light_projection(const mat4& mat) { + mat4 temp; + mat4_transpose(&mat, &temp); + g_light_projection[0] = temp.row0; + g_light_projection[1] = temp.row1; + g_light_projection[2] = temp.row2; + g_light_projection[3] = temp.row3; +} + +void obj_scene_shader_data::set_projection_view(const mat4& view, const mat4& proj) { + mat4 temp; + mat4_transpose(&view, &temp); + g_view[0] = temp.row0; + g_view[1] = temp.row1; + g_view[2] = temp.row2; + + mat4_invert(&view, &temp); + mat4_transpose(&temp, &temp); + g_view_inverse[0] = temp.row0; + g_view_inverse[1] = temp.row1; + g_view_inverse[2] = temp.row2; + + mat4_mul(&view, &proj, &temp); + mat4_transpose(&temp, &temp); + g_projection_view[0] = temp.row0; + g_projection_view[1] = temp.row1; + g_projection_view[2] = temp.row2; + g_projection_view[3] = temp.row3; +} + +void obj_batch_shader_data::set_g_joint(const mat4& mat) { + mat4 temp; + mat4_transpose(&mat, &temp); + g_joint[0] = temp.row0; + g_joint[1] = temp.row1; + g_joint[2] = temp.row2; + + mat4_invert(&mat, &temp); + mat4_transpose(&temp, &temp); + g_joint_inverse[0] = temp.row0; + g_joint_inverse[1] = temp.row1; + g_joint_inverse[2] = temp.row2; +} + +void obj_batch_shader_data::set_g_texcoord_transforms(int32_t index, const mat4& mat) { + size_t _index = index * 2LL; + + mat4 temp; + mat4_transpose(&mat, &temp); + g_texcoord_transforms[_index + 0] = temp.row0; + g_texcoord_transforms[_index + 1] = temp.row1; +} + +void obj_batch_shader_data::set_transforms(const mat4& model, const mat4& view, const mat4& proj) { + mat4 temp; + mat4_transpose(&model, &temp); + g_worlds[0] = temp.row0; + g_worlds[1] = temp.row1; + g_worlds[2] = temp.row2; + + mat4_invert(&model, &temp); + g_worlds_invtrans[0] = temp.row0; + g_worlds_invtrans[1] = temp.row1; + g_worlds_invtrans[2] = temp.row2; + + mat4 mv; + mat4_mul(&model, &view, &mv); + + mat4_transpose(&mv, &temp); + g_worldview[0] = temp.row0; + g_worldview[1] = temp.row1; + g_worldview[2] = temp.row2; + + mat4_invert(&mv, &temp); + mat4_transpose(&temp, &temp); + g_worldview_inverse[0] = temp.row0; + g_worldview_inverse[1] = temp.row1; + g_worldview_inverse[2] = temp.row2; + + mat4_mul(&mv, &proj, &temp); + mat4_transpose(&temp, &temp); + g_transforms[0] = temp.row0; + g_transforms[1] = temp.row1; + g_transforms[2] = temp.row2; + g_transforms[3] = temp.row3; +} + +render_context::render_context() : box_vao(), lens_ghost_vao(), common_vao(), +reflect_buffer(), render_buffer(), screen_buffer(), shadow_buffer(), empty_texture_2d(), +empty_texture_cube_map(), samplers(), render_samplers(), sprite_samplers(), sprite_width(), +sprite_height(), screen_x_offset(), screen_y_offset(), screen_width(), screen_height() { + static const float_t box_texcoords[] = { + 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, -1.5f, -1.5f, 0.5f, 1.5f, -0.5f, -0.5f, 1.5f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f, + 3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f, + 3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f, + 3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f, + 3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f, + 3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f, + 3.5f, -3.5f, -1.5f, -3.5f, 1.5f, -1.5f, -3.5f, -1.5f, + 3.5f, 1.5f, -1.5f, 1.5f, 1.5f, 3.5f, -3.5f, 3.5f, + }; + + glGenVertexArrays(1, &box_vao); + gl_state_bind_vertex_array(box_vao); + + box_vbo.Create(sizeof(box_texcoords), box_texcoords); + box_vbo.Bind(); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 4)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 8)); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(float_t) * 16, (void*)(sizeof(float_t) * 12)); + + glGenVertexArrays(1, &lens_ghost_vao); + gl_state_bind_vertex_array(lens_ghost_vao); + + lens_ghost_vbo.Create(sizeof(float_t) * 5 * (6 * 16)); + lens_ghost_vbo.Bind(); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float_t) * 5, (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float_t) * 5, (void*)(sizeof(float_t) * 2)); + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + + glGenVertexArrays(1, &common_vao); + + contour_coef_ubo.Create(sizeof(contour_coef_shader_data)); + contour_params_ubo.Create(sizeof(contour_params_shader_data)); + filter_scene_ubo.Create(sizeof(filter_scene_shader_data)); + esm_filter_batch_ubo.Create(sizeof(esm_filter_batch_shader_data)); + imgfilter_batch_ubo.Create(sizeof(imgfilter_batch_shader_data)); + exposure_measure_ubo.Create(sizeof(exposure_measure_shader_data)); + gaussian_coef_ubo.Create(sizeof(gaussian_coef_shader_data)); + glass_eye_batch_ubo.Create(sizeof(glass_eye_batch_shader_data)); + glitter_batch_ubo.Create(sizeof(glitter_batch_shader_data)); + quad_ubo.Create(sizeof(quad_shader_data)); + sprite_scene_ubo.Create(sizeof(sprite_scene_shader_data)); + sss_filter_gaussian_coef_ubo.Create(sizeof(sss_filter_gaussian_coef_shader_data)); + sun_quad_ubo.Create(sizeof(sun_quad_shader_data)); + tone_map_ubo.Create(sizeof(tone_map_shader_data)); + + obj_scene = {}; + obj_batch = {}; + obj_skinning = {}; + obj_scene_ubo.Create(sizeof(obj_scene_shader_data)); + obj_batch_ubo.Create(sizeof(obj_batch_shader_data)); + obj_skinning_ubo.Create(sizeof(obj_skinning_shader_data)); + + static const uint8_t empty_texture_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + static const GLenum target_cube_map_array[] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z + }; + + glGenTextures(1, &empty_texture_2d); + gl_state_bind_texture_2d(empty_texture_2d); + texture_set_params(GL_TEXTURE_2D, 0, false); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 0, 8, empty_texture_data); + gl_state_bind_texture_2d(0); + + glGenTextures(1, &empty_texture_cube_map); + gl_state_bind_texture_cube_map(empty_texture_cube_map); + texture_set_params(GL_TEXTURE_CUBE_MAP, 0, false); + for (int32_t side = 0; side < 6; side++) + glCompressedTexImage2D(target_cube_map_array[side], 0, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 0, 8, empty_texture_data); + gl_state_bind_texture_cube_map(0); + + static const vec4 border_color = 0.0f; + + glGenSamplers(18, samplers); + for (int32_t i = 0; i < 18; i++) { + GLuint sampler = samplers[i]; + + glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, + i % 2 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); + + GLuint wrap_s; + switch (i / 2 % 3) { + case 0: + wrap_s = GL_CLAMP_TO_EDGE; + break; + case 1: + wrap_s = GL_REPEAT; + break; + case 2: + wrap_s = GL_MIRRORED_REPEAT; + break; + } + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, wrap_s); + + GLenum wrap_t; + switch (i / 6 % 3) { + case 0: + wrap_t = GL_CLAMP_TO_EDGE; + break; + case 1: + wrap_t = GL_REPEAT; + break; + case 2: + wrap_t = GL_MIRRORED_REPEAT; + break; + } + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, wrap_t); + } + + GLuint sampler; + glGenSamplers(3, render_samplers); + sampler = render_samplers[0]; + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + sampler = render_samplers[1]; + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + sampler = render_samplers[2]; + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + + glGenSamplers(3, sprite_samplers); + sampler = sprite_samplers[0]; + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); + + sampler = sprite_samplers[1]; + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); + + sampler = sprite_samplers[2]; + glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); +} + +render_context::~render_context() { + glDeleteSamplers(3, sprite_samplers); + glDeleteSamplers(3, render_samplers); + glDeleteSamplers(18, samplers); + + glDeleteTextures(1, &empty_texture_cube_map); + glDeleteTextures(1, &empty_texture_2d); + + obj_skinning_ubo.Destroy(); + obj_batch_ubo.Destroy(); + obj_scene_ubo.Destroy(); + + tone_map_ubo.Destroy(); + transparency_batch_ubo.Destroy(); + sun_quad_ubo.Destroy(); + sss_filter_gaussian_coef_ubo.Destroy(); + sprite_scene_ubo.Destroy(); + quad_ubo.Destroy(); + glitter_batch_ubo.Destroy(); + glass_eye_batch_ubo.Destroy(); + gaussian_coef_ubo.Destroy(); + exposure_measure_ubo.Destroy(); + imgfilter_batch_ubo.Destroy(); + esm_filter_batch_ubo.Destroy(); + filter_scene_ubo.Destroy(); + contour_params_ubo.Destroy(); + contour_coef_ubo.Destroy(); + + if (common_vao) { + glDeleteVertexArrays(1, &common_vao); + common_vao = 0; + } + + if (lens_ghost_vao) { + glDeleteVertexArrays(1, &lens_ghost_vao); + lens_ghost_vao = 0; + } + + lens_ghost_vbo.Destroy(); + + if (box_vao) { + glDeleteVertexArrays(1, &box_vao); + box_vao = 0; + } + + box_vbo.Destroy(); +} + +void render_context::ctrl(bool change_res) { + RECT rect; + extern size_t diva_handle; + GetClientRect((HWND)diva_handle, &rect); + + int32_t width = rect.right - rect.left; + int32_t height = rect.bottom - rect.top; + if (screen_width == width && screen_height == height) + return; + + static const double_t aspect = 16.0 / 9.0; + + double_t res_width = (double_t)width; + double_t res_height = (double_t)height; + double_t view_aspect = res_width / res_height; + if (view_aspect < aspect) + res_height = round(res_width / aspect); + else if (view_aspect > aspect) + res_width = round(res_height * aspect); + + int32_t render_width = (int32_t)res_width; + int32_t render_height = (int32_t)res_height; + int32_t sprite_width = (int32_t)res_width; + int32_t sprite_height = (int32_t)res_height; + int32_t screen_width = width; + int32_t screen_height = height; + + //bool render_res_change = render->inner_width != render_width || render->inner_height != render_height; + bool sprite_res_change = this->sprite_width != sprite_width || this->sprite_height != sprite_height; + bool screen_res_change = this->screen_width != screen_width || this->screen_height != screen_height; + + this->sprite_width = sprite_width; + this->sprite_height = sprite_height; + + screen_x_offset = (screen_width - sprite_width) / 2 + (screen_width - sprite_width) % 2; + screen_y_offset = (screen_height - sprite_height) / 2 + (screen_height - sprite_height) % 2; + + this->screen_width = screen_width; + this->screen_height = screen_height; + + if (!change_res || /*!render_res_change && */!sprite_res_change && !screen_res_change) + return; + + /*if (render_res_change) + render.resize(render_width, render_height);*/ + + if (sprite_res_change) + render_manager->resize(sprite_width, sprite_height); + + /*if (render_res_change) + litproj_texture->Init(render_width, render_height, 0, GL_RGBA8, GL_DEPTH_COMPONENT32F);*/ + + /*sprite_manager_set_res((double_t)sprite_width / (double_t)sprite_height, + sprite_width, sprite_height);*/ + + /*if (render_res_change) { + auto init_copy_buffer = [&](RenderTexture& src, RenderTexture& dst) { + dst.Init(src.GetWidth(), + src.GetHeight(), 0, src.color_texture->internal_format, + src.depth_texture ? src.depth_texture->internal_format : GL_ZERO); + }; + + RenderTexture& render_buffer = render->rend_texture[0]; + RenderTexture& reflect_buffer = render_manager->get_render_texture(1); + RenderTexture& shadow_buffer = shadow_ptr_get()->render_textures[1]; + init_copy_buffer(reflect_buffer, this->reflect_buffer); + init_copy_buffer(render_buffer, this->render_buffer); + init_copy_buffer(shadow_buffer, this->shadow_buffer); + }*/ + + if (sprite_res_change) + screen_buffer.Init(sprite_width, sprite_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F +} + +void render_context::free() { + shadow_buffer.Free(); + screen_buffer.Free(); + render_buffer.Free(); + reflect_buffer.Free(); +} + +void render_context::init() { + ctrl(false); + + auto init_copy_buffer = [&](RenderTexture& src, RenderTexture& dst) { + dst.Init(src.GetWidth(), + src.GetHeight(), 0, src.color_texture->internal_format, + src.depth_texture ? src.depth_texture->internal_format : GL_ZERO); + }; + + RenderTexture& render_buffer = render->rend_texture[0]; + RenderTexture& reflect_buffer = render_manager->get_render_texture(1); + RenderTexture& shadow_buffer = shadow_ptr_get()->render_textures[1]; + init_copy_buffer(reflect_buffer, this->reflect_buffer); + init_copy_buffer(render_buffer, this->render_buffer); + init_copy_buffer(shadow_buffer, this->shadow_buffer); + + screen_buffer.Init(sprite_width, sprite_height, 0, GL_RGBA16F, 0); // Was GL_R11F_G11F_B10F +} + +void fbo_blit(GLuint src_fbo, GLuint dst_fbo, + GLint src_x, GLint src_y, GLint src_width, GLint src_height, + GLint dst_x, GLint dst_y, GLint dst_width, GLint dst_height, GLbitfield mask, GLenum filter) { + gl_state_bind_read_framebuffer(src_fbo); + gl_state_bind_draw_framebuffer(dst_fbo); + glBlitFramebuffer(src_x, src_y, src_x + src_width, src_y + src_height, + dst_x, dst_y, dst_x + dst_width, dst_y + dst_height, mask, filter); +} diff --git a/src/DivaGL/render_context.hpp b/src/DivaGL/render_context.hpp new file mode 100644 index 0000000..8aea63c --- /dev/null +++ b/src/DivaGL/render_context.hpp @@ -0,0 +1,331 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "light_param/fog.hpp" +#include "light_param/light.hpp" +#include "mdl/disp_manager.hpp" +#include "camera.hpp" +#include "gl_array_buffer.hpp" +#include "gl_element_array_buffer.hpp" +#include "gl_uniform_buffer.hpp" +#include "render.hpp" +#include "render_manager.hpp" +#include "render_texture.hpp" + +#define TEXTURE_PATTERN_COUNT 24 +#define TEXTURE_TRANSFORM_COUNT 24 + +struct draw_state_stats { + int32_t object_draw_count; + int32_t object_translucent_draw_count; + int32_t object_reflect_draw_count; + int32_t field_C; + int32_t field_10; + int32_t draw_count; + int32_t draw_triangle_count; + int32_t field_1C; + + void reset(); +}; + +struct sss_data { + bool init; + bool enable; + bool npr_contour; + RenderTexture textures[4]; + vec4 param; +}; + +struct draw_state_struct { + draw_state_stats stats; + draw_state_stats stats_prev; + bool vertex_buffer; + bool wireframe; + bool wireframe_overlay; + bool light; + bool self_shadow; + bool shader_debug_flag; + bool use_global_material; + bool fog_height; + bool back_display; + int32_t shader_index; + int32_t show; + float_t bump_depth; + float_t intensity; + float_t reflectivity; + float_t reflect_uv_scale; + float_t refract_uv_scale; + int32_t field_68; + void* curr_obj_sub_mesh_args; + float_t fresnel; + GLuint program_buffer_index; + void* program_buffer_matrix_data; +}; + +struct contour_coef_shader_data { + vec4 g_contour; + vec4 g_near_far; +}; + +struct contour_params_shader_data { + vec4 g_near_far; +}; + +struct filter_scene_shader_data { + vec4 g_transform; + vec4 g_texcoord; +}; + +struct exposure_measure_shader_data { + vec4 g_spot_weight; + vec4 g_spot_coefficients[32]; +}; + +struct gaussian_coef_shader_data { + vec4 g_coef[8]; +}; + +struct esm_filter_batch_shader_data { + vec4 g_params; + vec4 g_gauss[2]; +}; + +struct imgfilter_batch_shader_data { + vec4 g_texture_lod; + vec4 g_color_scale; + vec4 g_color_offset; +}; + +struct glass_eye_batch_shader_data { + vec4 g_ellipsoid_radius; + vec4 g_ellipsoid_scale; + vec4 g_tex_model_param; + vec4 g_tex_offset; + vec4 g_eb_radius; + vec4 g_eb_tex_model_param; + vec4 g_fresnel; + vec4 g_refract1; + vec4 g_refract2; + vec4 g_iris_radius; + vec4 g_cornea_radius; + vec4 g_pupil_radius; + vec4 g_tex_scale; +}; + +struct glitter_batch_shader_data { + vec4 g_mvp[4]; + vec4 g_glitter_blend_color; + vec4 g_state_material_diffuse; + vec4 g_state_material_emission; +}; + +struct obj_scene_shader_data { + vec4 g_irradiance_r_transforms[4]; + vec4 g_irradiance_g_transforms[4]; + vec4 g_irradiance_b_transforms[4]; + vec4 g_light_env_stage_diffuse; + vec4 g_light_env_stage_specular; + vec4 g_light_env_chara_diffuse; + vec4 g_light_env_chara_ambient; + vec4 g_light_env_chara_specular; + vec4 g_light_env_reflect_diffuse; + vec4 g_light_env_reflect_ambient; + vec4 g_light_env_proj_diffuse; + vec4 g_light_env_proj_specular; + vec4 g_light_env_proj_position; + vec4 g_light_stage_dir; + vec4 g_light_stage_diff; + vec4 g_light_stage_spec; + vec4 g_light_chara_dir; + vec4 g_light_chara_spec; + vec4 g_light_chara_luce; + vec4 g_light_chara_back; + vec4 g_light_face_diff; + vec4 g_chara_color_rim; + vec4 g_chara_color0; + vec4 g_chara_color1; + vec4 g_chara_f_dir; + vec4 g_chara_f_ambient; + vec4 g_chara_f_diffuse; + vec4 g_chara_tc_param; + vec4 g_fog_depth_color; + vec4 g_fog_height_params; //x=density, y=start, z=end, w=1/(end-start) + vec4 g_fog_height_color; + vec4 g_fog_bump_params; //x=density, y=start, z=end, w=1/(end-start) + vec4 g_fog_state_params; //x=density, y=start, z=end, w=1/(end-start) + vec4 g_normal_tangent_transforms[3]; + vec4 g_esm_param; + vec4 g_self_shadow_receivers[6]; + vec4 g_shadow_ambient; + vec4 g_shadow_ambient1; + vec4 g_framebuffer_size; + vec4 g_light_reflect_dir; + vec4 g_clip_plane; + vec4 g_npr_cloth_spec_color; + vec4 g_view[3]; + vec4 g_view_inverse[3]; + vec4 g_projection_view[4]; + vec4 g_view_position; + vec4 g_light_projection[4]; + + void set_g_irradiance_r_transforms(const mat4& mat); + void set_g_irradiance_g_transforms(const mat4& mat); + void set_g_irradiance_b_transforms(const mat4& mat); + void set_g_normal_tangent_transforms(const mat4& mat); + void set_g_self_shadow_receivers(int32_t index, const mat4& mat); + void set_g_light_projection(const mat4& mat); + + void set_projection_view(const mat4& view, const mat4& proj); +}; + +struct obj_batch_shader_data { + vec4 g_transforms[4]; + vec4 g_worlds[3]; + vec4 g_worlds_invtrans[3]; + vec4 g_worldview[3]; + vec4 g_worldview_inverse[3]; + vec4 g_joint[3]; + vec4 g_joint_inverse[3]; + vec4 g_texcoord_transforms[4]; + vec4 g_blend_color; + vec4 g_offset_color; + vec4 g_material_state_diffuse; + vec4 g_material_state_ambient; + vec4 g_material_state_emission; + vec4 g_material_state_shininess; + vec4 g_material_state_specular; + vec4 g_fresnel_coefficients; + vec4 g_texture_color_coefficients; + vec4 g_texture_color_offset; + vec4 g_texture_specular_coefficients; + vec4 g_texture_specular_offset; + vec4 g_shininess; + vec4 g_max_alpha; + vec4 g_morph_weight; + vec4 g_sss_param; + vec4 g_bump_depth; + vec4 g_intensity; + vec4 g_reflect_uv_scale; + vec4 g_texture_blend; + + void set_g_joint(const mat4& mat); + void set_g_texcoord_transforms(int32_t index, const mat4& mat); + + void set_transforms(const mat4& model, const mat4& view, const mat4& proj); +}; + +struct obj_skinning_shader_data { + vec4 g_joint_transforms[768]; +}; + +struct quad_shader_data { + vec4 g_texcoord_modifier; + vec4 g_texel_size; + vec4 g_color; + vec4 g_texture_lod; +}; + +struct sprite_scene_shader_data { + mat4 g_transform; + vec4 g_framebuffer_size; +}; + +struct sss_filter_gaussian_coef_shader_data { + vec4 g_param; + vec4 g_coef[64]; +}; + +struct sun_quad_shader_data { + vec4 g_transform[4]; + vec4 g_emission; +}; + +struct tone_map_shader_data { + vec4 g_exposure; + vec4 g_flare_coef; + vec4 g_fade_color; + vec4 g_tone_scale; //xyz=tone_scale, w=fade_func + vec4 g_tone_offset; //xyz=tone_offset, w=inv_tone + vec4 g_texcoord_transforms[8]; +}; + +struct render_context { + mat4 view_mat; + mat4 proj_mat; + mat4 vp_mat; + vec4 g_near_far; + + GLuint box_vao; + GLArrayBuffer box_vbo; + + GLuint lens_ghost_vao; + GLArrayBuffer lens_ghost_vbo; + + GLuint common_vao; + + RenderTexture reflect_buffer; + RenderTexture render_buffer; + RenderTexture screen_buffer; + RenderTexture shadow_buffer; + + GLUniformBuffer contour_coef_ubo; + GLUniformBuffer contour_params_ubo; + GLUniformBuffer filter_scene_ubo; + GLUniformBuffer esm_filter_batch_ubo; + GLUniformBuffer imgfilter_batch_ubo; + GLUniformBuffer exposure_measure_ubo; + GLUniformBuffer gaussian_coef_ubo; + GLUniformBuffer glass_eye_batch_ubo; + GLUniformBuffer glitter_batch_ubo; + GLUniformBuffer quad_ubo; + GLUniformBuffer sprite_scene_ubo; + GLUniformBuffer sss_filter_gaussian_coef_ubo; + GLUniformBuffer sun_quad_ubo; + GLUniformBuffer transparency_batch_ubo; + GLUniformBuffer tone_map_ubo; + + obj_scene_shader_data obj_scene; + obj_batch_shader_data obj_batch; + obj_skinning_shader_data obj_skinning; + GLUniformBuffer obj_scene_ubo; + GLUniformBuffer obj_batch_ubo; + GLUniformBuffer obj_skinning_ubo; + + GLuint empty_texture_2d; + GLuint empty_texture_cube_map; + + GLuint samplers[18]; + GLuint render_samplers[3]; + GLuint sprite_samplers[3]; + + int32_t sprite_width; + int32_t sprite_height; + int32_t screen_x_offset; + int32_t screen_y_offset; + int32_t screen_width; + int32_t screen_height; + + render_context(); + ~render_context(); + + void ctrl(bool change_res = true); + void free(); + void init(); +}; + +extern draw_state_struct* draw_state; + +extern render_context* rctx; + +extern sss_data* (FASTCALL* sss_data_get)(); + +void fbo_blit(GLuint src_fbo, GLuint dst_fbo, + GLint src_x, GLint src_y, GLint src_width, GLint src_height, + GLint dst_x, GLint dst_y, GLint dst_width, GLint dst_height, GLbitfield mask, GLenum filter); diff --git a/src/DivaGL/render_manager.cpp b/src/DivaGL/render_manager.cpp new file mode 100644 index 0000000..b49137c --- /dev/null +++ b/src/DivaGL/render_manager.cpp @@ -0,0 +1,1781 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "render_manager.hpp" +#include "../KKdLib/mat.hpp" +#include "Glitter/glitter.hpp" +#include "light_param/fog.hpp" +#include "light_param/light.hpp" +#include "mdl/disp_manager.hpp" +#include "rob/rob.hpp" +#include "gl_state.hpp" +#include "render.hpp" +#include "render_context.hpp" +#include "render_texture.hpp" +#include "shader_glsl_ft.hpp" +#include "sprite.hpp" +#include "stage_param.hpp" +#include "texture.hpp" +#include + +static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3); +static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, int32_t index, int32_t a3); +static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, + RenderTexture* a3, float_t sigma, float_t far_texel_offset, bool enable_lit_proj); +static void draw_pass_shadow_esm_filter(RenderTexture* dst, RenderTexture* buf, RenderTexture* src); +static bool draw_pass_shadow_litproj(); +static bool draw_pass_shadow_litproj_set(); +static bool draw_pass_shadow_litproj_set_mat(bool set_mat); +static void draw_pass_sss_contour(rndr::Render* rend); +static void draw_pass_sss_filter(sss_data* sss); +static int32_t draw_pass_3d_get_translucent_count(); +static void draw_pass_3d_shadow_reset(); +static void draw_pass_3d_shadow_set(Shadow* shad); +extern void draw_pass_3d_translucent(bool opaque_enable, + bool transparent_enable, bool translucent_enable, mdl::ObjType opaque, + mdl::ObjType transparent, mdl::ObjType translucent); +static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, + mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent); +static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type); + +static void blur_filter_apply(RenderTexture* dst, RenderTexture* src, + blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset); + +extern render_context* rctx; + +RenderTexture* litproj_shadow = (RenderTexture*)0x0000000141194DA0; +RenderTexture* litproj_texture = (RenderTexture*)0x0000000141194E00; +rndr::RenderManager* render_manager = (rndr::RenderManager*)0x00000001411AD320; + +namespace rndr { + static const int32_t render_manager_render_texture_index_array[][3] = { + { 1, 1, 1 }, + { 0, 0, 0 }, + { 6, 6, 6 }, + { 6, 6, 6 }, + { 6, 6, 6 }, + { 2, 2, 2 }, + { 3, 3, 3 }, + { 4, 4, 4 }, + { 5, 5, 5 }, + { 6, 6, 6 }, + { 7, 7, 7 }, + }; + + void RenderManager::add_pre_process(int32_t type, void(*func)(void*), void* data) { + pre_process.push_back({ type, func, data }); + } + + void RenderManager::clear_pre_process(int32_t type) { + for (std::list::iterator i = pre_process.begin(); i != pre_process.end(); i++) + if (i->type == type) { + pre_process.erase(i); + break; + } + } + + RenderTexture& RenderManager::get_render_texture(int32_t index) { + return render_textures[render_manager_render_texture_index_array[index][tex_index[index]]]; + } + + void RenderManager::resize(int32_t width, int32_t height) { + if (this->width == width && this->height == height) + return; + + this->width = width; + this->height = height; + + if (!multisample_framebuffer) + glGenFramebuffers(1, &multisample_framebuffer); + + if (!multisample_renderbuffer) + glGenRenderbuffers(1, &multisample_renderbuffer); + + glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, multisample_renderbuffer); + glDrawBufferDLL(GL_COLOR_ATTACHMENT0); + glReadBufferDLL(GL_COLOR_ATTACHMENT0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + + void RenderManager::set_effect_texture(texture* value) { + effect_texture = value; + } + + void RenderManager::set_multisample(bool value) { + multisample = value; + } + + void RenderManager::set_npr_param(int32_t value) { + npr_param = value; + } + + void RenderManager::set_pass_sw(RenderPassID id, bool value) { + pass_sw[id] = value; + } + + void RenderManager::set_reflect(bool value) { + reflect = value; + } + + void RenderManager::set_reflect_blur(int32_t reflect_blur_num, blur_filter_mode reflect_blur_filter) { + this->reflect_blur_num = reflect_blur_num; + this->reflect_blur_filter = reflect_blur_filter; + } + + void RenderManager::set_reflect_resolution_mode(reflect_refract_resolution_mode mode) { + tex_index[0] = mode; + } + + void RenderManager::set_reflect_type(stage_data_reflect_type type) { + reflect_type = type; + } + + void RenderManager::set_refract(bool value) { + refract = value; + } + + void RenderManager::set_refract_resolution_mode(reflect_refract_resolution_mode mode) { + tex_index[1] = mode; + } + + void RenderManager::set_shadow_false() { + shadow = false; + } + + void RenderManager::set_shadow_true() { + shadow = true; + } + + void RenderManager::render_all() { + static const int32_t ibl_texture_index[] = { + 9, 10, 11, 12, 13 + }; + + rctx->obj_scene.g_framebuffer_size = { + 1.0f / (float_t)render->render_width[0], + 1.0f / (float_t)render->render_height[0], + (float_t)render->render_width[0], + (float_t)render->render_height[0] + }; + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl_state_enable_depth_test(); + gl_state_set_depth_func(GL_LEQUAL); + gl_state_set_depth_mask(GL_TRUE); + + gl_state_begin_event("rndpass_render_all_pass::Caller::execute_pre3d"); + for (int32_t i = RND_PASSID_SHADOW; i <= RND_PASSID_CLEAR; i++) + RenderManager::render_single_pass((RenderPassID)i); + gl_state_end_event(); + + gl_state_begin_event("rndpass_render_all_pass::Caller::execute_3d"); + for (int32_t i = RND_PASSID_PRE_SPRITE; i <= RND_PASSID_3D; i++) + RenderManager::render_single_pass((RenderPassID)i); + gl_state_end_event(); + + gl_state_begin_event("rndpass_render_all_pass::Caller::execute_2d"); + for (int32_t i = RND_PASSID_SHOW_VECTOR; i <= RND_PASSID_12; i++) + RenderManager::render_single_pass((RenderPassID)i); + gl_state_end_event(); + + disp_manager->check_vertex_arrays(); + gl_state_bind_vertex_array(0); + gl_state_disable_primitive_restart(); + gl_state_bind_uniform_buffer_base(0, 0); + gl_state_bind_uniform_buffer_base(1, 0); + gl_state_bind_uniform_buffer_base(2, 0); + gl_state_bind_uniform_buffer_base(3, 0); + gl_state_bind_uniform_buffer_base(4, 0); + } + + void RenderManager::render_single_pass(RenderPassID id) { + cpu_time[id] = 0.0; + gpu_time[id] = 0.0; + if (!pass_sw[id]) { + gl_state_get_error(); + return; + } + + render_pass_begin(); + switch (id) { + case RND_PASSID_SHADOW: + pass_shadow(); + break; + case RND_PASSID_SS_SSS: + pass_ss_sss(); + break; + case RND_PASSID_REFLECT: + pass_reflect(); + break; + case RND_PASSID_REFRACT: + pass_refract(); + break; + case RND_PASSID_PRE_PROCESS: + pass_pre_process(); + break; + case RND_PASSID_CLEAR: + pass_clear(); + break; + case RND_PASSID_PRE_SPRITE: + pass_pre_sprite(); + break; + case RND_PASSID_3D: + pass_3d(); + break; + case RND_PASSID_SHOW_VECTOR: + pass_show_vector(); + break; + case RND_PASSID_POST_PROCESS: + pass_post_process(); + break; + case RND_PASSID_SPRITE: + pass_sprite(); + break; + } + render_pass_end(id); + gl_state_get_error(); + } + + void RenderManager::render_pass_begin() { + if (sync_gpu) + glFinishDLL(); + time.get_timestamp(); + } + + void RenderManager::render_pass_end(RenderPassID id) { + cpu_time[id] = time.calc_time(); + if (sync_gpu) { + time_struct t; + glFinishDLL(); + gpu_time[id] = t.calc_time(); + } + else + gpu_time[id] = 0; + } + + void RenderManager::pass_shadow() { + gl_state_begin_event("pass_shadow"); + if (draw_pass_shadow_litproj_set()) { + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); + disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); + disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); + + draw_state->shader_index = -1; + uniform->arr[U0A] = 0; + draw_pass_shadow_filter(&litproj_shadow[0], &litproj_shadow[1], 0, 1.5f, 0.01f, true); + + if (draw_pass_shadow_litproj()) { + draw_pass_set_camera(); + + for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) + light_set_data[i].data_set((light_set_id)i); + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); + disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_state_enable_blend(); + disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); + gl_state_disable_blend(); + draw_state->shader_index = -1; + gl_state_bind_framebuffer(0); + } + } + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + bool v3 = false; + int32_t v10[2]; + for (int32_t i = 0; i < 2; i++) { + v10[i] = disp_manager->get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + i)); + if (v10[i]) + v3 = true; + } + + Shadow* shad = shadow_ptr; + if (shadow && v3) { + int32_t v11[2]; + v11[0] = shad->field_200[0]; + v11[1] = shad->field_200[1]; + shad->curr_render_textures[0] = &shad->render_textures[0]; + shad->curr_render_textures[1] = &shad->render_textures[1]; + shad->curr_render_textures[2] = &shad->render_textures[2]; + + for (int32_t i = 0, j = 0; i < 2; i++) { + if (!v10[i]) + continue; + + draw_pass_shadow_begin_make_shadowmap(shad, v11[i], j); + disp_manager->draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_CHARA + v11[i])); + if (disp_manager->get_obj_count((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + v11[i])) > 0) { + gl_state_set_color_mask(field_2F8 ? GL_TRUE : GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + disp_manager->draw((mdl::ObjType)(mdl::OBJ_TYPE_SHADOW_OBJECT_CHARA + i)); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } + draw_pass_shadow_end_make_shadowmap(shad, v11[i], j); + j++; + } + } + else { + shad->curr_render_textures[0] = &shad->render_textures[0]; + shad->curr_render_textures[1] = &shad->render_textures[1]; + shad->curr_render_textures[2] = &shad->render_textures[2]; + + for (int32_t i = 1; i < 3; i++) + for (int32_t j = 0; j < 4; j++) { + shad->curr_render_textures[i]->Bind(j); + glClearColorDLL(1.0f, 1.0f, 1.0f, 1.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + } + } + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event(); + } + + void RenderManager::pass_ss_sss() { + ::sss_data* sss = sss_data_get(); + if (!sss->init || !sss->enable) + return; + + gl_state_begin_event("pass_ss_sss"); + rndr::Render* rend = render; + //if (rend->render_width > 1280.0) + // sss->npr_contour = false; + + //if (sss->npr_contour) { + rend->rend_texture[0].Bind(); + rend->rend_texture[0].SetViewport(); + //} + //else { + // sss->textures[0].Bind(); + // glViewportDLL(0, 0, 640, 360); + //} + + glClearColorDLL(sss->param.x, sss->param.y, sss->param.z, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_pass_set_camera(); + for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) + light_set_data[i].data_set((light_set_id)i); + + if (shadow) + draw_pass_3d_shadow_set(shadow_ptr); + else + draw_pass_3d_shadow_reset(); + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + draw_state->shader_index = SHADER_FT_SSS_SKIN; + gl_state_enable_depth_test(); + gl_state_set_depth_func(GL_LEQUAL); + gl_state_set_depth_mask(GL_TRUE); + disp_manager->draw(mdl::OBJ_TYPE_SSS); + gl_state_disable_depth_test(); + draw_state->shader_index = -1; + draw_pass_3d_shadow_reset(); + uniform->arr[U_NPR] = 0; + + if (npr_param == 1) { + if (sss->enable && sss->npr_contour) { + uniform->arr[U_NPR] = 1; + draw_pass_sss_contour(rend); + } + else if (npr) { + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + rend->rend_texture[0].Bind(); + rend->rend_texture[0].SetViewport(); + glClearDLL(GL_DEPTH_BUFFER_BIT); + draw_state->shader_index = SHADER_FT_SSS_SKIN; + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + disp_manager->draw(mdl::OBJ_TYPE_SSS); + gl_state_disable_depth_test(); + draw_state->shader_index = -1; + gl_state_bind_framebuffer(0); + uniform->arr[U_NPR] = 1; + draw_pass_sss_contour(rend); + } + } + + if (!sss->npr_contour) { + sss->textures[0].Bind(); + glViewportDLL(0, 0, 640, 360); + + filter_scene_shader_data filter_scene = {}; + filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f }; + filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; + rctx->filter_scene_ubo.WriteMemory(filter_scene); + + imgfilter_batch_shader_data imgfilter_batch = {}; + imgfilter_batch.g_color_scale = 1.0f; + imgfilter_batch.g_color_offset = 0.0f; + imgfilter_batch.g_texture_lod = 0.0f; + rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch); + + uniform->arr[U_IMAGE_FILTER] = 5; + shaders_ft.set(SHADER_FT_IMGFILT); + rctx->filter_scene_ubo.Bind(0); + rctx->imgfilter_batch_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + } + + draw_pass_sss_filter(sss); + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event(); + } + + void RenderManager::pass_reflect() { + gl_state_begin_event("pass_reflect"); + RenderTexture& refl_tex = render_manager->get_render_texture(0); + RenderTexture& refl_buf_tex = rctx->reflect_buffer; + refl_tex.Bind(); + if (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE) + || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSPARENT) + || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT) + || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE) + || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSPARENT) + || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT)) { + refl_tex.SetViewport(); + + draw_pass_set_camera(); + + for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) + light_set_data[i].data_set((light_set_id)i); + for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) + fog_data[i].data_set((fog_id)i); + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_state->shader_index = SHADER_FT_S_REFL; + + light_set* set = &light_set_data[LIGHT_SET_MAIN]; + light_clip_plane clip_plane; + set->lights[LIGHT_SPOT].get_clip_plane(clip_plane); + uniform->arr[U_REFLECT] = 2; + uniform->arr[U_CLIP_PLANE] = clip_plane.data[1]; + + gl_state_enable_depth_test(); + gl_state_set_depth_func(GL_LEQUAL); + gl_state_set_depth_mask(GL_TRUE); + disp_manager->draw(mdl::OBJ_TYPE_REFLECT_OPAQUE, 0, field_31D); + if (reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { + gl_state_enable_blend(); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_state_set_blend_equation(GL_FUNC_ADD); + disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT); + gl_state_disable_blend(); + } + + if (reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { + uniform->arr[U_REFLECT] = field_31E; + uniform->arr[U_CLIP_PLANE] = clip_plane.data[0]; + disp_manager->draw(mdl::OBJ_TYPE_REFLECT_CHARA_OPAQUE); + } + gl_state_disable_depth_test(); + uniform->arr[U_REFLECT] = 0; + draw_state->shader_index = -1; + + refl_buf_tex.Bind(); + for (int32_t i = reflect_blur_num, j = 0; i > 0; i--, j++) { + blur_filter_apply(&refl_buf_tex, &refl_tex, + reflect_blur_filter, 1.0f, 1.0f, 0.0f); + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, refl_tex.GetWidth(), refl_tex.GetHeight()); + } + } + else { + vec4 clear_color; + glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + } + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event(); + } + + void RenderManager::pass_refract() { + gl_state_begin_event("pass_refract"); + RenderTexture& refract_texture = render_manager->get_render_texture(1); + refract_texture.Bind(); + if (disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_OPAQUE) + || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSPARENT) + || disp_manager->get_obj_count(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT)) { + texture* refr_tex = refract_texture.color_texture; + glViewportDLL(0, 0, refr_tex->width, refr_tex->height); + + draw_pass_set_camera(); + + for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) + light_set_data[i].data_set((light_set_id)i); + for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) + fog_data[i].data_set((fog_id)i); + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + vec4 clear_color; + glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + + draw_state->shader_index = SHADER_FT_S_REFR; + gl_state_enable_depth_test(); + gl_state_set_depth_func(GL_LEQUAL); + gl_state_set_depth_mask(GL_TRUE); + disp_manager->draw(mdl::OBJ_TYPE_REFRACT_OPAQUE); + disp_manager->draw(mdl::OBJ_TYPE_REFRACT_TRANSPARENT); + disp_manager->draw(mdl::OBJ_TYPE_REFRACT_TRANSLUCENT); + gl_state_disable_depth_test(); + draw_state->shader_index = -1; + } + else { + vec4 clear_color; + glGetFloatvDLL(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + glClearColorDLL(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + } + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event(); + } + + void RenderManager::pass_pre_process() { + return; + gl_state_begin_event("pass_pre_process"); + for (draw_pre_process& i : pre_process) + if (i.func) + i.func(i.data); + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event(); + } + + void RenderManager::pass_clear() { + void(FASTCALL * clear_color_set_gl)() = (void(FASTCALL*)())0x00000001405022A0; + + gl_state_begin_event("pass_clear"); + if (clear) { + rctx->screen_buffer.Bind(); + clear_color_set_gl(); + //glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearDLL(GL_COLOR_BUFFER_BIT); + gl_state_bind_framebuffer(0); + } + + rndr::Render* rend = render; + if (!sss_data_get()->enable || !sss_data_get()->npr_contour) { + rend->bind_render_texture(); + if (sprite_manager_get_reqlist_count(2)) { + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepthf(1.0f); + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gl_state_bind_framebuffer(0); + } + else { + clear_color_set_gl(); + glClearDepthf(1.0f); + if (clear) + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + else + glClearDLL(GL_DEPTH_BUFFER_BIT); + gl_state_bind_framebuffer(0); + } + } + else { + if (sprite_manager_get_reqlist_count(2)) { + rend->bind_render_texture(); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + gl_state_bind_framebuffer(0); + } + else if (clear) { + rend->bind_render_texture(); + clear_color_set_gl(); + glClearDLL(GL_COLOR_BUFFER_BIT); + gl_state_bind_framebuffer(0); + } + } + + gl_state_get_error(); + gl_state_end_event(); + } + + void RenderManager::pass_pre_sprite() { + if (!sprite_manager_get_reqlist_count(2)) + return; + + gl_state_begin_event("pass_pre_sprite"); + rndr::Render* rend = render; + rend->bind_render_texture(true); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + gl_state_set_depth_mask(GL_FALSE); + gl_state_disable_depth_test(); + gl_state_enable_blend(); + gl_state_disable_cull_face(); + sprite_manager_draw(2, true, + rend->temp_buffer.color_texture); + gl_state_enable_cull_face(); + gl_state_disable_blend(); + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + gl_state_get_error(); + gl_state_end_event(); + } + + void RenderManager::pass_3d() { + render->bind_render_texture(); + draw_pass_set_camera(); + if (!sss_data_get()->enable || !sss_data_get()->npr_contour + || draw_pass_3d_get_translucent_count()) + glClearDLL(GL_DEPTH_BUFFER_BIT); + + gl_state_set_depth_func(GL_LEQUAL); + + for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) + light_set_data[i].data_set((light_set_id)i); + for (int32_t i = FOG_DEPTH; i < FOG_MAX; i++) + fog_data[i].data_set((fog_id)i); + + if (shadow) + draw_pass_3d_shadow_set(shadow_ptr); + else + draw_pass_3d_shadow_reset(); + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + if (pass_sw[RND_PASSID_REFLECT] && reflect) { + RenderTexture& refl_tex = get_render_texture(0); + gl_state_active_bind_texture_2d(15, refl_tex.GetColorTex()); + uniform->arr[U_WATER_REFLECT] = 1; + } + else { + gl_state_active_bind_texture_2d(15, rctx->empty_texture_2d); + uniform->arr[U_WATER_REFLECT] = 0; + } + + uniform->arr[U12] = field_320 ? 1 : 0; + + if (effect_texture) + gl_state_active_bind_texture_2d(14, effect_texture->tex); + else + gl_state_active_bind_texture_2d(14, rctx->empty_texture_2d); + + gl_state_active_bind_texture_2d(16, sss_data_get()->textures[1].GetColorTex()); + gl_state_active_texture(0); + + if (alpha_z_sort) { + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW, 2); + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1, 1); + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2, 1); + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, 1); + //disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL, 1); + } + + if (opaque_z_sort) + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_OPAQUE, 0); + + if (draw_pass_3d[DRAW_PASS_3D_OPAQUE]) { + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + disp_manager->draw(mdl::OBJ_TYPE_OPAQUE); + gl_state_disable_depth_test(); + } + + Glitter::GltParticleManager__DispScenes(Glitter::glt_particle_manager, Glitter::DISP_OPAQUE); + + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + if (draw_pass_3d[DRAW_PASS_3D_TRANSPARENT]) + disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT); + if (render_manager->field_120) + disp_manager->draw(mdl::OBJ_TYPE_TYPE_7); + + render->calc_exposure_chara_data(); + + if (npr_param == 1) + pass_3d_contour(); + + render->draw_lens_flare(); + //star_catalog_draw(); + + draw_pass_3d_translucent( + draw_pass_3d[DRAW_PASS_3D_OPAQUE], + draw_pass_3d[DRAW_PASS_3D_TRANSPARENT], + draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT], + mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_3, + mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3); + + //snow_particle_draw(); + //rain_particle_draw(); + //leaf_particle_draw(); + //particle_draw(); + gl_state_disable_depth_test(); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::GltParticleManager__DispScenes(Glitter::glt_particle_manager, Glitter::DISP_ALPHA); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + /*if (npr_param == 1) { + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + }*/ + + gl_state_enable_depth_test(); + + if (draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT]) { + gl_state_enable_blend(); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_state_set_depth_mask(GL_FALSE); + disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW); + disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT); + gl_state_disable_blend(); + } + + //gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X + //Glitter::GltParticleManager__DispScenes(Glitter::glt_particle_manager, Glitter::DISP_TYPE_2); + //gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + gl_state_set_depth_mask(GL_TRUE); + draw_pass_3d_translucent( + draw_pass_3d[DRAW_PASS_3D_OPAQUE], + draw_pass_3d[DRAW_PASS_3D_TRANSPARENT], + draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT], + mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2, + mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2); + gl_state_disable_depth_test(); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::GltParticleManager__DispScenes(Glitter::glt_particle_manager, Glitter::DISP_NORMAL); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + draw_pass_3d_translucent( + draw_pass_3d[DRAW_PASS_3D_OPAQUE], + draw_pass_3d[DRAW_PASS_3D_TRANSPARENT], + draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT], + mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_1, + mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1); + +#if defined(CRE_DEV) + if (Glitter::glt_particle_manager->CheckHasLocalEffect()) { // X + camera* cam = camera_data; + double_t fov = cam->get_fov(); + cam->set_fov(32.2673416137695); + draw_pass_set_camera(); + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + disp_manager->draw(mdl::OBJ_TYPE_OPAQUE_LOCAL); + disp_manager->draw(mdl::OBJ_TYPE_TRANSPARENT_LOCAL); + gl_state_enable_blend(); + disp_manager->draw(mdl::OBJ_TYPE_TRANSLUCENT_LOCAL); + gl_state_disable_blend(); + + draw_pass_3d_translucent( + draw_pass_3d[DRAW_PASS_3D_OPAQUE], + draw_pass_3d[DRAW_PASS_3D_TRANSPARENT], + draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT], + mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL, + mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::GltParticleManager__DispScenes(Glitter::glt_particle_manager, Glitter::DISP_LOCAL); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + cam->set_fov(fov); + draw_pass_set_camera(); + } +#endif + + gl_state_active_bind_texture_2d(14, 0); + gl_state_active_bind_texture_2d(15, 0); + + gl_state_disable_depth_test(); + + if (shadow) + draw_pass_3d_shadow_reset(); + pass_sprite_surf(); + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + } + + void RenderManager::pass_show_vector() { + return; + /*if (!show_vector_flags) + return; + + gl_state_begin_event("pass_show_vector"); + + render->bind_render_texture(); + draw_pass_set_camera(); + + rctx->obj_scene_ubo.WriteMemory(rctx->obj_scene); + + if (alpha_z_sort) { + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT, 1); + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW, 2); + } + + if (opaque_z_sort) + disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_OPAQUE, 0); + + //shaders_ft.env_vert_set(20, show_vector_length, show_vector_z_offset, 0.0f, 0.0f); + for (int32_t i = 1; i < 4; i++) { + if (!(show_vector_flags & (1 << (i - 1)))) + continue; + + if (draw_pass_3d[DRAW_PASS_3D_OPAQUE]) + draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_OPAQUE, i); + if (draw_pass_3d[DRAW_PASS_3D_TRANSPARENT]) + draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_TRANSPARENT, i); + if (draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT]) { + draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_TRANSLUCENT_NO_SHADOW, i); + draw_task_draw_objects_by_type_show_vector(mdl::OBJ_TYPE_TRANSLUCENT, i); + } + } + shader::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event();*/ + } + + void RenderManager::pass_post_process() { + gl_state_begin_event("pass_post_process"); + render->apply_post_process(); + gl_state_end_event(); + } + + void RenderManager::pass_sprite() { + if (!sprite_manager_get_reqlist_count(0)) + return; + + gl_state_begin_event("pass_sprite"); + rndr::Render* rend = render; + glViewportDLL(0, 0, rctx->sprite_width, rctx->sprite_height); + + if (multisample && multisample_framebuffer) { + glBindFramebuffer(GL_FRAMEBUFFER, multisample_framebuffer); + gl_state_enable_multisample(); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + } + else + rctx->screen_buffer.Bind(); + + gl_state_disable_depth_test(); + gl_state_enable_blend(); + gl_state_disable_cull_face(); + sprite_manager_set_res((double_t)rctx->sprite_width / (double_t)rctx->sprite_height, + rctx->sprite_width, rctx->sprite_height); + sprite_manager_draw(0, true, + rend->temp_buffer.color_texture); + gl_state_enable_cull_face(); + gl_state_disable_blend(); + gl_state_enable_depth_test(); + + if (multisample && multisample_framebuffer) { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + gl_state_disable_multisample(); + gl_state_bind_read_framebuffer(multisample_framebuffer); + glBlitFramebuffer(0, 0, width, height, + 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + gl_state_bind_read_framebuffer(0); + } + gl_state_get_error(); + + fbo_blit(rctx->screen_buffer.fbos[0], 0, + 0, 0, rctx->sprite_width, rctx->sprite_height, + rctx->screen_x_offset, rctx->screen_y_offset, + rctx->sprite_width, rctx->sprite_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + shader_glsl::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event(); + } + + void RenderManager::pass_3d_contour() { + RenderTexture* rt = &render->rend_texture[0]; + RenderTexture* contour_rt = render->sss_contour_texture; + + gl_state_enable_blend(); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_state_set_blend_equation(GL_FUNC_ADD); + gl_state_disable_depth_test(); + + quad_shader_data quad_data = {}; + quad_data.g_texcoord_modifier = { 0.5f, 0.5f, 0.5f, 0.5f }; + rctx->quad_ubo.WriteMemory(quad_data); + + contour_params_shader_data contour_params_data = {}; + contour_params_data.g_near_far = rctx->g_near_far; + rctx->contour_params_ubo.WriteMemory(contour_params_data); + + shaders_ft.set(SHADER_FT_CONTOUR_NPR); + gl_state_active_bind_texture_2d(16, contour_rt->GetColorTex()); + gl_state_bind_sampler(16, rctx->render_samplers[1]); + gl_state_active_bind_texture_2d(17, contour_rt->GetDepthTex()); + gl_state_bind_sampler(17, rctx->render_samplers[1]); + gl_state_active_bind_texture_2d(14, rt->GetDepthTex()); + gl_state_bind_sampler(14, rctx->render_samplers[1]); + rctx->quad_ubo.Bind(0); + rctx->contour_params_ubo.Bind(2); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + + if (effect_texture) + gl_state_active_bind_texture_2d(14, effect_texture->tex); + else + gl_state_active_bind_texture_2d(14, rctx->empty_texture_2d); + gl_state_enable_depth_test(); + gl_state_disable_blend(); + } + + void RenderManager::pass_sprite_surf() { + if (!sprite_manager_get_reqlist_count(1)) + return; + + rndr::Render* rend = render; + + gl_state_set_depth_mask(GL_FALSE); + gl_state_disable_depth_test(); + gl_state_disable_depth_test(); + gl_state_enable_blend(); + gl_state_disable_cull_face(); + sprite_manager_draw(1, true, + rend->temp_buffer.color_texture); + } +} + +void image_filter_scale(GLuint dst, GLuint src, const vec4 scale) { + if (!dst || !src) + return; + + texture_param tex_params[2]; + texture_params_get(dst, &tex_params[0], src, &tex_params[1]); + + filter_scene_shader_data filter_scene = {}; + filter_scene.g_transform = { 1.0f, 1.0f, 0.0f, 0.0f }; + filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; + rctx->filter_scene_ubo.WriteMemory(filter_scene); + + imgfilter_batch_shader_data imgfilter_batch = {}; + imgfilter_batch.g_color_scale = 1.0f; + imgfilter_batch.g_color_offset = 0.0f; + imgfilter_batch.g_texture_lod = 0.0f; + rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch); + + uniform->arr[U_IMAGE_FILTER] = 5; + shaders_ft.set(SHADER_FT_IMGFILT); + rctx->filter_scene_ubo.Bind(0); + rctx->imgfilter_batch_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, src); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + + texture_params_restore(&tex_params[0], &tex_params[1]); +} + +void draw_pass_set_camera() { + camera_struct::update_data(); + mat4_transpose(&camera_data->view_matrix, &rctx->view_mat); + mat4_transpose(&camera_data->projection_matrix, &rctx->proj_mat); + mat4_transpose(&camera_data->view_projection_matrix, &rctx->vp_mat); + rctx->obj_scene.set_projection_view(rctx->view_mat, rctx->proj_mat); + *(vec3*)&rctx->obj_scene.g_view_position = camera_data->view_point; + rctx->obj_scene.g_view_position.w = 0.0f; + + float_t max_distance = camera_data->max_distance; + float_t min_distance = camera_data->min_distance; + rctx->g_near_far = { + (float_t)(max_distance / (max_distance - min_distance)), + (float_t)(-(max_distance * min_distance) / (max_distance - min_distance)), + 0.0f, 0.0f + }; +} + +HOOK(void, FASTCALL, render_manager_init_render_textures, 0x0000000140502560, int32_t multisample) { + rndr::RenderManager& render_manager = *::render_manager; + + if (multisample) { + glGenFramebuffers(1, &render_manager.multisample_framebuffer); + glGenRenderbuffers(1, &render_manager.multisample_renderbuffer); + + gl_state_bind_framebuffer(render_manager.multisample_framebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, render_manager.multisample_renderbuffer); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, + GL_RGBA8, render_manager.width, render_manager.height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, render_manager.multisample_renderbuffer); + glDrawBufferDLL(GL_COLOR_ATTACHMENT0); + glDrawBufferDLL(GL_COLOR_ATTACHMENT0); + gl_state_bind_framebuffer(0); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + if (glGetErrorDLL()) { + glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer); + render_manager.multisample_renderbuffer = 0; + glDeleteFramebuffers(1, &render_manager.multisample_framebuffer); + render_manager.multisample_framebuffer = 0; + } + } + + struct RenderTextureData { + GLenum type; + int32_t width; + int32_t height; + int32_t max_level; + GLenum color_format; + GLenum depth_format; + }; + + const RenderTextureData* render_manager_render_texture_data_array + = (const RenderTextureData*)0x0000000140A24420; + + for (int32_t i = 0; i < 9; i++) { + const RenderTextureData* tex_data = &render_manager_render_texture_data_array[i]; + if (tex_data->type != GL_TEXTURE_2D) + continue; + + RenderTexture& rt = render_manager.render_textures[i]; + rt.Init(tex_data->width, tex_data->height, tex_data->max_level, + tex_data->color_format, tex_data->depth_format); + rt.Bind(); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + gl_state_bind_framebuffer(0); +} + +HOOK(void, FASTCALL, render_manager_free_render_textures, 0x00000001405027A0) { + rndr::RenderManager& render_manager = *::render_manager; + + if (render_manager.multisample_renderbuffer) { + glDeleteRenderbuffers(1, &render_manager.multisample_renderbuffer); + render_manager.multisample_renderbuffer = 0; + } + + if (render_manager.multisample_framebuffer) { + glDeleteFramebuffers(1, &render_manager.multisample_framebuffer); + render_manager.multisample_framebuffer = 0; + } + + for (RenderTexture& i : render_manager.render_textures) + i.Free(); +} + +void render_manager_patch() { + INSTALL_HOOK(render_manager_init_render_textures); + INSTALL_HOOK(render_manager_free_render_textures); +} + +static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) { + shad->curr_render_textures[0]->Bind(); + shad->curr_render_textures[0]->SetViewport(); + texture* tex = shad->curr_render_textures[0]->color_texture; + glScissorDLL(0, 0, tex->width, tex->height); + gl_state_enable_depth_test(); + gl_state_enable_scissor_test(); + glClearColorDLL(1.0, 1.0, 1.0, 1.0); + if (!a3) + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + else if (shad->field_2F5) + glClearDLL(GL_COLOR_BUFFER_BIT); + glScissorDLL(1, 1, tex->width - 2, tex->height - 2); + + float_t offset = 0.0f; + float_t range = shad->view_region * shad->range; + vec3* interest; + vec3* view_point; + if (shad->field_2F5) { + offset = -0.5f; + if (index) + offset = 0.5f; + + interest = &shad->interest[index]; + view_point = &shad->view_point[index]; + } + else { + interest = &shad->interest_shared; + view_point = &shad->view_point_shared; + } + + mat4 temp; + mat4_translate(offset, 0.0f, 0.0f, &temp); + + mat4 proj; + mat4_ortho(-range, range, -range, range, shad->z_near, shad->z_far, &proj); + mat4_mul(&proj, &temp, &rctx->proj_mat); + mat4_look_at(view_point, interest, &rctx->view_mat); + + draw_state->shader_index = SHADER_FT_SIL; + uniform->arr[U0A] = 0; +} + +static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, int32_t index, int32_t a3) { + gl_state_disable_depth_test(); + gl_state_disable_scissor_test(); + + draw_state->shader_index = -1; + if (a3 == shad->field_2EC - 1) { + draw_pass_shadow_filter(&shad->render_textures[3], + &shad->render_textures[4], shad->curr_render_textures[0], + shad->field_2DC, shad->field_2E0 / (shad->field_208 * 2.0f), false); + draw_pass_shadow_esm_filter(&shad->render_textures[5], + &shad->render_textures[6], &shad->render_textures[3]); + } + + RenderTexture* rend_tex = shad->curr_render_textures[1 + index]; + RenderTexture& rend_buf_tex = rctx->shadow_buffer; + rend_tex->Bind(); + + image_filter_scale(rend_tex->GetColorTex(), + shad->curr_render_textures[0]->GetColorTex(), 1.0f); + + rend_buf_tex.Bind(); + if (shad->blur_filter_enable[index]) { + for (int32_t i = shad->near_blur, j = 0; i > 0; i--, j++) { + blur_filter_apply(&rend_buf_tex, rend_tex, + shad->blur_filter, 1.0f, 1.0f, 0.0f); + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, 0, 0, 0, 0, rend_buf_tex.GetWidth(), rend_buf_tex.GetHeight()); + } + } + else { + glClearColorDLL(1.0f, 1.0f, 1.0f, 1.0f); + glClearDLL(GL_COLOR_BUFFER_BIT); + } + + gl_state_bind_framebuffer(0); + gl_state_bind_texture_2d(rend_tex->GetColorTex()); + glGenerateMipmap(GL_TEXTURE_2D); + gl_state_bind_texture_2d(0); +} + +static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, + RenderTexture* a3, float_t sigma, float_t far_texel_offset, bool enable_lit_proj) { + GLuint v7 = a1->GetColorTex(); + GLuint v9 = a2->GetColorTex(); + GLuint v11 = v7; + if (a3) + v11 = a3->GetDepthTex(); + + if (!v7 || !v9 || !v11) + return; + + texture_param tex_params[2]; + texture_params_get(v7, &tex_params[0], v9, &tex_params[1]); + if (tex_params[0].width != tex_params[1].width + || tex_params[0].height != tex_params[1].height) + return; + + filter_scene_shader_data filter_scene = {}; + filter_scene.g_transform = 0.0f; + filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; + rctx->filter_scene_ubo.WriteMemory(filter_scene); + + esm_filter_batch_shader_data esm_filter_batch = {}; + esm_filter_batch.g_params = { 1.0f / (float_t)tex_params[0].width, 0.0f, far_texel_offset, far_texel_offset }; + double_t v6 = 1.0 / (sqrt(M_PI * 2.0) * sigma); + double_t v8 = -1.0 / (2.0 * sigma * sigma); + for (int32_t i = 0; i < 8; i++) + ((float_t*)esm_filter_batch.g_gauss)[i] = (float_t)(exp((double_t)((ssize_t)i * i) * v8) * v6); + + uniform->arr[U_LIGHT_PROJ] = enable_lit_proj ? 1 : 0; + shaders_ft.set(SHADER_FT_ESMGAUSS); + rctx->filter_scene_ubo.Bind(0); + rctx->esm_filter_batch_ubo.Bind(1); + + a2->Bind(); + esm_filter_batch.g_params = { 1.0f / (float_t)tex_params[0].width, 0.0f, far_texel_offset, far_texel_offset }; + rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + + gl_state_active_bind_texture_2d(0, v11); + if (a3) { + GLint swizzle[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + } + else { + GLint swizzle[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + } + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + + a1->Bind(); + + esm_filter_batch.g_params = { 0.0f, 1.0f / (float_t)tex_params[0].height, far_texel_offset, far_texel_offset }; + rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + + gl_state_active_bind_texture_2d(0, v9); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + shader_glsl::unbind(); + + texture_params_restore(&tex_params[0], &tex_params[1], 0); +} + +static void draw_pass_shadow_esm_filter(RenderTexture* dst, RenderTexture* buf, RenderTexture* src) { + GLuint dst_tex = dst->GetColorTex(); + GLuint buf_tex = buf->GetColorTex(); + GLuint src_tex = src->GetColorTex(); + if (!dst_tex || !buf_tex || !src_tex) + return; + + filter_scene_shader_data filter_scene = {}; + filter_scene.g_transform = 0.0f; + filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; + rctx->filter_scene_ubo.WriteMemory(filter_scene); + + esm_filter_batch_shader_data esm_filter_batch = {}; + esm_filter_batch.g_gauss[0] = 0.0f; + esm_filter_batch.g_gauss[1] = 0.0f; + + rctx->filter_scene_ubo.Bind(0); + rctx->esm_filter_batch_ubo.Bind(1); + + texture_param tex_params[3]; + texture_params_get(dst_tex, &tex_params[0], src_tex, &tex_params[1], buf_tex, &tex_params[2]); + + buf->Bind(); + esm_filter_batch.g_params = { 1.0f / (float_t)tex_params[1].width, + 1.0f / (float_t)tex_params[1].height, 0.0f, 0.0f }; + rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + + uniform->arr[U_ESM_FILTER] = 0; + shaders_ft.set(SHADER_FT_ESMFILT); + gl_state_active_bind_texture_2d(0, src_tex); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + + dst->Bind(); + esm_filter_batch.g_params = { 0.75f / (float_t)tex_params[2].width, + 0.75f / (float_t)tex_params[2].height, 0.0f, 0.0f }; + rctx->esm_filter_batch_ubo.WriteMemory(esm_filter_batch); + + uniform->arr[U_ESM_FILTER] = 1; + shaders_ft.set(SHADER_FT_ESMFILT); + gl_state_active_bind_texture_2d(0, buf_tex); + gl_state_bind_vertex_array(rctx->common_vao); + shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, 0, 4); + + texture_params_restore(&tex_params[0], &tex_params[1], &tex_params[2]); +} + +static bool draw_pass_shadow_litproj() { + if (!*stage_param_data_litproj_current) + return false; + + texture* tex = texture_handler_get_texture((*stage_param_data_litproj_current)->tex_id); + if (!tex) + return false; + + litproj_texture->Bind(); + litproj_texture->SetViewport(); + gl_state_enable_depth_test(); + glClearColorDLL(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepthf(1.0f); + glClearDLL(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (!draw_pass_shadow_litproj_set_mat(false)) { + gl_state_bind_framebuffer(0); + return false; + } + + draw_state->shader_index = SHADER_FT_LITPROJ; + gl_state_active_bind_texture_2d(17, tex->tex); + gl_state_bind_sampler(17, rctx->render_samplers[2]); + gl_state_active_bind_texture_2d(18, litproj_shadow[0].GetColorTex()); + gl_state_bind_sampler(18, rctx->render_samplers[2]); + gl_state_active_texture(0); + return true; +} + +static bool draw_pass_shadow_litproj_set() { + if (!*stage_param_data_litproj_current) + return 0; + + static const vec4 color_clear = 1.0f; + static const GLfloat depth_clear = 1.0f; + + litproj_shadow[0].Bind(); + glViewportDLL(0, 0, 2048, 512); + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); + glClearBufferfv(GL_DEPTH, 0, &depth_clear); + + if (draw_pass_shadow_litproj_set_mat(false)) { + draw_state->shader_index = SHADER_FT_SIL; + uniform->arr[U0A] = 1; + return true; + } + else { + litproj_texture->Bind(); + litproj_texture->SetViewport(); + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + glClearBufferfv(GL_COLOR, 0, (float_t*)&color_clear); + glClearBufferfv(GL_DEPTH, 0, &depth_clear); + } + return false; +} + +static bool draw_pass_shadow_litproj_set_mat(bool set_mat) { + light_set* set = &light_set_data[LIGHT_SET_MAIN]; + light_data* data = &set->lights[LIGHT_PROJECTION]; + if (data->get_type() != LIGHT_SPOT) + return false; + + vec3 position; + vec3 spot_direction; + data->get_position(position); + data->get_spot_direction(spot_direction); + + if (vec3::length_squared(spot_direction) <= 0.000001f) + return false; + + float_t spot_cutoff = data->get_spot_cutoff(); + float_t fov = atanf(tanf(spot_cutoff * DEG_TO_RAD_FLOAT) * 0.25f) * 2.0f; + + vec3 interest = position + spot_direction; + if (set_mat) { + mat4 temp; + mat4_translate(0.5f, 0.5f, 0.5f, &temp); + mat4_scale_rot(&temp, 0.5f, 0.5f, 0.5f, &temp); + + mat4 proj; + mat4_persp(fov, 4.0f, 0.1f, 10.0f, &proj); + mat4_mul(&proj, &temp, &proj); + + mat4 view; + vec3 up = { 0.0f, 1.0f, 0.0f }; + mat4_look_at(&position, &interest, &up, &view); + + mat4 mat; + mat4_mul(&view, &proj, &mat); + rctx->obj_scene.set_g_light_projection(mat); + } + else { + mat4_persp(fov, 4.0f, 0.1f, 10.0f, &rctx->proj_mat); + + vec3 up = { 0.0f, 1.0f, 0.0f }; + mat4_look_at(&position, &interest, &up, &rctx->view_mat); + rctx->obj_scene.set_projection_view(rctx->view_mat, rctx->proj_mat); + } + return true; +} + +static void draw_pass_sss_contour(rndr::Render* rend) { + rend->sss_contour_texture->Bind(); + rend->sss_contour_texture->SetViewport(); + gl_state_enable_depth_test(); + gl_state_set_depth_func(GL_ALWAYS); + gl_state_set_depth_mask(GL_TRUE); + glViewportDLL(0, 0, rend->render_width[0], rend->render_height[0]); + gl_state_active_bind_texture_2d(0, rend->rend_texture[0].GetColorTex()); + gl_state_bind_sampler(0, rctx->render_samplers[1]); + gl_state_active_bind_texture_2d(1, rend->rend_texture[0].GetDepthTex()); + gl_state_bind_sampler(1, rctx->render_samplers[1]); + gl_state_active_texture(0); + + float_t v3 = 1.0f / tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT); + + vec3 direction = camera_data->interest - camera_data->view_point; + float_t length = vec3::length(direction); + float_t v7 = direction.y; + if (length != 0.0f) + v7 /= length; + + float_t v9 = fabsf(v7) - 0.1f; + if (v9 < 0.0f) + v9 = 0.0f; + + contour_coef_shader_data shader_data = {}; + shader_data.g_contour = { v9 * 0.004f + 0.0027f, 0.003f, v3 * 0.35f, 0.0008f }; + shader_data.g_near_far = rctx->g_near_far; + rctx->contour_coef_ubo.WriteMemory(shader_data); + + shaders_ft.set(SHADER_FT_CONTOUR); + rctx->contour_coef_ubo.Bind(2); + render->draw_quad( + rend->render_post_width[0], rend->render_post_height[0], + rend->render_post_width_scale, rend->render_post_height_scale, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); +} + +static void draw_pass_sss_filter_calc_coef(double_t a1, size_t a2, double_t a3, size_t a4, + const double_t* a5, const double_t* a6, const double_t* a7, const double_t* a8, vec4 params[64]) { + if (a2 > 8) + return; + + for (size_t i = a4; i; i--) { + float_t* v20 = (float_t*)params; + double_t v56[3]; + v56[0] = *a6; + v56[1] = *a7; + v56[2] = *a8; + + for (size_t j = 0; j < 3; j++) { + double_t v22 = 0.0; + double_t v23 = 0.0; + double_t v54[8]; + double_t v24 = 1.0 / (a3 * v56[j]); + v24 *= v24; + for (size_t k = 0; k < a2; k++) { + double_t v25 = exp(-0.5 * (v23 * v23) * v24); + v54[k] = v25; + v23 += a1; + v22 += v25; + } + + double_t v27 = 1.0 / v22; + for (size_t k = 0; k < a2; k++) + v54[k] *= v27; + + float_t* v35 = v20; + for (size_t k = 0; k < a2; k++) { + double_t v37 = v54[k] * *a5; + for (size_t v36 = 0; v36 < a2; v36++) { + *v35 += (float_t)(v37 * v54[v36]); + v35 += 4; + } + } + v20++; + } + a5++; + a6++; + a7++; + a8++; + } +} + +static void draw_pass_sss_filter(sss_data* sss) { + const int32_t sss_count = 6; + vec3 interest = camera_data->interest; + vec3 view_point = camera_data->view_point; + + vec3 chara_position[2]; + chara_position[0] = 0.0f; + chara_position[1] = 0.0f; + float_t chara_distance[2]; + size_t rob_chara_smth = get_rob_chara_smth(); + for (int32_t i = 0; i < 2; i++) { + chara_position[i] = interest; + chara_distance[i] = 999999.0f; + size_t rob_bone_data = rob_chara_array_get_bone_data(rob_chara_smth, i); + if (rob_chara_pv_data_array_check_chara_id(rob_chara_smth, i) + && rob_chara_array_check_visibility(rob_chara_smth, i)) { + mat4* mat = rob_chara_bone_data_get_mats_mat(rob_bone_data, 0); + if (mat) { + mat4_get_translation(mat, &chara_position[i]); + chara_distance[i] = vec3::distance(view_point, chara_position[i]); + } + } + } + + vec3 closest_chara_position; + if (chara_distance[0] > chara_distance[1]) { + closest_chara_position = chara_position[1]; + chara_position[0] = chara_position[1]; + } + else + closest_chara_position = chara_position[0]; + + float_t length = vec3::distance(interest, closest_chara_position); + if (length > 1.25f) + interest = chara_position[0]; + + float_t v29 = vec3::distance(view_point, interest); + if (v29 < 0.25f) + v29 = 0.25f; + float_t v31 = tanf(camera_data->fov * 0.5f * DEG_TO_RAD_FLOAT) * 5.0f; + if (v31 < 0.25f) + v31 = 0.25f; + float_t v32 = v31 * v29; + float_t v33 = 0.6f; + float_t v34 = 1.0f / clamp_def(v32, 0.25f, 100.0f); + if (v34 < 0.145f) { + float_t v36 = v34 - 0.02f; + if (v34 < 0.0f) + v36 = 0.0f; + v33 = (v36 * 8.0f) * 0.6f; + } + rctx->obj_batch.g_sss_param = { v33, 0.0f, 0.0f, 0.0f }; + + gl_state_active_texture(0); + if (sss->npr_contour) { + sss->textures[0].Bind(); + glViewportDLL(0, 0, 640, 360); + rndr::Render* rend = render; + uniform->arr[U_REDUCE] = 0; + shaders_ft.set(SHADER_FT_REDUCE); + gl_state_bind_texture_2d(rend->rend_texture[0].GetColorTex()); + render->draw_quad(640, 360, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); + } + sss->textures[2].Bind(); + glViewportDLL(0, 0, 320, 180); + uniform->arr[U_SSS_FILTER] = 0; + shaders_ft.set(SHADER_FT_SSS_FILT); + gl_state_bind_texture_2d(sss->textures[0].GetColorTex()); + render->draw_quad(640, 360, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); + + sss_filter_gaussian_coef_shader_data shader_data = {}; + shader_data.g_param = { (float_t)(sss_count - 1), 0.0f, 1.0f, 1.0f }; + + const double_t a5[] = { 0.4, 0.3, 0.3 }; + const double_t a6[] = { 1.0, 2.0, 5.0 }; + const double_t a7[] = { 0.2, 0.4, 1.2 }; + const double_t a8[] = { 0.3, 0.7, 2.0 }; + draw_pass_sss_filter_calc_coef(1.0, sss_count, v34, 3, a5, a6, a7, a8, shader_data.g_coef); + + rctx->sss_filter_gaussian_coef_ubo.WriteMemory(shader_data); + sss->textures[1].Bind(); + glViewportDLL(0, 0, 320, 180); + uniform->arr[U_SSS_FILTER] = 3; + shaders_ft.set(SHADER_FT_SSS_FILT); + gl_state_bind_texture_2d(sss->textures[2].GetColorTex()); + rctx->sss_filter_gaussian_coef_ubo.Bind(1); + render->draw_quad(320, 180, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 0.96f, 1.0f, 0.0f); + gl_state_bind_texture_2d(0); +} + +static int32_t draw_pass_3d_get_translucent_count() { + int32_t count = 0; + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_1); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_3); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3); + count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3); + //count += disp_manager->get_obj_count(mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL); + //count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL); + //count += disp_manager->get_obj_count(mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL); + return count; +} + +static void draw_pass_3d_shadow_reset() { + gl_state_active_bind_texture_2d(6, 0); + gl_state_active_bind_texture_2d(7, 0); + rctx->obj_scene.set_g_self_shadow_receivers(0, mat4_identity); + rctx->obj_scene.set_g_self_shadow_receivers(1, mat4_identity); + draw_state->self_shadow = false; + draw_state->light = false; +} + +static void draw_pass_3d_shadow_set(Shadow* shad) { + if (shad->self_shadow && shad->field_2EC > 0) { + gl_state_active_bind_texture_2d(19, shad->render_textures[3].GetColorTex()); + gl_state_active_bind_texture_2d(20, shad->render_textures[5].GetColorTex()); + gl_state_active_texture(0); + float_t esm_param = (shad->field_2D8 * shad->field_208 * 2.0f) * 1.442695f; + rctx->obj_scene.g_esm_param = { esm_param, 0.0f, 0.0f, 0.0f }; + draw_state->self_shadow = true; + } + else { + gl_state_active_bind_texture_2d(19, rctx->empty_texture_2d); + gl_state_active_bind_texture_2d(20, rctx->empty_texture_2d); + gl_state_active_texture(0); + draw_state->self_shadow = false; + } + + if (shad->field_2EC > 0) { + draw_state->light = true; + uniform->arr[U_LIGHT_1] = shad->field_2EC > 1 ? 1 : 0; + + float_t range = shad->view_region * shad->range; + for (int32_t i = 0; i < 2; i++) { + float_t v6 = 0.0f; + vec3* interest; + vec3* view_point; + if (shad->field_2F5) { + v6 = i ? 0.5f : -0.5f; + + interest = &shad->interest[i]; + view_point = &shad->view_point[i]; + } + else { + interest = &shad->interest_shared; + view_point = &shad->view_point_shared; + } + + mat4 temp; + mat4_translate(0.5f, 0.5f, 0.5f, &temp); + mat4_scale_rot(&temp, 0.5f, 0.5f, 0.5f, &temp); + mat4_mul_translate(&temp, v6, 0.0f, 0.0f, &temp); + + mat4 proj; + mat4_ortho(-range, range, -range, range, shad->z_near, shad->z_far, &proj); + mat4_mul(&proj, &temp, &proj); + + mat4 view; + mat4_look_at(view_point, interest, &view); + mat4_mul(&view, &proj, &view); + rctx->obj_scene.set_g_self_shadow_receivers(i, view); + } + + for (int32_t i = 0, j = 0; i < 2; i++) { + if (!shad->field_2F0[i]) { + gl_state_active_bind_texture_2d(6 + j, rctx->empty_texture_2d); + continue; + } + + gl_state_active_bind_texture_2d(6 + j, shad->curr_render_textures[1 + i]->GetColorTex()); + glTexParameterfDLL(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f); + j++; + } + gl_state_active_texture(0); + + light_set* set = &light_set_data[LIGHT_SET_MAIN]; + light_data* data = &set->lights[LIGHT_SHADOW]; + + vec4 ambient; + if (data->get_type() == LIGHT_PARALLEL) + data->get_ambient(ambient); + else { + ambient.x = shad->ambient; + ambient.y = shad->ambient; + ambient.z = shad->ambient; + } + + rctx->obj_scene.g_shadow_ambient = { ambient.x, ambient.y, ambient.z, 1.0f }; + rctx->obj_scene.g_shadow_ambient1 = { 1.0f - ambient.x, 1.0f - ambient.y, 1.0f - ambient.z, 0.0f }; + } + else { + draw_state->light = false; + + for (int32_t i = 0; i < 2; i++) + gl_state_active_bind_texture_2d(6 + i, shad->curr_render_textures[1 + i]->GetColorTex()); + gl_state_active_texture(0); + + rctx->obj_scene.g_shadow_ambient = 1.0f; + rctx->obj_scene.g_shadow_ambient1 = 0.0f; + } +} + +static void draw_pass_3d_translucent(bool opaque_enable, + bool transparent_enable, bool translucent_enable, mdl::ObjType opaque, + mdl::ObjType transparent, mdl::ObjType translucent) { + if (disp_manager->get_obj_count(opaque) < 1 + && disp_manager->get_obj_count(transparent) < 1 + && disp_manager->get_obj_count(translucent) < 1) + return; + + rndr::Render* rend = render; + + int32_t alpha_array[256]; + int32_t count = draw_pass_3d_translucent_count_layers( + alpha_array, opaque, transparent, translucent); + for (int32_t i = 0; i < count; i++) { + int32_t alpha = alpha_array[i]; + rend->transparency_copy(); + if (opaque_enable && disp_manager->get_obj_count(opaque)) + disp_manager->draw_translucent(opaque, alpha); + if (transparent_enable && disp_manager->get_obj_count(transparent)) + disp_manager->draw_translucent(transparent, alpha); + if (translucent_enable && disp_manager->get_obj_count(translucent)) { + gl_state_enable_blend(); + disp_manager->draw_translucent(translucent, alpha); + gl_state_disable_blend(); + } + rend->transparency_combine((float_t)alpha * (float_t)(1.0 / 255.0)); + } +} + +static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, + mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent) { + bool arr[256] = { 0 }; + + draw_pass_3d_translucent_has_objects(arr, opaque); + draw_pass_3d_translucent_has_objects(arr, transparent); + draw_pass_3d_translucent_has_objects(arr, translucent); + + int32_t count = 0; + for (int32_t i = 0xFF; i >= 1; i--) + if (arr[i]) { + count++; + *alpha_array++ = i; + } + return count; +} + +static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type) { + prj::list& vec = disp_manager->obj[type]; + for (mdl::ObjData*& i : vec) + switch (i->kind) { + case mdl::OBJ_KIND_NORMAL: { + int32_t alpha = (int32_t)(i->args.sub_mesh.blend_color.w * 255.0f); + alpha = clamp_def(alpha, 0, 255); + arr[alpha] = true; + } break; + case mdl::OBJ_KIND_TRANSLUCENT: { + for (uint32_t j = 0; j < i->args.translucent.count; j++) { + int32_t alpha = (int32_t)(i->args.translucent.sub_mesh[j]->blend_color.w * 255.0f); + alpha = clamp_def(alpha, 0, 255); + arr[alpha] = true; + } + } break; + } +} + +static void blur_filter_apply(RenderTexture* dst, RenderTexture* src, + blur_filter_mode filter, const vec2 res_scale, const vec4 scale, const vec4 offset) { + if (!dst || !src) + return; + + filter_scene_shader_data filter_scene = {}; + float_t w = res_scale.x / (float_t)src->GetWidth(); + float_t h = res_scale.y / (float_t)src->GetHeight(); + filter_scene.g_transform = { w, h, 0.0f, 0.0f }; + filter_scene.g_texcoord = { 1.0f, 1.0f, 0.0f, 0.0f }; + rctx->filter_scene_ubo.WriteMemory(filter_scene); + + imgfilter_batch_shader_data imgfilter_batch = {}; + if (filter == BLUR_FILTER_32) + imgfilter_batch.g_color_scale = scale * (float_t)(1.0 / 8.0); + else + imgfilter_batch.g_color_scale = scale * (float_t)(1.0 / 4.0); + imgfilter_batch.g_color_offset = offset; + imgfilter_batch.g_texture_lod = 0.0f; + rctx->imgfilter_batch_ubo.WriteMemory(imgfilter_batch); + + uniform->arr[U_IMAGE_FILTER] = filter == BLUR_FILTER_32 ? 1 : 0; + gl_state_bind_vertex_array(rctx->box_vao); + shaders_ft.set(SHADER_FT_IMGFILT); + rctx->filter_scene_ubo.Bind(0); + rctx->imgfilter_batch_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, src->GetColorTex()); + //shaders_ft.draw_arrays(GL_TRIANGLE_STRIP, (GLint)(filter * 4LL), 4); +} diff --git a/src/DivaGL/render_manager.hpp b/src/DivaGL/render_manager.hpp new file mode 100644 index 0000000..da9a711 --- /dev/null +++ b/src/DivaGL/render_manager.hpp @@ -0,0 +1,154 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/vec.hpp" +#include "render.hpp" +#include "shadow.hpp" +#include "types.hpp" +#include "wrap.hpp" + +enum draw_pass_3d_type { + DRAW_PASS_3D_OPAQUE = 0, + DRAW_PASS_3D_TRANSLUCENT, + DRAW_PASS_3D_TRANSPARENT, + DRAW_PASS_3D_MAX, +}; + +enum reflect_refract_resolution_mode { + REFLECT_REFRACT_RESOLUTION_256x256 = 0, + REFLECT_REFRACT_RESOLUTION_512x256, + REFLECT_REFRACT_RESOLUTION_512x512, + REFLECT_REFRACT_RESOLUTION_MAX, +}; + +enum stage_data_reflect_type { + STAGE_DATA_REFLECT_DISABLE = 0x00, + STAGE_DATA_REFLECT_NORMAL = 0x01, + STAGE_DATA_REFLECT_REFLECT_MAP = 0x02, +}; + +struct draw_pre_process { + int32_t type; + void(FASTCALL* func)(void*); + void* data; +}; + +namespace rndr { + enum RenderPassID { + RND_PASSID_SHADOW = 0, + RND_PASSID_SS_SSS, + RND_PASSID_2, + RND_PASSID_REFLECT, + RND_PASSID_REFRACT, + RND_PASSID_PRE_PROCESS, + RND_PASSID_CLEAR, + RND_PASSID_PRE_SPRITE, + RND_PASSID_3D, + RND_PASSID_SHOW_VECTOR, + RND_PASSID_POST_PROCESS, + RND_PASSID_SPRITE, + RND_PASSID_12, + RND_PASSID_NUM, + }; + + struct RenderManager { + bool pass_sw[RND_PASSID_NUM]; + struct Shadow* shadow_ptr; + bool reflect; + bool refract; + int32_t reflect_blur_num; + blur_filter_mode reflect_blur_filter; + rndr::Render* render; + bool sync_gpu; + double_t cpu_time[RND_PASSID_NUM]; + double_t gpu_time[RND_PASSID_NUM]; + time_struct time; + bool shadow; + bool opaque_z_sort; + bool alpha_z_sort; + bool draw_pass_3d[DRAW_PASS_3D_MAX]; + bool field_11E; + bool field_11F; + bool field_120; + bool show_ref_map; + stage_data_reflect_type reflect_type; + bool clear; + int32_t tex_index[11]; + RenderTexture render_textures[8]; + int32_t width; + int32_t height; + GLuint multisample_framebuffer; + GLuint multisample_renderbuffer; + bool multisample; + bool check_state; + int32_t show_vector_flags; + float_t show_vector_length; + float_t show_vector_z_offset; + bool field_2F8; + prj::list pre_process; + texture* effect_texture; + int32_t npr_param; + bool field_31C; + bool field_31D; + bool field_31E; + bool field_31F; + bool field_320; + bool npr; + + void add_pre_process(int32_t type, void(*func)(void*), void* data); + void clear_pre_process(int32_t type); + RenderTexture& get_render_texture(int32_t index); + void resize(int32_t width, int32_t height); + void set_effect_texture(texture* value); + void set_multisample(bool value); + void set_npr_param(int32_t value); + void set_pass_sw(rndr::RenderPassID id, bool value); + void set_reflect(bool value); + void set_reflect_blur(int32_t reflect_blur_num, blur_filter_mode reflect_blur_filter); + void set_reflect_resolution_mode(reflect_refract_resolution_mode mode); + void set_reflect_type(stage_data_reflect_type type); + void set_refract(bool value); + void set_refract_resolution_mode(reflect_refract_resolution_mode mode); + void set_shadow_false(); + void set_shadow_true(); + + void render_all(); + + void render_single_pass(rndr::RenderPassID id); + + void render_pass_begin(); + void render_pass_end(rndr::RenderPassID id); + + void pass_shadow(); + void pass_ss_sss(); + void pass_reflect(); + void pass_refract(); + void pass_pre_process(); + void pass_clear(); + void pass_pre_sprite(); + void pass_3d(); + void pass_show_vector(); + void pass_post_process(); + void pass_sprite(); + + void pass_3d_contour(); + void pass_sprite_surf(); + }; + + static_assert(sizeof(rndr::RenderManager) == 0x328, "\"rndr::RenderManager\" struct should have a size of 0x328"); +} + +extern RenderTexture* litproj_shadow; +extern RenderTexture* litproj_texture; +extern rndr::RenderManager* render_manager; + +extern void image_filter_scale(GLuint dst, GLuint src, const vec4 scale); + +extern void draw_pass_set_camera(); + +extern void render_manager_patch(); diff --git a/src/DivaGL/render_texture.cpp b/src/DivaGL/render_texture.cpp new file mode 100644 index 0000000..13f003c --- /dev/null +++ b/src/DivaGL/render_texture.cpp @@ -0,0 +1,43 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "render_texture.hpp" +#include "gl_state.hpp" + +int32_t RenderTexture::Bind(int32_t index) { + if (index < 0 || index > max_level) + return -1; + + gl_state_bind_framebuffer(fbos[index]); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + return -1; + + gl_state_get_error(); + return 0; +} + +void RenderTexture::Free() { + static void (FASTCALL * RenderTexture__Free)(RenderTexture * rt) + = (void (FASTCALL*)(RenderTexture * rt))0x00000001405035C0; + RenderTexture__Free(this); +} + +int32_t RenderTexture::Init(int32_t width, int32_t height, + int32_t max_level, GLenum color_format, GLenum depth_format) { + static int32_t(FASTCALL * RenderTexture__Init)(RenderTexture * rt, int32_t width, int32_t height, + int32_t max_level, GLenum color_format, GLenum depth_format) + = (int32_t(FASTCALL*)(RenderTexture * rt, int32_t width, int32_t height, + int32_t max_level, GLenum color_format, GLenum depth_format))0x0000000140503420; + return RenderTexture__Init(this, width, height, max_level, color_format, depth_format); +} + +int32_t RenderTexture::SetColorDepthTextures(GLuint color_texture, + int32_t max_level, GLuint depth_texture) { + int32_t(FASTCALL * RenderTexture__SetColorDepthTextures)(RenderTexture * rt, + GLuint color_texture, int32_t level, GLuint depth_texture) + = (int32_t(FASTCALL*)(RenderTexture * rt, + GLuint color_texture, int32_t level, GLuint depth_texture))0x0000000140503130; + return RenderTexture__SetColorDepthTextures(this, color_texture, max_level, depth_texture); +} diff --git a/src/DivaGL/render_texture.hpp b/src/DivaGL/render_texture.hpp new file mode 100644 index 0000000..af29314 --- /dev/null +++ b/src/DivaGL/render_texture.hpp @@ -0,0 +1,49 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "shared.hpp" +#include "texture.hpp" + +struct RenderTexture { + void* __vftable; + texture* color_texture; + texture* depth_texture; + int32_t binding; + int32_t max_level; + GLuint* fbos; + GLuint rbo; + GLuint field_2C; + + int32_t Bind(int32_t index = 0); + void Free(); + int32_t Init(int32_t width, int32_t height, + int32_t max_level, GLenum color_format, GLenum depth_format); + int32_t SetColorDepthTextures(GLuint color_texture, + int32_t max_level = 0, GLuint depth_texture = 0); + + inline GLuint GetColorTex() { + return color_texture->tex; + }; + + inline GLuint GetDepthTex() { + return depth_texture->tex; + }; + + inline int32_t GetHeight() { + return color_texture->height; + }; + + inline int32_t GetWidth() { + return color_texture->width; + }; + + inline void SetViewport() { + glViewportDLL(0, 0, GetWidth(), GetHeight()); + }; +}; + +static_assert(sizeof(RenderTexture) == 0x30, "\"RenderTexture\" struct should have a size of 0x30"); diff --git a/src/DivaGL/renderer/dof.cpp b/src/DivaGL/renderer/dof.cpp new file mode 100644 index 0000000..5233cce --- /dev/null +++ b/src/DivaGL/renderer/dof.cpp @@ -0,0 +1,273 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "dof.hpp" +#include "../rob/rob.hpp" +#include "../camera.hpp" +#include "../gl_state.hpp" +#include "../render_context.hpp" + +struct dof_common_shader_data { + vec4 g_depth_params; //x=(n-f)/(nf), y=1/n, z=coc_from_z_scale, w=coc_from_z_offset + vec4 g_spread_scale; //x=scale_from_meter_to_pixel, y=scale_from_meter_to_sample, + // z=scale_from_pixel_to_sample, w=scale_from_sample_to_pixel + vec4 g_depth_params2; //x=distance_to_focus_m, y=focus_range, + // z=k/(fuzzing_range*fuzzing_range), w=max_coc_radius_in_pixel //yzw=for_f2 +}; + +dof_debug* dof_debug_data = (dof_debug*)0x00000001411AB650; +dof_pv* dof_pv_data = (dof_pv*)0x0000001411AB630; + +namespace renderer { + void DOF3::apply(RenderTexture* rt) { + if (dof_debug_data->flags & DOF_DEBUG_USE_UI_PARAMS) { + if (dof_debug_data->flags & DOF_DEBUG_ENABLE_DOF) { + if (dof_debug_data->flags & DOF_DEBUG_ENABLE_PHYS_DOF) { + float_t focus = dof_debug_data->focus; + if (dof_debug_data->flags & DOF_DEBUG_AUTO_FOCUS) { + size_t rob_chara_smth = get_rob_chara_smth(); + + size_t rob_chr = 0; + for (int32_t i = 0; i < ROB_CHARA_COUNT; i++) { + size_t rob_chr = rob_chara_array_get(rob_chara_smth, i); + if (!rob_chr || !(*(uint8_t*)(rob_chara_smth + 0x440) & 1)) + continue; + + mat4 mat; + sub_1405163C0(rob_chr, 4, &mat); + mat4_transpose(&mat, &mat); + + vec3 chara_trans = 0.0f; + mat4_get_translation(&mat, &chara_trans); + + mat4 view_transpose; + mat4_transpose(&camera_data->view_matrix, &view_transpose); + focus = -vec3::dot(*(vec3*)&view_transpose.row2, chara_trans) + - view_transpose.row2.w - 0.1f; + break; + } + } + + focus = max_def(focus, camera_data->min_distance); + apply_physical(rt, rt->GetColorTex(), rt->GetDepthTex(), + camera_data->min_distance, camera_data->max_distance, + focus, dof_debug_data->focal_length, + camera_data->fov * DEG_TO_RAD_FLOAT, + dof_debug_data->f_number); + } + else { + float_t fuzzing_range = max_def(dof_debug_data->f2.fuzzing_range, 0.01f); + apply_f2(rt, + rt->GetColorTex(), + rt->GetDepthTex(), + camera_data->min_distance, camera_data->max_distance, + camera_data->fov * DEG_TO_RAD_FLOAT, + dof_debug_data->f2.focus, dof_debug_data->f2.focus_range, + fuzzing_range, dof_debug_data->f2.ratio); + } + } + } + else if (dof_pv_data->enable && dof_pv_data->f2.ratio > 0.0f) { + float_t fuzzing_range = max_def(dof_pv_data->f2.fuzzing_range, 0.01f); + if (dof_pv_data->f2.fuzzing_range >= 0.0099999998) + apply_f2(rt, rt->GetColorTex(), rt->GetDepthTex(), + camera_data->min_distance, camera_data->max_distance, + camera_data->fov * DEG_TO_RAD_FLOAT, + dof_pv_data->f2.focus, dof_pv_data->f2.focus_range, + fuzzing_range, dof_pv_data->f2.ratio); + enum_or(dof_debug_data->flags, DOF_DEBUG_ENABLE_DOF); + dof_debug_data->f2 = dof_pv_data->f2; + } + else + enum_and(dof_debug_data->flags, ~DOF_DEBUG_ENABLE_DOF); + } + + void DOF3::resize(int32_t width, int32_t height) { + if (textures[0]) { + glDeleteTextures(6, textures); + textures[0] = 0; + } + + void(FASTCALL * renderer__FBO__init)(void* fbo, int32_t width, int32_t height, + GLuint * color_textures, int32_t count, GLuint depth_texture) + = (void(FASTCALL*)(void* fbo, int32_t width, int32_t height, + GLuint * color_textures, int32_t count, GLuint depth_texture))0x00000001404AEF40; + + this->width = width; + this->height = height; + int32_t w20 = max_def(width / 20, 1); + int32_t h20 = max_def(height / 20, 1); + int32_t w2 = max_def(width / 2, 1); + int32_t h2 = max_def(height / 2, 1); + glGenTextures(6, textures); + gl_state_bind_texture_2d(textures[0]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); + renderer__FBO__init(&fbo[0], w20, h20, &textures[0], 1, 0); + gl_state_bind_texture_2d(textures[1]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG16F, w20, h20); + renderer__FBO__init(&fbo[1], w20, h20, &textures[1], 1, 0); + gl_state_bind_texture_2d(textures[2]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + gl_state_bind_texture_2d(textures[3]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + renderer__FBO__init(&fbo[2], w2, h2, &textures[2], 2, 0); + gl_state_bind_texture_2d(textures[4]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R11F_G11F_B10F, w2, h2); + gl_state_bind_texture_2d(textures[5]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, w2, h2); + renderer__FBO__init(&fbo[3], w2, h2, &textures[4], 2, 0); + } + + void DOF3::apply_f2(RenderTexture* rt, GLuint color_texture, + GLuint depth_texture, float_t min_distance, float_t max_distance, float_t fov, + float_t focus, float_t focus_range, float_t fuzzing_range, float_t ratio) { + gl_state_begin_event("renderer::DOF3::apply_f2"); + gl_state_disable_blend(); + gl_state_set_depth_mask(GL_FALSE); + gl_state_set_depth_func(GL_ALWAYS); + update_data(min_distance, max_distance, + fov, focus, 0.0f, 1.0f, focus_range, fuzzing_range, ratio); + + gl_state_bind_vertex_array(vao); + render_tiles(depth_texture, true); + downsample(color_texture, depth_texture, true); + main_filter(true); + upsample(rt, color_texture, depth_texture, true); + + gl_state_use_program(0); + for (int32_t i = 0; i < 8; i++) { + gl_state_bind_sampler(i, 0); + gl_state_active_bind_texture_2d(i, 0); + } + gl_state_bind_vertex_array(0); + gl_state_end_event(); + } + + void DOF3::apply_physical(RenderTexture* rt, GLuint color_texture, + GLuint depth_texture, float_t min_distance, float_t max_distance, + float_t focus, float_t focal_length, float_t fov, float_t f_number) { + gl_state_begin_event("renderer::DOF3::apply_physical"); + gl_state_disable_blend(); + gl_state_set_depth_mask(GL_FALSE); + gl_state_set_depth_func(GL_ALWAYS); + update_data(min_distance, max_distance, + fov, focus, focal_length, f_number, 0.0f, 0.1f, 0.0f); + + gl_state_bind_vertex_array(vao); + render_tiles(depth_texture, false); + downsample(color_texture, depth_texture, false); + main_filter(false); + upsample(rt, color_texture, depth_texture, false); + + gl_state_use_program(0); + for (int32_t i = 0; i < 8; i++) { + gl_state_bind_sampler(i, 0); + gl_state_active_bind_texture_2d(i, 0); + } + gl_state_bind_vertex_array(0); + gl_state_end_event(); + } + + void DOF3::render_tiles(GLuint depth_texture, bool f2) { + gl_state_begin_event("renderer::DOF3::render_tiles"); + gl_state_bind_framebuffer(fbo[0].buffer); + glViewportDLL(0, 0, fbo[0].width, fbo[0].height); + gl_state_use_program(program[f2 ? 5 : 1]); + common_ubo.Bind(0); + gl_state_active_bind_texture_2d(0, depth_texture); + gl_state_bind_sampler(0, samplers[1]); + glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + + gl_state_bind_framebuffer(fbo[1].buffer); + glViewportDLL(0, 0, fbo[1].width, fbo[1].height); + gl_state_use_program(program[0]); + gl_state_active_bind_texture_2d(0, textures[0]); + gl_state_bind_sampler(0, samplers[1]); + glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + gl_state_end_event(); + + } + + void DOF3::downsample(GLuint color_texture, GLuint depth_texture, bool f2) { + gl_state_begin_event("renderer::DOF3::downsample"); + gl_state_bind_framebuffer(fbo[2].buffer); + glViewportDLL(0, 0, fbo[2].width, fbo[2].height); + gl_state_use_program(program[f2 ? 6 : 2]); + common_ubo.Bind(0); + gl_state_active_bind_texture_2d(0, depth_texture); + gl_state_bind_sampler(0, samplers[1]); + gl_state_active_bind_texture_2d(1, color_texture); + gl_state_bind_sampler(1, samplers[0]); + gl_state_active_bind_texture_2d(2, textures[1]); + gl_state_bind_sampler(2, samplers[1]); + glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + gl_state_end_event(); + } + + void DOF3::main_filter(bool f2) { + gl_state_begin_event("renderer::DOF3::main_filter"); + gl_state_bind_framebuffer(fbo[3].buffer); + glViewportDLL(0, 0, fbo[3].width, fbo[3].height); + gl_state_use_program(program[f2 ? 7 : 3]); + common_ubo.Bind(0); + texcoords_ubo.Bind(1); + gl_state_active_bind_texture_2d(0, textures[3]); + gl_state_bind_sampler(0, samplers[1]); + gl_state_active_bind_texture_2d(1, textures[2]); + gl_state_bind_sampler(1, samplers[1]); + gl_state_active_bind_texture_2d(2, textures[1]); + gl_state_bind_sampler(2, samplers[1]); + glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + gl_state_end_event(); + } + + void DOF3::upsample(RenderTexture* rt, GLuint color_texture, GLuint depth_texture, bool f2) { + gl_state_begin_event("renderer::DOF3::upsample"); + rctx->render_buffer.Bind(); + glViewportDLL(0, 0, width, height); + gl_state_use_program(program[f2 ? 8 : 4]); + common_ubo.Bind(0); + gl_state_active_bind_texture_2d(0, textures[4]); + gl_state_bind_sampler(0, samplers[1]); + gl_state_active_bind_texture_2d(1, textures[5]); + gl_state_bind_sampler(1, samplers[1]); + gl_state_active_bind_texture_2d(2, textures[1]); + gl_state_bind_sampler(2, samplers[1]); + gl_state_active_bind_texture_2d(3, color_texture); + gl_state_bind_sampler(3, samplers[1]); + gl_state_active_bind_texture_2d(4, depth_texture); + gl_state_bind_sampler(4, samplers[1]); + glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + + glCopyImageSubData( + rctx->render_buffer.GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, + rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1); + gl_state_end_event(); + } + + void DOF3::update_data(float_t min_dist, float_t max_dist, float_t fov, float_t dist, float_t focal_length, + float_t f_number, float_t focus_range, float_t fuzzing_range, float_t ratio) { + float_t fl = focal_length; + if (dist <= focal_length) + fl = dist + 0.1f; + fl = fl / (dist - fl) * fl / f_number; + + dof_common_shader_data shader_data = {}; + shader_data.g_depth_params.x = 1.0f / (min_dist * max_dist) * (min_dist - max_dist); + shader_data.g_depth_params.y = 1.0f / min_dist; + shader_data.g_depth_params.z = -((fl * dist * (min_dist - max_dist)) * (1.0f / (min_dist * max_dist))); + shader_data.g_depth_params.w = (1.0f - 1.0f / min_dist * dist) * fl; + shader_data.g_spread_scale.x = 720.0f / (tanf(fov * 0.5f) * (min_dist * 2.0f)); + shader_data.g_spread_scale.y = shader_data.g_spread_scale.x * (float_t)(1.0 / 3.0); + shader_data.g_spread_scale.z = (float_t)(1.0 / 3.0); + shader_data.g_spread_scale.w = 3.0f; + shader_data.g_depth_params2.x = dist; + shader_data.g_depth_params2.y = focus_range; + shader_data.g_depth_params2.z = -4.5f / (fuzzing_range * fuzzing_range); + shader_data.g_depth_params2.w = ratio * 8.0f; + common_ubo.WriteMemory(shader_data); + } + +} diff --git a/src/DivaGL/renderer/dof.hpp b/src/DivaGL/renderer/dof.hpp new file mode 100644 index 0000000..f97234a --- /dev/null +++ b/src/DivaGL/renderer/dof.hpp @@ -0,0 +1,82 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../gl_uniform_buffer.hpp" +#include "../render_texture.hpp" +#include "fbo.hpp" + +enum dof_debug_flags { + DOF_DEBUG_USE_UI_PARAMS = 0x01, + DOF_DEBUG_ENABLE_DOF = 0x02, + DOF_DEBUG_ENABLE_PHYS_DOF = 0x04, + DOF_DEBUG_AUTO_FOCUS = 0x08, +}; + +struct dof_f2 { + float_t focus; + float_t focus_range; + float_t fuzzing_range; + float_t ratio; +}; + +static_assert(sizeof(dof_f2) == 0x10, "\"dof_f2\" struct should have a size of 0x10"); + +struct dof_debug { + dof_debug_flags flags; + float_t focus; + float_t focal_length; + float_t f_number; + dof_f2 f2; +}; + +static_assert(sizeof(dof_debug) == 0x20, "\"dof_debug\" struct should have a size of 0x14"); + +struct dof_pv { + bool enable; + dof_f2 f2; +}; + +static_assert(sizeof(dof_pv) == 0x14, "\"dof_pv\" struct should have a size of 0x14"); + +namespace renderer { + struct DOF3 { + int32_t width; + int32_t height; + GLuint textures[6]; + FBO fbo[4]; + GLuint samplers[2]; + GLuint vao; + GLuint program[9]; + GLUniformBuffer common_ubo; + GLUniformBuffer texcoords_ubo; + + void apply(RenderTexture* rt); + void resize(int32_t width, int32_t height); + + private: + void apply_f2(RenderTexture* rt, GLuint color_texture, + GLuint depth_texture, float_t min_distance, float_t max_distance, float_t fov, + float_t focus, float_t focus_range, float_t fuzzing_range, float_t ratio); + void apply_physical(RenderTexture* rt, GLuint color_texture, + GLuint depth_texture, float_t min_distance, float_t max_distance, + float_t focus, float_t focal_length, float_t fov, float_t f_number); + + void render_tiles(GLuint depth_texture, bool f2); + void downsample(GLuint color_texture, GLuint depth_texture, bool f2); + void main_filter(bool f2); + void upsample(RenderTexture* rt, GLuint color_texture, GLuint depth_texture, bool f2); + + void update_data(float_t min_dist, float_t max_dist, float_t fov, float_t dist, float_t focal_length, + float_t f_number, float_t focus_range, float_t fuzzing_range, float_t ratio); + }; + + static_assert(sizeof(renderer::DOF3) == 0xD8, "\"renderer::DOF3\" struct should have a size of 0xD8"); +} + +extern dof_debug* dof_debug_data; +extern dof_pv* dof_pv_data; diff --git a/src/DivaGL/renderer/fbo.cpp b/src/DivaGL/renderer/fbo.cpp new file mode 100644 index 0000000..b216c9e --- /dev/null +++ b/src/DivaGL/renderer/fbo.cpp @@ -0,0 +1,62 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "fbo.hpp" +#include "../gl_state.hpp" + +namespace renderer { +#pragma warning(push) +#pragma warning(disable: 6385) +#pragma warning(disable: 6386) + void FBO::init(int32_t width, int32_t height, + GLuint* color_textures, int32_t count, GLuint depth_texture) { + free(); + + count = min_def(count, 8); + + this->width = width; + this->height = height; + this->count = count; + flags = (Flags)0; + if (depth_texture) { + this->flags = DEPTH_ATTACHMENT; + this->count++; + } + + textures = new GLuint[this->count]; + for (int32_t i = 0; i < count; i++) + textures[i] = color_textures[i]; + + if (flags & DEPTH_ATTACHMENT) + textures[count] = depth_texture; + + glGenFramebuffers(1, &buffer); + glBindFramebuffer(GL_FRAMEBUFFER, buffer); + for (int32_t i = 0; i < count; i++) + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, textures[i], 0); + + if (flags & DEPTH_ATTACHMENT) + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textures[count], 0); + + GLenum color_attachments[8]; + for (int32_t i = 0; i < count; i++) + color_attachments[i] = GL_COLOR_ATTACHMENT0 + i; + glDrawBuffers(count, color_attachments); + glCheckFramebufferStatus(GL_FRAMEBUFFER); + } +#pragma warning(pop) + + void FBO::free() { + if (buffer) { + glDeleteFramebuffers(1, &buffer); + buffer = 0; + } + + if (textures) { + delete[] textures; + textures = 0; + } + } +} diff --git a/src/DivaGL/renderer/fbo.hpp b/src/DivaGL/renderer/fbo.hpp new file mode 100644 index 0000000..2397c50 --- /dev/null +++ b/src/DivaGL/renderer/fbo.hpp @@ -0,0 +1,29 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../shared.hpp" + +namespace renderer { + struct FBO { + enum Flags { + DEPTH_ATTACHMENT = 0x01, + }; + + Flags flags; + int32_t width; + int32_t height; + GLuint buffer; + int32_t count; + GLuint* textures; + + void init(int32_t width, int32_t height, + GLuint* color_textures, int32_t count, GLuint depth_texture); + void free(); + }; + + static_assert(sizeof(renderer::FBO) == 0x20, "\"renderer::FBO\" struct should have a size of 0x20"); +} diff --git a/src/DivaGL/renderer/transparency.cpp b/src/DivaGL/renderer/transparency.cpp new file mode 100644 index 0000000..1da90fe --- /dev/null +++ b/src/DivaGL/renderer/transparency.cpp @@ -0,0 +1,46 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "transparency.hpp" +#include "../../KKdLib/str_utils.hpp" +#include "../render_context.hpp" +#include "../gl_state.hpp" + +extern render_context* rctx; + +namespace renderer { + void Transparency::combine(RenderTexture* rt, float_t alpha) { + vec4 g_opacity = { alpha, 0.0f, 0.0f, 0.0f }; + + gl_state_disable_blend(); + gl_state_disable_depth_test(); + rctx->render_buffer.Bind(); + gl_state_use_program(program); + glUniform4fv(0, 1, (GLfloat*)&g_opacity.x); + gl_state_active_bind_texture_2d(0, fbo.textures[0]); + gl_state_active_bind_texture_2d(1, rt->GetColorTex()); + gl_state_bind_vertex_array(vao); + glDrawArraysDLL(GL_TRIANGLE_STRIP, 0, 4); + gl_state_enable_depth_test(); + + glCopyImageSubData( + rctx->render_buffer.GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, + rt->GetColorTex(), GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); + } + + void Transparency::copy(GLuint texture) { + glCopyImageSubData( + texture, GL_TEXTURE_2D, 0, 0, 0, 0, + fbo.textures[0], GL_TEXTURE_2D, 0, 0, 0, 0, fbo.width, fbo.height, 1); + gl_state_bind_framebuffer(fbo.buffer); + glViewportDLL(0, 0, fbo.width, fbo.height); + } + + void Transparency::resize(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height) { + GLuint color_textures[1]; + color_textures[0] = color_texture; + fbo.init(width, height, color_textures, 1, depth_texture); + } +} diff --git a/src/DivaGL/renderer/transparency.hpp b/src/DivaGL/renderer/transparency.hpp new file mode 100644 index 0000000..8ca73cd --- /dev/null +++ b/src/DivaGL/renderer/transparency.hpp @@ -0,0 +1,29 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/vec.hpp" +#include "../render_texture.hpp" +#include "fbo.hpp" + +namespace renderer { + struct Transparency { + private: + FBO fbo; + GLuint program; + GLuint sampler; + GLuint vao; + + public: + void combine(RenderTexture* rt, float_t alpha); + void copy(GLuint texture); + + void resize(GLuint color_texture, GLuint depth_texture, int32_t width, int32_t height); + }; + + static_assert(sizeof(renderer::Transparency) == 0x30, "\"renderer::Transparency\" struct should have a size of 0x30"); +}; diff --git a/src/DivaGL/resolution_mode.cpp b/src/DivaGL/resolution_mode.cpp new file mode 100644 index 0000000..224a7c1 --- /dev/null +++ b/src/DivaGL/resolution_mode.cpp @@ -0,0 +1,177 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "resolution_mode.hpp" + +const resolution_table_struct resolution_table[] = { + { 320, 240, 0, 0, 0, 320, 225 }, // QVGA + { 640, 480, 0, 0, 60, 640, 360 }, // VGA + { 800, 600, 0, 0, 75, 800, 450 }, // SVGA + { 1024, 768, 0, 0, 96, 1024, 576 }, // XGA + { 1280, 1024, 1, 0, 152, 1280, 720 }, // SXGA + { 1400, 1050, 0, 0, 131, 1400, 788 }, // SXGA+ + { 1600, 1200, 0, 0, 150, 1600, 900 }, // UXGA + { 800, 480, 2, 0, 15, 800, 450 }, // WVGA + { 1024, 600, 2, 0, 12, 1024, 576 }, // WSVGA + { 1280, 768, 2, 0, 24, 1280, 720 }, // WXGA + { 1360, 768, 3, 0, 2, 1360, 765 }, // FWXGA + { 1920, 1200, 2, 0, 60, 1920, 1200 }, // WUXGA + { 2560, 1536, 2, 0, 48, 2560, 1440 }, // WQXGA + { 1280, 720, 3, 0, 0, 1280, 720 }, // HD + { 1920, 1080, 3, 0, 0, 1920, 1080 }, // FHD + { 2560, 1440, 3, 0, 0, 2560, 1440 }, // QHD + { 480, 272, 3, 0, 0, 480, 272 }, // WQVGA + { 960, 544, 3, 0, 0, 960, 544 }, // qHD + + // MM+ + /*{ 320, 240, 0, 0, 0, 320, 225 }, // QVGA + { 640, 480, 0, 0, 60, 640, 360 }, // VGA + { 800, 600, 0, 0, 75, 800, 450 }, // SVGA + { 1024, 768, 0, 0, 96, 1024, 576 }, // XGA + { 1280, 1024, 1, 0, 152, 1280, 720 }, // SXGA + { 1400, 1050, 0, 0, 131, 1400, 788 }, // SXGA+ + { 1600, 1200, 0, 0, 150, 1600, 900 }, // UXGA + { 800, 480, 2, 0, 15, 800, 450 }, // WVGA + { 1024, 600, 2, 0, 12, 1024, 576 }, // WSVGA + { 1280, 768, 2, 0, 24, 1280, 720 }, // WXGA + { 1360, 768, 3, 0, 2, 1360, 765 }, // FWXGA + { 1920, 1200, 2, 0, 60, 1920, 1200 }, // WUXGA + { 2560, 1536, 2, 0, 48, 2560, 1440 }, // WQXGA + { 1280, 720, 3, 0, 0, 1280, 720 }, // HD + { 1920, 1080, 3, 0, 0, 1920, 1080 }, // FHD + { 3840, 2160, 3, 0, 0, 3840, 2160 }, // UHD + { 3840, 2160, 3, 0, 0, 2880, 1620 }, // 3K at UHD + { 2880, 1620, 3, 0, 0, 2880, 1620 }, // 3K + { 2560, 1440, 3, 0, 0, 2560, 1440 }, // QHD + { 480, 272, 3, 0, 0, 480, 272 }, // WQVGA + { 960, 544, 3, 0, 0, 960, 544 }, // qHD + { 1152, 864, 0, 0, 0, 1152, 864 }, // XGA+ + { 1176, 664, 3, 0, 0, 1176, 664 }, // 1176x664 + { 1200, 960, 1, 0, 0, 1200, 960 }, // 1200x960 + { 1280, 800, 2, 0, 0, 1280, 800 }, // WXGA1280x900 + { 1280, 960, 0, 0, 0, 1280, 960 }, // SXGA- + { 1366, 768, 3, 0, 0, 1366, 768 }, // FWXGA1366x766 + { 1440, 900, 2, 0, 0, 1440, 900 }, // WXGA+ + { 1600, 900, 0, 0, 0, 1600, 900 }, // HD+ + { 1600, 1024, 2, 0, 0, 1600, 1024 }, // WSXGA + { 1680, 1050, 2, 0, 0, 1680, 1050 }, // WSXGA+ + { 1920, 1440, 0, 0, 0, 1920, 1440 }, // 1920x1440 + { 2048, 1152, 0, 0, 0, 2048, 1152 }, // QWXGA*/ +}; + +resolution_struct* res_window = (resolution_struct*)0x0000000140EDA8B0; +resolution_struct* res_window_internal = (resolution_struct*)0x0000000140EDA8D8; + +resolution_struct::resolution_struct(::resolution_mode mode) { + resolution_mode = mode; + x_offset = 0; + y_offset = 0; + if (mode == RESOLUTION_MODE_MAX) { + width = res_window->width; + height = res_window->height; + aspect = res_window->aspect; + field_20 = res_window->field_20; + } + else { + width = resolution_table[mode].width_full; + height = resolution_table[mode].height_full; + aspect = (double_t)width / (double_t)height; + field_20 = resolution_table[mode].field_8; + } +} + +resolution_mode_scale_data::resolution_mode_scale_data( + resolution_mode src_mode, resolution_mode dst_mode) { + scale = 1.0f; + src_res = 0.0f; + dst_res = 0.0f; + this->src_mode = src_mode; + this->dst_mode = dst_mode; + scale = resolution_mode_get_scale(dst_mode, src_mode); + if (dst_mode != RESOLUTION_MODE_MAX && src_mode != RESOLUTION_MODE_MAX + && dst_mode >= RESOLUTION_MODE_QVGA && src_mode >= RESOLUTION_MODE_MAX + && dst_mode < RESOLUTION_MODE_MAX && src_mode < RESOLUTION_MODE_MAX) { + src_res.x = (float_t)resolution_table[src_mode].width_full * 0.5f; + src_res.y = (float_t)resolution_table[src_mode].height_full * 0.5f; + dst_res.x = (float_t)resolution_table[dst_mode].width_full * 0.5f; + dst_res.y = (float_t)resolution_table[dst_mode].height_full * 0.5f; + } +} + +resolution_struct* res_window_get() { + return res_window; +} + +resolution_struct* res_window_internal_get() { + return res_window_internal; +} + +void res_window_set(resolution_mode mode) { + *res_window = resolution_struct(mode); + + int32_t width = resolution_table[mode].width; + int32_t height = resolution_table[mode].height; + + res_window_internal->resolution_mode = RESOLUTION_MODE_MAX; + res_window_internal->x_offset = resolution_table[mode].x_offset; + res_window_internal->y_offset = resolution_table[mode].y_offset; + res_window_internal->width = width; + res_window_internal->height = height; + res_window_internal->aspect = (double_t)width / (double_t)height; + res_window_internal->field_20 = 4; + + for (int32_t i = 0; i < RESOLUTION_MODE_MAX; i++) + if (resolution_table[i].width_full == width && resolution_table[i].height_full == height) { + res_window_internal->resolution_mode = (resolution_mode)i; + res_window_internal->field_20 = resolution_table[i].field_8; + } +} + +vec2 resolution_mode_get_scale(const resolution_mode dst_mode, const resolution_mode src_mode) { + if (dst_mode == RESOLUTION_MODE_MAX || src_mode == RESOLUTION_MODE_MAX + || dst_mode < RESOLUTION_MODE_QVGA || src_mode < RESOLUTION_MODE_QVGA + || dst_mode >= RESOLUTION_MODE_MAX || src_mode >= RESOLUTION_MODE_MAX) + return 1.0f; + + float_t scale_x = (float_t)resolution_table[dst_mode].width_full / (float_t)resolution_table[src_mode].width_full; + float_t scale_y = (float_t)resolution_table[dst_mode].height_full / (float_t)resolution_table[src_mode].height_full; + int32_t v9 = resolution_table[src_mode].field_8; + int32_t v10 = resolution_table[dst_mode].field_8; + if (v9 != v10) { + if (!v9 && 10 == 1) + return scale_x; + + if (v9 == 2 || v9 == 3) + switch (v10) { + case 0: + case 1: + case 2: + return scale_x; + } + } + + if (src_mode == RESOLUTION_MODE_qHD && dst_mode != RESOLUTION_MODE_qHD && v10 == 3) + return scale_x; + else + return scale_y; +} + +void resolution_mode_scale_pos(vec2& dst_pos, const resolution_mode dst_mode, + const vec2& src_pos, const resolution_mode src_mode) { + if (dst_mode == RESOLUTION_MODE_MAX || src_mode == RESOLUTION_MODE_MAX + || dst_mode < RESOLUTION_MODE_QVGA || src_mode < RESOLUTION_MODE_QVGA + || dst_mode >= RESOLUTION_MODE_MAX || src_mode >= RESOLUTION_MODE_MAX) { + dst_pos = src_pos; + return; + } + + const resolution_table_struct* src = &resolution_table[src_mode]; + const resolution_table_struct* dst = &resolution_table[dst_mode]; + + vec2 src_size((float_t)src->width_full, (float_t)src->height_full); + vec2 dst_size((float_t)dst->width_full, (float_t)dst->height_full); + vec2 scale = resolution_mode_get_scale(dst_mode, src_mode); + dst_pos = dst_size * 0.5f + (src_pos - src_size * 0.5f) * scale; +} \ No newline at end of file diff --git a/src/DivaGL/resolution_mode.hpp b/src/DivaGL/resolution_mode.hpp new file mode 100644 index 0000000..850c5ea --- /dev/null +++ b/src/DivaGL/resolution_mode.hpp @@ -0,0 +1,55 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/spr.hpp" +#include "../KKdLib/vec.hpp" + +struct resolution_table_struct { + int32_t width_full; + int32_t height_full; + int32_t field_8; + int32_t x_offset; + int32_t y_offset; + int32_t width; + int32_t height; +}; + +struct resolution_struct { + resolution_mode resolution_mode; + int32_t x_offset; + int32_t y_offset; + int32_t width; + int32_t height; + double_t aspect; + int32_t field_20; + + inline resolution_struct() : resolution_struct(RESOLUTION_MODE_MAX) { + + } + + resolution_struct(::resolution_mode mode); +}; + +struct resolution_mode_scale_data { + vec2 scale; + vec2 src_res; + vec2 dst_res; + resolution_mode src_mode; + resolution_mode dst_mode; + + resolution_mode_scale_data(resolution_mode src_mode, resolution_mode dst_mode); +}; + +extern const resolution_table_struct resolution_table[]; + +extern resolution_struct* res_window_get(); +extern resolution_struct* res_window_internal_get(); +extern void res_window_set(resolution_mode mode); +extern vec2 resolution_mode_get_scale(const resolution_mode dst_mode, const resolution_mode src_mode); +extern void resolution_mode_scale_pos(vec2& dst_pos, const resolution_mode dst_mode, + const vec2& src_pos, const resolution_mode src_mode); diff --git a/src/DivaGL/rob/rob.cpp b/src/DivaGL/rob/rob.cpp new file mode 100644 index 0000000..778f905 --- /dev/null +++ b/src/DivaGL/rob/rob.cpp @@ -0,0 +1,136 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "rob.hpp" +#include "../mdl/disp_manager.hpp" +#include "../gl_state.hpp" +#include "../object.hpp" +#include +#include + +struct rob_chara_age_age_object_vertex { + vec3 position; + vec3 normal; + vec4 tangent; + vec2 texcoord; +}; + +struct rob_chara_age_age_object { + void* obj_set_handler; // obj_set_handler + int32_t obj_index; + int32_t field_C; + int32_t num_vertex; + int32_t num_index; + obj obj; + obj_mesh mesh; + obj_sub_mesh sub_mesh; + obj_material_data material[2]; + obj_axis_aligned_bounding_box axis_aligned_bounding_box; + rob_chara_age_age_object_vertex* vertex_data; + int32_t vertex_data_size; + int32_t vertex_array_size; + obj_mesh_vertex_buffer obj_vert_buf; + obj_mesh_index_buffer obj_index_buf; + vec3 trans[10]; + int32_t disp_count; + int32_t count; + bool field_C3C; +}; + +mat4* (FASTCALL* rob_chara_bone_data_get_mats_mat)(size_t rob_bone_data, size_t index) + = (mat4 * (FASTCALL*)(size_t rob_bone_data, size_t index))0x0000000140419520; +void(FASTCALL* sub_1405163C0)(size_t rob_chr, int32_t index, mat4* mat) + = (void(FASTCALL*)(size_t rob_chr, int32_t index, mat4 * mat))0x00000001405163C0; +float_t(FASTCALL* rob_chara_get_max_face_depth)(size_t rob_chr) + = (float_t(FASTCALL*)(size_t rob_chr))0x0000000140516510; +mat4* (FASTCALL* sub_140516740)(size_t rob_chr) + = (mat4 * (FASTCALL*)(size_t rob_chr))0x0000000140516740; +mat4* (FASTCALL* rob_chara_get_adjust_data_mat)(size_t rob_chr) + = (mat4 * (FASTCALL*)(size_t rob_chr))0x0000000140516750; +bool(FASTCALL* rob_chara_array_check_visibility)(size_t rob_chr, int32_t chara_id) + = (bool(FASTCALL*)(size_t rob_chr, int32_t chara_id))0x0000000140531F50; +size_t(FASTCALL* get_rob_chara_smth)() = (size_t(FASTCALL*)())0x00000001405320E0; +size_t(FASTCALL* rob_chara_array_get)(size_t rob_chr_smth, int32_t chara_id) + = (size_t(FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x0000000140532030; +size_t(FASTCALL* rob_chara_array_get_bone_data)(size_t rob_chr_smth, int32_t chara_id) + = (size_t(FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x00000001405320F0; +bool (FASTCALL* rob_chara_pv_data_array_check_chara_id)(size_t rob_chr_smth, int32_t chara_id) + = (bool (FASTCALL*)(size_t rob_chr_smth, int32_t chara_id))0x00000001405327B0; + +HOOK(void, FASTCALL, rob_chara_age_age_object__disp, 0x0000000140541D50, + rob_chara_age_age_object* rob_age_age_obj, size_t chara_index, bool npr, bool reflect, vec3* a5, bool chara_color) { + int32_t disp_count = rob_age_age_obj->disp_count; + if (!rob_age_age_obj->obj_set_handler || !disp_count) + return; + + disp_count = min_def(disp_count, 10); + + std::pair v44[10]; + for (int32_t i = 0; i < disp_count; i++) { + v44[i].first = vec3::dot(rob_age_age_obj->trans[i], *a5); + v44[i].second = i; + } + + if (disp_count >= 2) + std::sort(v44, v44 + disp_count, + [](const std::pair& a, const std::pair& b) { + return a.first < b.first; + }); + + rob_age_age_obj->obj_vert_buf.cycle_index(); + + GLuint buffer = rob_age_age_obj->obj_vert_buf.get_buffer(); + size_t vtx_data; + if (GL_VERSION_4_5) { + vtx_data = (size_t)glMapNamedBuffer(buffer, GL_WRITE_ONLY); + if (!vtx_data) { + glUnmapNamedBuffer(buffer); + return; + } + } + else { + gl_state_bind_array_buffer(buffer); + vtx_data = (size_t)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + if (!vtx_data) { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + return; + } + } + + size_t vertex_array_size = rob_age_age_obj->vertex_array_size; + for (int32_t i = 0; i < disp_count; i++) + memmove((void*)(vtx_data + vertex_array_size * i), + (void*)((size_t)rob_age_age_obj->vertex_data + vertex_array_size * v44[i].second), vertex_array_size); + + if (GL_VERSION_4_5) + glUnmapNamedBuffer(buffer); + else { + glUnmapBuffer(GL_ARRAY_BUFFER); + gl_state_bind_array_buffer(0); + } + + rob_age_age_obj->mesh.num_vertex = disp_count * rob_age_age_obj->num_vertex; + rob_age_age_obj->sub_mesh.num_index = disp_count * rob_age_age_obj->num_index; + rob_age_age_obj->sub_mesh.material_index = npr ? 1 : 0; + + mdl::ObjFlags flags = (mdl::ObjFlags)(mdl::OBJ_SSS | mdl::OBJ_4 | mdl::OBJ_SHADOW); + if (reflect) + enum_or(flags, mdl::OBJ_CHARA_REFLECT); + disp_manager->set_obj_flags(flags); + disp_manager->set_chara_color(chara_color); + disp_manager->set_shadow_type(chara_index ? SHADOW_STAGE : SHADOW_CHARA); + + static prj::vector*(FASTCALL * rob_chara_age_age_object__get_obj_set_texture)(rob_chara_age_age_object * rob_age_age_obj) + = (prj::vector*(FASTCALL*)(rob_chara_age_age_object* rob_age_age_obj))0x000000014045A8E0; + disp_manager->entry_obj_by_obj(&mat4_identity, &rob_age_age_obj->obj, + rob_chara_age_age_object__get_obj_set_texture(rob_age_age_obj), + &rob_age_age_obj->obj_vert_buf, &rob_age_age_obj->obj_index_buf, 0, 1.0f); +} + + +void rob_patch() { + INSTALL_HOOK(rob_chara_age_age_object__disp); +} diff --git a/src/DivaGL/rob/rob.hpp b/src/DivaGL/rob/rob.hpp new file mode 100644 index 0000000..c578837 --- /dev/null +++ b/src/DivaGL/rob/rob.hpp @@ -0,0 +1,25 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../../KKdLib/default.hpp" +#include "../../KKdLib/mat.hpp" +#include "../../KKdLib/vec.hpp" + +#define ROB_CHARA_COUNT 6 + +extern mat4* (FASTCALL* rob_chara_bone_data_get_mats_mat)(size_t rob_bone_data, size_t index); +extern void(FASTCALL* sub_1405163C0)(size_t rob_chr, int32_t index, mat4* mat); +extern float_t(FASTCALL* rob_chara_get_max_face_depth)(size_t rob_chr); +extern mat4* (FASTCALL* sub_140516740)(size_t rob_chr); +extern mat4* (FASTCALL* rob_chara_get_adjust_data_mat)(size_t rob_chr); +extern bool(FASTCALL* rob_chara_array_check_visibility)(size_t rob_chr, int32_t chara_id); +extern size_t(FASTCALL* get_rob_chara_smth)(); +extern size_t(FASTCALL* rob_chara_array_get)(size_t rob_chr_smth, int32_t chara_id); +extern size_t(FASTCALL* rob_chara_array_get_bone_data)(size_t rob_chr_smth, int32_t chara_id); +extern bool (FASTCALL* rob_chara_pv_data_array_check_chara_id)(size_t rob_chr_smth, int32_t chara_id); + +extern void rob_patch(); diff --git a/src/DivaGL/shader_glsl.cpp b/src/DivaGL/shader_glsl.cpp new file mode 100644 index 0000000..67f32a3 --- /dev/null +++ b/src/DivaGL/shader_glsl.cpp @@ -0,0 +1,993 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "shader_glsl.hpp" +#include "../KKdLib/io/file_stream.hpp" +#include "../KKdLib/io/path.hpp" +#include "../KKdLib/hash.hpp" +#include "../KKdLib/str_utils.hpp" +#include "gl_state.hpp" +#include "print.hpp" +#include "uniform.hpp" +#include "wrap.hpp" +#include + +struct program_binary { + GLsizei length; + GLenum binary_format; + size_t binary; +}; + +struct program_spv { + size_t size; + size_t spv; +}; + +extern bool vulkan_render; + +static GLuint shader_compile_shader(GLenum type, const char* data, const char* file); +static GLuint shader_compile(const char* vert, const char* frag, const char* vp, const char* fp); +static GLuint shader_compile_binary(const char* vert, const char* frag, const char* vp, const char* fp, + program_binary* bin, GLsizei* buffer_size, void** binary); +static bool shader_load_binary_shader(program_binary* bin, GLuint* program); +static void shader_glsl_update_data(shader_glsl_set_data* set); + +int32_t shader_glsl::bind(shader_glsl_set_data* set, uint32_t sub_index) { + set->curr_shader = 0; + + if (num_sub < 1) + return -1; + + int32_t sub_shader_index = 0; + for (shader_glsl_sub* i = sub; i->sub_index != sub_index; i++) + if (++sub_shader_index >= num_sub) + return -1; + + shader_glsl_sub* sub_shader = &sub[sub_shader_index]; + + int32_t unival_shad_curr = 1; + int32_t unival_shad = 0; + int32_t uniform_val[SHADER_MAX_UNIFORM_VALUES] = {}; + if (num_uniform > 0) { + const int32_t* vp_unival_max = sub_shader->vp_unival_max; + const int32_t* fp_unival_max = sub_shader->fp_unival_max; + + int32_t i = 0; + for (i = 0; i < num_uniform && i < sizeof(uniform_val) / sizeof(int32_t); i++) { + const int32_t unival = uniform->arr[use_uniform[i]]; + const int32_t unival_max = use_permut[i] + ? max_def(vp_unival_max[i], fp_unival_max[i]) : 0; + unival_shad += unival_shad_curr * min_def(unival, unival_max); + unival_shad_curr *= unival_max + 1; + + int32_t unival_max_glsl = max_def(vp_unival_max[i], fp_unival_max[i]); + uniform_val[i] = min_def(unival, unival_max_glsl); + } + } + + shader_glsl_sub_shader* shader = &sub_shader->shaders[unival_shad]; + set->curr_shader = shader; + + gl_state_use_program(shader->program); + if (memcmp(shader->uniform_val, uniform_val, sizeof(uniform_val))) { + memcpy(shader->uniform_val, uniform_val, sizeof(uniform_val)); + shader->uniform_val_update = true; + } + return 0; +} + +bool shader_glsl::parse_define(const char* data, char** temp, size_t* temp_size) { + if (!data) + return false; + + const char* def = strstr(data, "//DEF\n"); + if (!def) { + size_t len = utf8_length(data); + if (len + 1 > *temp_size) { + free_def(*temp); + *temp_size = len + 1; + *temp = force_malloc(*temp_size); + } + + memcpy(*temp, data, len); + (*temp)[len] = 0; + return true; + } + + size_t len_a = def - data; + def += 5; + if (*def == '\n') + def++; + + size_t len_b = utf8_length(def); + size_t len = 0; + len += len_a + len_b; + + if (len + 1 > *temp_size) { + free_def(*temp); + *temp_size = len + 1; + *temp = force_malloc(*temp_size); + } + + size_t pos = 0; + memcpy(*temp + pos, data, len_a); + pos += len_a; + memcpy(*temp + pos, def, len_b); + pos += len_b; + (*temp)[pos] = 0; + return true; +} + +bool shader_glsl::parse_define(const char* data, int32_t num_uniform, + int32_t* uniform_value, char** temp, size_t* temp_size) { + if (!data) + return false; + + const char* def = strstr(data, "//DEF\n"); + if (!def) { + size_t len = utf8_length(data); + if (len + 1 > *temp_size) { + free_def(*temp); + *temp_size = len + 1; + *temp = force_malloc(*temp_size); + } + + memcpy(*temp, data, len); + (*temp)[len] = 0; + return true; + } + + const int32_t s = min_def(0x100, num_uniform); + + size_t t_len[0x100]; + char t[0x100] = {}; + + for (int32_t i = 0; i < s; i++) { + sprintf_s(t, sizeof(t), "#define _%d %d\n", i, uniform_value[i]); + t_len[i] = utf8_length(t); + } + + size_t len_a = def - data; + def += 5; + size_t len_b = utf8_length(def); + size_t len = 0; + for (int32_t i = 0; i < s; i++) + len += t_len[i]; + if (!len) + def++; + len += len_a + len_b; + + if (len + 1 > *temp_size) { + free_def(*temp); + *temp_size = len + 1; + *temp = force_malloc(*temp_size); + } + + size_t pos = 0; + memcpy(*temp + pos, data, len_a); + pos += len_a; + for (int32_t i = 0; i < s; i++) { + sprintf_s(t, sizeof(t), "#define _%d %d\n", i, uniform_value[i]); + memcpy(*temp + pos, t, t_len[i]); + pos += t_len[i]; + } + memcpy(*temp + pos, def, len_b); + pos += len_b; + (*temp)[pos] = 0; + return true; +} + +char* shader_glsl::parse_include(char* data, farc* f) { + if (!data || !f) + return data; + + char* data_end = data + utf8_length(data); + char* i0 = strstr(data, "#include \""); + char* i1 = i0 ? strstr(i0, "\"\n") : 0; + if (!i0 || !i1) + return data; + + size_t count = 1; + while (i1 && (i0 = strstr(i1, "#include \""))) { + i0 += 10; + i1 = strstr(i0, "\"\n"); + if (i1) + i1 += 1; + count++; + } + + char** temp = force_malloc(count); + size_t* temp_len = force_malloc(count); + char** temp_ptr0 = force_malloc(count); + char** temp_ptr1 = force_malloc(count); + if (!temp || !temp_len || !temp_ptr0 || !temp_ptr1) { + free_def(temp); + free_def(temp_len); + free_def(temp_ptr0); + free_def(temp_ptr1); + return data; + } + + i1 = data; + for (size_t i = 0; i < count; i++) { + temp[i] = 0; + i0 = i1 ? strstr(i1, "#include \"") : 0; + i1 = i0 ? strstr(i0, "\"\n") : 0; + if (!i0 || !i1) + continue; + + temp_ptr0[i] = i0; + temp_ptr1[i] = i1 + 1; + i0 += 10; + size_t s = i1 - i0; + i1 += 2; + char* t = force_malloc(s + 1); + if (!t) + continue; + + memcpy(t, i0, s); + t[s] = 0; + + farc_file* ff = f->read_file(t); + free_def(t); + if (!ff) + continue; + + t = force_malloc(ff->size + 1); + if (t) { + memcpy(t, ff->data, ff->size); + t[ff->size] = 0; + } + temp[i] = t; + temp_len[i] = ff->size; + } + + size_t len = data_end - data; + i1 = data; + for (size_t i = 0; i < count; i++) { + i0 = temp_ptr0[i]; + i1 = temp_ptr1[i]; + if (!i0 || !i1) + continue; + + len -= i1 - i0; + len += temp_len[i]; + } + + char* temp_data = force_malloc(len + 1); + size_t pos = 0; + memcpy(temp_data + pos, data, temp_ptr0[0] - data); + pos += temp_ptr0[0] - data; + for (int32_t i = 0; i < count; i++) { + if (temp[i]) { + size_t s = temp_len[i]; + memcpy(temp_data + pos, temp[i], s); + pos += s; + } + + if (i < count - 1 && temp_ptr1[i]) { + size_t s = temp_ptr0[i + 1] - temp_ptr1[i]; + memcpy(temp_data + pos, temp_ptr1[i], s); + pos += s; + } + else if (temp_ptr1[i]) { + size_t s = data_end - temp_ptr1[i]; + memcpy(temp_data + pos, temp_ptr1[i], s); + pos += s; + } + } + temp_data[pos] = 0; + + free_def(data); + for (size_t i = 0; i < count; i++) + free_def(temp[i]); + free_def(temp); + free_def(temp_len); + free_def(temp_ptr0); + free_def(temp_ptr1); + return temp_data; +} + +void shader_glsl::unbind() { + gl_state_use_program(0); +} + +shader_glsl_set_data::shader_glsl_set_data() : size(), shaders(), curr_shader(), +primitive_restart(), primitive_restart_index(), get_index_by_name_func() { + +} + +void shader_glsl_set_data::disable_primitive_restart() { + primitive_restart = false; +} + +void shader_glsl_set_data::draw_arrays(GLenum mode, GLint first, GLsizei count) { + shader_glsl_update_data(this); + glDrawArraysDLL(mode, first, count); +} + +void shader_glsl_set_data::draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices) { + switch (mode) { + case GL_TRIANGLE_STRIP: + uint32_t index; + switch (type) { + case GL_UNSIGNED_BYTE: + index = 0xFF; + break; + case GL_UNSIGNED_SHORT: + index = 0xFFFF; + break; + case GL_UNSIGNED_INT: + default: + index = 0xFFFFFFFF; + break; + } + + enable_primitive_restart(); + + if (primitive_restart_index != index) + primitive_restart_index = index; + break; + } + + shader_glsl_update_data(this); + glDrawElementsDLL(mode, count, type, indices); + + switch (mode) { + case GL_TRIANGLE_STRIP: + disable_primitive_restart(); + break; + } +} + +void shader_glsl_set_data::draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { + switch (mode) { + case GL_TRIANGLE_STRIP: + uint32_t index; + switch (type) { + case GL_UNSIGNED_BYTE: + index = 0xFF; + break; + case GL_UNSIGNED_SHORT: + index = 0xFFFF; + break; + case GL_UNSIGNED_INT: + default: + index = 0xFFFFFFFF; + break; + } + + enable_primitive_restart(); + + if (primitive_restart_index != index) + primitive_restart_index = index; + break; + } + + shader_glsl_update_data(this); + glDrawRangeElements(mode, start, end, count, type, indices); + + switch (mode) { + case GL_TRIANGLE_STRIP: + disable_primitive_restart(); + break; + } +} + +void shader_glsl_set_data::enable_primitive_restart() { + primitive_restart = true; +} + +int32_t shader_glsl_set_data::get_index_by_name(const char* name) { + if (get_index_by_name_func) { + int32_t index = get_index_by_name_func(name); + if (index != -1) + return index; + } + + for (size_t i = 0; i < size; i++) + if (!str_utils_compare(shaders[i].name, name)) + return (int32_t)shaders[i].name_index; + return -1; +} + +void shader_glsl_set_data::load(farc* f, bool ignore_cache, + const char* name, const shader_glsl_table* shaders_table, const size_t size, + const shader_glsl_bind_func* bind_func_table, const size_t bind_func_table_size, + PFNSHADERGLSLGETINDEXFUNCPROC get_index_by_name) { + if (!this || !f || !shaders_table || !size) + return; + + wchar_t temp_buf[MAX_PATH]; + if (FAILED(SHGetFolderPathW(0, CSIDL_LOCAL_APPDATA, 0, 0, temp_buf))) + return; + + wcscat_s(temp_buf, sizeof(temp_buf) / sizeof(wchar_t), L"\\PDAFT"); + CreateDirectoryW(temp_buf, 0); + + wchar_t buf[MAX_PATH]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), L"\\%hs_shader_cache", name); + wcscat_s(temp_buf, sizeof(temp_buf) / sizeof(wchar_t), buf); + + bool shader_cache_changed = false; + farc shader_cache_farc; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), L"%ls.farc", temp_buf); + if (!ignore_cache && path_check_file_exists(buf)) + shader_cache_farc.read(buf, true, false); + + char vert_buf[MAX_PATH]; + char frag_buf[MAX_PATH]; + char vert_file_buf[MAX_PATH]; + char frag_file_buf[MAX_PATH]; + + GLsizei buffer_size = 0x100000; + void* binary = force_malloc(buffer_size); + size_t temp_vert_size = 0x10000; + char* temp_vert = force_malloc(temp_vert_size); + size_t temp_frag_size = 0x10000; + char* temp_frag = force_malloc(temp_frag_size); + std::vector vec_vert; + std::vector vec_frag; + std::vector program_data_binary; + shader_glsl* shaders = force_malloc(size); + this->shaders = shaders; + this->size = size; + for (size_t i = 0; i < size; i++) { + shader_glsl* shader = &shaders[i]; + shader->name = shaders_table[i].name; + shader->name_index = shaders_table[i].name_index; + shader->num_sub = shaders_table[i].num_sub; + shader->sub = force_malloc(shader->num_sub); + shader->num_uniform = shaders_table[i].num_uniform; + shader->use_uniform = shaders_table[i].use_uniform; + shader->use_permut = shaders_table[i].use_permut; + + int32_t num_sub = shader->num_sub; + const shader_glsl_sub_table* sub_table = shaders_table[i].sub; + shader_glsl_sub* sub = shader->sub; + vec_vert.resize(shader->num_uniform); + vec_frag.resize(shader->num_uniform); + int32_t* vec_vert_data = vec_vert.data(); + int32_t* vec_frag_data = vec_frag.data(); + for (size_t j = 0; j < num_sub; j++, sub++, sub_table++) { + sub->sub_index = sub_table->sub_index; + sub->vp_unival_max = sub_table->vp_unival_max; + sub->fp_unival_max = sub_table->fp_unival_max; + + strcpy_s(vert_file_buf, sizeof(vert_file_buf), sub_table->vp); + strcat_s(vert_file_buf, sizeof(vert_file_buf), ".vert"); + farc_file* vert_ff = f->read_file(vert_file_buf); + + char* vert_data = 0; + if (vert_ff && vert_ff->data) { + vert_data = force_malloc(vert_ff->size + 1); + if (vert_data) { + memcpy(vert_data, vert_ff->data, vert_ff->size); + vert_data[vert_ff->size] = 0; + } + } + + strcpy_s(frag_file_buf, sizeof(frag_file_buf), sub_table->fp); + strcat_s(frag_file_buf, sizeof(frag_file_buf), ".frag"); + farc_file* frag_ff = f->read_file(frag_file_buf); + + char* frag_data = 0; + if (frag_ff && frag_ff->data) { + frag_data = force_malloc(frag_ff->size + 1); + if (frag_data) { + memcpy(frag_data, frag_ff->data, frag_ff->size); + frag_data[frag_ff->size] = 0; + } + } + + if (!vert_data || !frag_data) { + free_def(vert_data); + free_def(frag_data); + continue; + } + + uint64_t vert_file_name_cache = hash_utf8_fnv1a64m(vert_file_buf); + uint64_t frag_file_name_cache = hash_utf8_fnv1a64m(frag_file_buf); + for (int32_t i = 0; i < 64; i += 8) + if (((vert_file_name_cache >> i) & 0xFF) == 0) + vert_file_name_cache |= 0xFFULL << i; + + for (int32_t i = 0; i < 64; i += 8) + if (((frag_file_name_cache >> i) & 0xFF) == 0) + frag_file_name_cache |= 0xFFULL << i; + + char shader_cache_file_name[MAX_PATH]; + strcpy_s(shader_cache_file_name, sizeof(shader_cache_file_name), sub_table->vp); + if (str_utils_compare(sub_table->vp, sub_table->fp)) { + strcat_s(shader_cache_file_name, sizeof(shader_cache_file_name), "."); + strcat_s(shader_cache_file_name, sizeof(shader_cache_file_name), sub_table->fp); + } + strcat_s(shader_cache_file_name, sizeof(shader_cache_file_name), ".bin"); + + vert_data = shader_glsl::parse_include(vert_data, f); + frag_data = shader_glsl::parse_include(frag_data, f); + uint64_t vert_data_hash = hash_utf8_fnv1a64m(vert_data); + uint64_t frag_data_hash = hash_utf8_fnv1a64m(frag_data); + + farc_file* shader_cache_file = shader_cache_farc.read_file(shader_cache_file_name); + program_binary* bin = 0; + if (!ignore_cache) { + if (!shader_cache_file || !shader_cache_file->data) + printf_debug("Shader not compiled: %s %s\n", vert_file_buf, frag_file_buf); + else if (vert_data_hash != ((uint64_t*)shader_cache_file->data)[0] + || frag_data_hash != ((uint64_t*)shader_cache_file->data)[1]) + printf_debug("Shader hash not equal: %s %s\n", vert_file_buf, frag_file_buf); + else + bin = (program_binary*)&((uint64_t*)shader_cache_file->data)[2]; + } + + if (shader->num_uniform > 0 + && (sub_table->vp_unival_max[0] != -1 || sub_table->fp_unival_max[0] != -1)) { + int32_t num_uniform = shader->num_uniform; + int32_t unival_shad_curr = 1; + int32_t unival_shad_count = 1; + const int32_t* vp_unival_max = sub_table->vp_unival_max; + const int32_t* fp_unival_max = sub_table->fp_unival_max; + for (size_t k = 0; k < num_uniform; k++) { + const int32_t unival_max = shader->use_permut[k] + ? max_def(vp_unival_max[k], fp_unival_max[k]) : 0; + unival_shad_count += unival_shad_curr * unival_max; + unival_shad_curr *= unival_max + 1; + } + + if (!ignore_cache) + program_data_binary.reserve(unival_shad_count); + shader_glsl_sub_shader* shaders = force_malloc(unival_shad_count); + sub->shaders = shaders; + if (shaders) { + strcpy_s(vert_buf, sizeof(vert_buf), sub_table->vp); + size_t vert_buf_pos = utf8_length(vert_buf); + vert_buf[vert_buf_pos++] = '.'; + vert_buf[vert_buf_pos] = 0; + memset(&vert_buf[vert_buf_pos], '0', num_uniform); + vert_buf[vert_buf_pos + num_uniform] = 0; + strcat_s(vert_buf, sizeof(vert_buf), ".vert"); + + strcpy_s(frag_buf, sizeof(frag_buf), sub_table->fp); + size_t frag_buf_pos = utf8_length(frag_buf); + frag_buf[frag_buf_pos++] = '.'; + frag_buf[frag_buf_pos] = 0; + memset(&frag_buf[frag_buf_pos], '0', num_uniform); + frag_buf[frag_buf_pos + num_uniform] = 0; + strcat_s(frag_buf, sizeof(frag_buf), ".frag"); + + for (size_t k = 0; k < unival_shad_count; k++) { + for (size_t l = 0, m = k; l < num_uniform; l++) { + size_t unival_max = (size_t)(shader->use_permut[l] + ? max_def(vp_unival_max[l], fp_unival_max[l]) : 0) + 1; + vec_vert_data[l] = (uint32_t)(min_def(m % unival_max, vp_unival_max[l])); + m /= unival_max; + vert_buf[vert_buf_pos + l] = (char)('0' + vec_vert_data[l]); + } + + for (size_t l = 0, m = k; l < num_uniform; l++) { + size_t unival_max = (size_t)(shader->use_permut[l] + ? max_def(vp_unival_max[l], fp_unival_max[l]) : 0) + 1; + vec_frag_data[l] = (uint32_t)(min_def(m % unival_max, fp_unival_max[l])); + m /= unival_max; + frag_buf[frag_buf_pos + l] = (char)('0' + vec_frag_data[l]); + } + + if (!bin || !shader_load_binary_shader(bin, &shaders[k].program)) { + bool vert_succ = shader_glsl::parse_define(vert_data, num_uniform, + vec_vert_data, &temp_vert, &temp_vert_size); + bool frag_succ = shader_glsl::parse_define(frag_data, num_uniform, + vec_frag_data, &temp_frag, &temp_frag_size); + + if (ignore_cache) + shaders[k].program = shader_compile(vert_succ ? temp_vert : 0, + frag_succ ? temp_frag : 0, vert_buf, frag_buf); + else { + program_data_binary.push_back({}); + shaders[k].program = shader_compile_binary(vert_succ ? temp_vert : 0, + frag_succ ? temp_frag : 0, vert_buf, frag_buf, + &program_data_binary.back(), &buffer_size, &binary); + } + shader_cache_changed |= shaders[k].program ? true : false; + } + else { + program_data_binary.push_back({}); + program_binary* b = &program_data_binary.back(); + b->length = bin->length; + b->binary_format = bin->binary_format; + b->binary = (size_t)force_malloc(bin->length); + memcpy((void*)b->binary, (void*)((size_t)bin + bin->binary), bin->length); + } + + if (!ignore_cache && bin) + bin++; + } + } + } + else { + program_data_binary.reserve(1); + shader_glsl_sub_shader* shaders = force_malloc(); + sub->shaders = shaders; + if (shaders) { + strcpy_s(vert_buf, sizeof(vert_buf), sub_table->vp); + strcpy_s(frag_buf, sizeof(vert_buf), sub_table->fp); + strcat_s(vert_buf, sizeof(vert_buf), "..vert"); + strcat_s(frag_buf, sizeof(vert_buf), "..frag"); + + if (!bin || !shader_load_binary_shader(bin, &shaders[0].program)) { + bool vert_succ = shader_glsl::parse_define(vert_data, &temp_vert, &temp_vert_size); + bool frag_succ = shader_glsl::parse_define(frag_data, &temp_frag, &temp_frag_size); + + if (ignore_cache) + shaders[0].program = shader_compile(vert_succ ? temp_vert : 0, + frag_succ ? temp_frag : 0, vert_buf, frag_buf); + else { + program_data_binary.push_back({}); + shaders[0].program = shader_compile_binary(vert_succ ? temp_vert : 0, + frag_succ ? temp_frag : 0, vert_buf, frag_buf, + &program_data_binary.back(), &buffer_size, &binary); + } + shader_cache_changed |= shaders[0].program ? true : false; + } + else { + program_data_binary.push_back({}); + program_binary* b = &program_data_binary.back(); + b->length = bin->length; + b->binary_format = bin->binary_format; + b->binary = (size_t)force_malloc(bin->length); + memcpy((void*)b->binary, (void*)((size_t)bin + bin->binary), bin->length); + } + + if (!ignore_cache && bin) + bin++; + } + } + + if (!ignore_cache) { + if (!shader_cache_file) + shader_cache_file = shader_cache_farc.add_file(shader_cache_file_name); + else + free_def(shader_cache_file->data); + + size_t bin_count = program_data_binary.size(); + size_t bin_size = sizeof(uint64_t) * 2 + bin_count * sizeof(program_binary); + for (program_binary& k : program_data_binary) + bin_size += align_val(k.length, 0x04); + shader_cache_file->data = force_malloc(bin_size); + shader_cache_file->size = bin_size; + shader_cache_file->data_changed = true; + + ((uint64_t*)shader_cache_file->data)[0] = vert_data_hash; + ((uint64_t*)shader_cache_file->data)[1] = frag_data_hash; + bin = (program_binary*)&((uint64_t*)shader_cache_file->data)[2]; + size_t bin_data_base = (size_t)shader_cache_file->data + sizeof(uint64_t) * 2; + size_t bin_data = bin_data_base + bin_count * sizeof(program_binary); + for (program_binary& k : program_data_binary) { + bin->length = k.length; + bin->binary_format = k.binary_format; + bin->binary = bin_data - bin_data_base; + memcpy((void*)bin_data, (void*)k.binary, k.length); + bin_data_base += sizeof(program_binary); + bin_data += align_val(k.length, 0x04); + void* binary = (void*)k.binary; + free_def(binary); + k.binary = 0; + bin++; + } + } + + free_def(vert_data); + free_def(frag_data); + program_data_binary.clear(); + } + vec_vert.clear(); + vec_frag.clear(); + + for (size_t j = 0; j < bind_func_table_size; j++) + if (shader->name_index == bind_func_table[j].name_index) { + shader->bind_func = bind_func_table[j].bind_func; + break; + } + } + free_def(binary); + free_def(temp_vert); + free_def(temp_frag); + + if (shader_cache_changed) + shader_cache_farc.write(temp_buf, FARC_FArC, FARC_NONE, false); + + this->get_index_by_name_func = get_index_by_name; +} + +void shader_glsl_set_data::set(uint32_t index) { + if (this && index && index != -1) { + shader_glsl* shader = &shaders[index]; + if (shader->bind_func) + shader->bind_func(this, shader); + else + shader->bind(this, shader->sub[0].sub_index); + } + else + shader_glsl::unbind(); +} + +void shader_glsl_set_data::unload() { + size_t size = this->size; + shader_glsl* shaders = this->shaders; + for (size_t i = 0; i < size; i++) { + shader_glsl* shader = &shaders[i]; + if (!shader->sub) + continue; + + int32_t num_sub = shader->num_sub; + shader_glsl_sub* sub = shader->sub; + for (size_t j = 0; j < num_sub; j++, sub++) { + int32_t unival_shad_count = 1; + if (shader->num_uniform > 0) { + int32_t num_uniform = shader->num_uniform; + int32_t unival_shad_curr = 1; + const int32_t* vp_unival_max = sub->vp_unival_max; + const int32_t* fp_unival_max = sub->fp_unival_max; + for (size_t k = 0; k < num_uniform; k++) { + const int32_t unival_max = shader->use_permut[k] + ? max_def(vp_unival_max[k], fp_unival_max[k]) : 0; + unival_shad_count += unival_shad_curr * unival_max; + unival_shad_curr *= unival_max + 1; + } + } + + if (sub->shaders) { + shader_glsl_sub_shader* shaders = sub->shaders; + for (size_t k = 0; k < unival_shad_count; k++) + glDeleteProgram(shaders[k].program); + free(shaders); + sub->shaders = 0; + } + } + free(shader->sub); + shader->sub = 0; + } + free_def(shaders); + this->shaders = 0; + + get_index_by_name_func = 0; +} + +static GLuint shader_compile_shader(GLenum type, const char* data, const char* file) { + if (!data) + return 0; + + GLuint shader = glCreateShader(type); + glShaderSource(shader, 1, &data, 0); + glCompileShader(shader); + + GLint success = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + GLchar* info_log = force_malloc(0x10000); + glGetShaderInfoLog(shader, 0x10000, 0, info_log); + const char* type_str = "Unknown"; + switch (type) { + case GL_FRAGMENT_SHADER: + type_str = "Fragment"; + break; + case GL_VERTEX_SHADER: + type_str = "Vertex"; + break; + } + printf_debug("%s shader compile error:\nfile: %s\n%s\n", type_str, file, info_log); + free_def(info_log); + glDeleteShader(shader); + +#if defined(CRE_DEV) + wchar_t temp_buf[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPathW(0, CSIDL_LOCAL_APPDATA, 0, 0, temp_buf))) { + wcscat_s(temp_buf, sizeof(temp_buf) / sizeof(wchar_t), L"\\ReDIVA"); + temp_buf[sizeof(temp_buf) / sizeof(wchar_t) - 1] = 0; + CreateDirectoryW(temp_buf, 0); + + wchar_t buf[MAX_PATH]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error", temp_buf); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + CreateDirectoryW(buf, 0); + + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error\\%hs", temp_buf, file); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + + file_stream s; + s.open(buf, L"wb"); + s.write(data, utf8_length(data)); + } +#endif + return 0; + } + return shader; +} + +static GLuint shader_compile(const char* vert, const char* frag, const char* vp, const char* fp) { + GLuint vert_shad = shader_compile_shader(GL_VERTEX_SHADER, vert, vp); + GLuint frag_shad = shader_compile_shader(GL_FRAGMENT_SHADER, frag, fp); + + GLuint program = glCreateProgram(); + if (vert_shad) + glAttachShader(program, vert_shad); + if (frag_shad) + glAttachShader(program, frag_shad); + glLinkProgram(program); + + if (vert_shad) + glDeleteShader(vert_shad); + if (frag_shad) + glDeleteShader(frag_shad); + + GLint success = 0; + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + GLchar* info_log = force_malloc(0x10000); + glGetProgramInfoLog(program, 0x10000, 0, info_log); + printf_debug("Program Shader Permut linking error:\nvp: %s; fp: %s\n%s\n", vp, fp, info_log); + free_def(info_log); + glDeleteProgram(program); + +#if defined(CRE_DEV) + wchar_t temp_buf[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPathW(0, CSIDL_LOCAL_APPDATA, 0, 0, temp_buf))) { + wcscat_s(temp_buf, sizeof(temp_buf) / sizeof(wchar_t), L"\\ReDIVA"); + temp_buf[sizeof(temp_buf) / sizeof(wchar_t) - 1] = 0; + CreateDirectoryW(temp_buf, 0); + + wchar_t buf[MAX_PATH]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error", temp_buf); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + CreateDirectoryW(buf, 0); + + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error\\%hs", temp_buf, vp); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + + file_stream s; + s.open(buf, L"wb"); + s.write(vert, utf8_length(vert)); + s.close(); + + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error\\%hs", temp_buf, fp); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + + s.open(buf, L"wb"); + s.write(frag, utf8_length(frag)); + s.close(); + } +#endif + return 0; + } + else { + gl_state_get_all_gl_errors(); + return program; + } +} + +static GLuint shader_compile_binary(const char* vert, const char* frag, const char* vp, const char* fp, + program_binary* bin, GLsizei* buffer_size, void** binary) { + memset(bin, 0, sizeof(*bin)); + + GLuint vert_shad = shader_compile_shader(GL_VERTEX_SHADER, vert, vp); + GLuint frag_shad = shader_compile_shader(GL_FRAGMENT_SHADER, frag, fp); + + GLuint program = glCreateProgram(); + if (vert_shad) + glAttachShader(program, vert_shad); + if (frag_shad) + glAttachShader(program, frag_shad); + glLinkProgram(program); + + if (vert_shad) + glDeleteShader(vert_shad); + if (frag_shad) + glDeleteShader(frag_shad); + + GLint success = 0; + glGetProgramiv(program, GL_LINK_STATUS, &success); + if (!success) { + GLchar* info_log = force_malloc(0x10000); + glGetProgramInfoLog(program, 0x10000, 0, info_log); + printf_debug("Program Shader Permut linking error:\nvp: %s; fp: %s\n%s\n", vp, fp, info_log); + free_def(info_log); + glDeleteProgram(program); + +#if defined(CRE_DEV) + wchar_t temp_buf[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPathW(0, CSIDL_LOCAL_APPDATA, 0, 0, temp_buf))) { + wcscat_s(temp_buf, sizeof(temp_buf) / sizeof(wchar_t), L"\\ReDIVA"); + temp_buf[sizeof(temp_buf) / sizeof(wchar_t) - 1] = 0; + CreateDirectoryW(temp_buf, 0); + + wchar_t buf[MAX_PATH]; + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error", temp_buf); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + CreateDirectoryW(buf, 0); + + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error\\%hs", temp_buf, vp); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + + file_stream s; + s.open(buf, L"wb"); + s.write(vert, utf8_length(vert)); + s.close(); + + swprintf_s(buf, sizeof(buf) / sizeof(wchar_t), + L"%ls\\shader_error\\%hs", temp_buf, fp); + buf[sizeof(buf) / sizeof(wchar_t) - 1] = 0; + + s.open(buf, L"wb"); + s.write(frag, utf8_length(frag)); + s.close(); + } +#endif + return 0; + } + else { + gl_state_get_all_gl_errors(); + + GLenum binary_format = 0x0; + GLsizei length = 0; + while (*buffer_size < 0x7FFFFFF) { + glGetProgramBinary(program, *buffer_size, &length, &binary_format, *binary); + if (!gl_state_get_error()) + break; + + free_def(*binary); + *buffer_size <<= 1; + *binary = force_malloc(*buffer_size); + } + + bin->length = length; + bin->binary_format = binary_format; + bin->binary = (size_t)force_malloc(length); + if (*binary) + memcpy((void*)bin->binary, *binary, length); + return program; + } +} + +static bool shader_load_binary_shader(program_binary* bin, GLuint* program) { + *program = glCreateProgram(); + glProgramBinary(*program, bin->binary_format, (void*)((size_t)bin + bin->binary), bin->length); + GLint success = 0; + glGetProgramiv(*program, GL_LINK_STATUS, &success); + if (!success) { + glDeleteProgram(*program); + *program = 0; + return false; + } + return true; +} + +static void shader_glsl_update_data(shader_glsl_set_data* set) { + if (!set) + return; + + if (set->curr_shader) { + shader_glsl_sub_shader* shader = set->curr_shader; + if (shader->uniform_val_update) { + glUniform1iv(0, SHADER_MAX_UNIFORM_VALUES, (GLint*)shader->uniform_val); + shader->uniform_val_update = false; + } + } + + if (set->primitive_restart) { + gl_state_enable_primitive_restart(); + gl_state_set_primitive_restart_index(set->primitive_restart_index); + } + else + gl_state_disable_primitive_restart(); +} diff --git a/src/DivaGL/shader_glsl.hpp b/src/DivaGL/shader_glsl.hpp new file mode 100644 index 0000000..b8bc9a0 --- /dev/null +++ b/src/DivaGL/shader_glsl.hpp @@ -0,0 +1,114 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include +#include +#include "../KKdLib/default.hpp" +#include "../KKdLib/farc.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "gl.hpp" +#include "uniform.hpp" + +#define SHADER_MAX_LIGHTS 8 +#define SHADER_MAX_PALETTE_MATRICES 32 +#define SHADER_MAX_PROGRAM_ENV_PARAMETERS 256 +#define SHADER_MAX_PROGRAM_LOCAL_PARAMETERS 64 +#define SHADER_MAX_PROGRAM_BUFFER_PARAMETERS 1024 +#define SHADER_MAX_PROGRAM_MATRICES 8 +#define SHADER_MAX_TEXTURE_COORDS 8 +#define SHADER_MAX_UNIFORM_BLOCK_SIZE 65536 +#define SHADER_MAX_UNIFORM_VALUES 16 + +struct shader_glsl_sub_table { + uint32_t sub_index; + const int32_t* vp_unival_max; + const int32_t* fp_unival_max; + const char* vp; + const char* fp; +}; + +struct shader_glsl_table { + const char* name; + uint32_t name_index; + int32_t num_sub; + const shader_glsl_sub_table* sub; + int32_t num_uniform; + const uniform_name* use_uniform; + const bool* use_permut; +}; + +struct shader_glsl; +struct shader_glsl_set_data; + +typedef int32_t (*PFNSHADERGLSLGETINDEXFUNCPROC)(const char* name); + +typedef void (*PFNSHADERGLSLBINDFUNCPROC)(shader_glsl_set_data* set, shader_glsl* shad); + +struct shader_glsl_bind_func { + uint32_t name_index; + PFNSHADERGLSLBINDFUNCPROC bind_func; +}; + +struct shader_glsl_sub_shader { + GLuint program; + int32_t uniform_val[SHADER_MAX_UNIFORM_VALUES]; + bool uniform_val_update; +}; + +struct shader_glsl_sub { + uint32_t sub_index; + const int32_t* vp_unival_max; + const int32_t* fp_unival_max; + shader_glsl_sub_shader* shaders; +}; + +struct shader_glsl { + const char* name; + uint32_t name_index; + int32_t num_sub; + shader_glsl_sub* sub; + int32_t num_uniform; + const uniform_name* use_uniform; + const bool* use_permut; + PFNSHADERGLSLBINDFUNCPROC bind_func; + + int32_t bind(shader_glsl_set_data* set, uint32_t sub_index); + + static bool parse_define(const char* data, char** temp, size_t* temp_size); + static bool parse_define(const char* data, int32_t num_uniform, + int32_t* uniform_value, char** temp, size_t* temp_size); + static char* parse_include(char* data, farc* f); + static void unbind(); +}; + +struct shader_glsl_set_data { + size_t size; + shader_glsl* shaders; + shader_glsl_sub_shader* curr_shader; + GLboolean primitive_restart; + GLuint primitive_restart_index; + + PFNSHADERGLSLGETINDEXFUNCPROC get_index_by_name_func; + + shader_glsl_set_data(); + + void disable_primitive_restart(); + void draw_arrays(GLenum mode, GLint first, GLsizei count); + void draw_elements(GLenum mode, + GLsizei count, GLenum type, const void* indices); + void draw_range_elements(GLenum mode, + GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices); + void enable_primitive_restart(); + int32_t get_index_by_name(const char* name); + void load(farc* f, bool ignore_cache, const char* name, + const shader_glsl_table* shaders_table, const size_t size, + const shader_glsl_bind_func* bind_func_table, const size_t bind_func_table_size, + PFNSHADERGLSLGETINDEXFUNCPROC get_index_by_name); + void set(uint32_t index); + void unload(); +}; diff --git a/src/DivaGL/shader_glsl_ft.cpp b/src/DivaGL/shader_glsl_ft.cpp new file mode 100644 index 0000000..46b7528 --- /dev/null +++ b/src/DivaGL/shader_glsl_ft.cpp @@ -0,0 +1,3387 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "shader_glsl_ft.hpp" +#include "../KKdLib/str_utils.hpp" +#include "gl_state.hpp" +#include "render_context.hpp" +#include "uniform.hpp" + +enum shader_ft_sub_enum { + SHADER_FT_SUB_SHADER_FFP = 0, + SHADER_FT_SUB_BLINN_VERT, + SHADER_FT_SUB_BLINN_FRAG, + SHADER_FT_SUB_ITEM_BLINN, + SHADER_FT_SUB_STAGE_BLINN, + SHADER_FT_SUB_SKIN_DEFAULT, + SHADER_FT_SUB_SSS_SKIN, + //SHADER_FT_SUB_SSS_FILTER, + SHADER_FT_SUB_SSS_FILTER_MIN, + SHADER_FT_SUB_SSS_FILTER_MIN_NPR, + SHADER_FT_SUB_SSS_FILTER_GAUSS_2D, + SHADER_FT_SUB_HAIR_DEFAULT, + //SHADER_FT_SUB_HAIR_ANISO, + SHADER_FT_SUB_HAIR_NPR1, + SHADER_FT_SUB_CLOTH_DEFAULT, + SHADER_FT_SUB_CLOTH_ANISO, + SHADER_FT_SUB_CLOTH_NPR1, + SHADER_FT_SUB_TIGHTS, + SHADER_FT_SUB_SKY_DEFAULT, + //SHADER_FT_SUB_EYE_BALL, + //SHADER_FT_SUB_EYE_LENS, + SHADER_FT_SUB_GLASS_EYE, + //SHADER_FT_SUB_MEMBRANE, + //SHADER_FT_SUB_SHADOWMAP, + //SHADER_FT_SUB_ESM, + SHADER_FT_SUB_ESM_GAUSS, + //SHADER_FT_SUB_ESM_FILTER, + SHADER_FT_SUB_ESM_FILTER_MIN, + SHADER_FT_SUB_ESM_FILTER_EROSION, + SHADER_FT_SUB_LIT_PROJ, + SHADER_FT_SUB_SIMPLE, + SHADER_FT_SUB_SILHOUETTE, + SHADER_FT_SUB_LAMBERT, + SHADER_FT_SUB_CONSTANT, + //SHADER_FT_SUB_PEEL, + SHADER_FT_SUB_TONEMAP, + SHADER_FT_SUB_TONEMAP_NPR1, + //SHADER_FT_SUB_REDUCE_TEX, + SHADER_FT_SUB_GHOST, + SHADER_FT_SUB_REDUCE_TEX_REDUCE_2, + SHADER_FT_SUB_REDUCE_TEX_REDUCE_2_ALPHAMASK, + SHADER_FT_SUB_REDUCE_TEX_REDUCE_4, + SHADER_FT_SUB_REDUCE_TEX_REDUCE_4_EXTRACT, + SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_2, + SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_BLUR, + SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_4, + //SHADER_FT_SUB_MAGNIFY, + SHADER_FT_SUB_MAGNIFY_CONE, + SHADER_FT_SUB_MAGNIFY_CONE2, + SHADER_FT_SUB_MAGNIFY_DIFF, + SHADER_FT_SUB_MAGNIFY_DIFF2, + SHADER_FT_SUB_MAGNIFY_LINEAR, + //SHADER_FT_SUB_MLAA, + SHADER_FT_SUB_MLAA_EDGE, + SHADER_FT_SUB_MLAA_AREA, + SHADER_FT_SUB_MLAA_BLEND, + SHADER_FT_SUB_CONTOUR, + SHADER_FT_SUB_CONTOUR_NPR, + //SHADER_FT_SUB_EXPOSURE, + SHADER_FT_SUB_EXPOSURE_MINIFY, + SHADER_FT_SUB_EXPOSURE_MEASURE, + SHADER_FT_SUB_EXPOSURE_AVERAGE, + //SHADER_FT_SUB_PP_GAUSS, + SHADER_FT_SUB_PP_GAUSS_USUAL, + SHADER_FT_SUB_PP_GAUSS_CONE, + SHADER_FT_SUB_SUN, + SHADER_FT_SUB_SUN_NO_TEXTURED, + //SHADER_FT_SUB_FADE, + SHADER_FT_SUB_WATER01, + //SHADER_FT_SUB_WATER02, + //SHADER_FT_SUB_WATER_RING, + SHADER_FT_SUB_WATER_PARTICLE, + //SHADER_FT_SUB_SNOW_PARTICLE, + SHADER_FT_SUB_SNOW_PARTICLE, + SHADER_FT_SUB_SNOW_PARTICLE_CPU, + SHADER_FT_SUB_LEAF_PARTICLE, + SHADER_FT_SUB_STAR, + SHADER_FT_SUB_STAR_MILKY_WAY, + //SHADER_FT_SUB_SNOW_RING, + //SHADER_FT_SUB_SNOW_FOOTPRINT, + //SHADER_FT_SUB_SNOW_TEX_SPACE_LIGHT, + //SHADER_FT_SUB_SNOW_CALC_NORMAL, + SHADER_FT_SUB_FLOOR, + SHADER_FT_SUB_PUDDLE, + SHADER_FT_SUB_SIMPLE_REFLECT, + SHADER_FT_SUB_SIMPLE_REFRACT, + SHADER_FT_SUB_RIPPLE_EMIT, + SHADER_FT_SUB_RAIN, + //SHADER_FT_SUB_VOLUME_LIGHT, + //SHADER_FT_SUB_FENCE_ALPHA, + SHADER_FT_SUB_RIPPLE, + SHADER_FT_SUB_FOG_PTCL, + SHADER_FT_SUB_PARTICLE, + SHADER_FT_SUB_GLITTER_PARTICLE, + //SHADER_FT_SUB_SHOW_VECTOR, + SHADER_FT_SUB_FONT, + SHADER_FT_SUB_MOVIE, + //SHADER_FT_SUB_IMGFILTER, + SHADER_FT_SUB_BOX4, + SHADER_FT_SUB_BOX8, + SHADER_FT_SUB_COPY, + SHADER_FT_SUB_SPRITE, + SHADER_FT_SUB_SHADER_END, +}; + +static const int32_t blinn_vert_vpt_unival_max[] = { + //1, 1, 0, 1, 0, 0, 0, 3, 1, 1, 0, 0, // 11th added + 1, 0, 1, 0, 0, 0, 3, 1, 1, 0, 0, // 0th removed, 11th added +}; + +static const int32_t blinn_vert_fpt_unival_max[] = { + //0, 0, 2, 1, 0, 1, 1, 3, 0, 0, 1, 1, // 11th added + 0, 2, 1, 0, 1, 1, 3, 0, 0, 1, 1, // 0th removed, 11th added +}; + +static const int32_t blinn_frag_vpt_unival_max[] = { + //1, 1, 0, 1, 0, 0, 0, 3, 1, 1, 0, 0, // 11th added + 1, 0, 1, 0, 0, 0, 3, 1, 1, 0, 0, // 0th removed, 11th added +}; + +static const int32_t blinn_frag_fpt_unival_max[] = { + //0, 0, 2, 1, 1, 1, 1, 3, 0, 0, 1, 1, // 11th added + 0, 2, 1, 1, 1, 1, 3, 0, 0, 1, 1, // 0th removed, 11th added +}; + +static const int32_t item_blinn_vpt_unival_max[] = { + //1, 1, 1, 0, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0, + 1, 1, 0, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0, // 0th removed +}; + +static const int32_t item_blinn_fpt_unival_max[] = { + //1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, + 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, // 0th removed +}; + +static const int32_t stage_blinn_vpt_unival_max[] = { + //1, 1, 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, // 11th added + 1, 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, // 0th removed, 11th added +}; + +static const int32_t stage_blinn_fpt_unival_max[] = { + //0, 0, 0, 0, 2, 1, 1, 1, 3, 1, 1, 1, // 11th added + 0, 0, 0, 2, 1, 1, 1, 3, 1, 1, 1, // 0th removed, 11th added +}; + +static const int32_t skin_default_vpt_unival_max[] = { + //1, 1, 1, 0, 2, 0, 1, 0, 0, 0, + 1, 1, 0, 2, 0, 1, 0, 0, 0, // 0th removed +}; + +static const int32_t skin_default_fpt_unival_max[] = { + //1, 0, 1, 1, 0, 1, 0, 1, 1, 1, + 0, 1, 1, 0, 1, 0, 1, 1, 1, // 0th removed +}; + +static const int32_t sss_skin_vpt_unival_max[] = { + //1, 1, 0, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 1, 0, 0, // 0th removed +}; + +static const int32_t sss_skin_fpt_unival_max[] = { + //1, 0, 1, 1, 1, 0, 1, 1, + 0, 1, 1, 1, 0, 1, 1, // 0th removed +}; + +/*static const int32_t sss_filter_vpt_unival_max[] = { + //0, 3, 0, + 3, 0, // 0th removed +}; + +static const int32_t sss_filter_fpt_unival_max[] = { + //1, 3, 1, + 3, 1, // 0th removed +};*/ + +static const int32_t sss_filter_min_vpt_unival_max[] = { + //0, 0, 0, + 0, 0, // 0th removed +}; + +static const int32_t sss_filter_min_fpt_unival_max[] = { + //0, 0, 0, + 0, 0, // 0th removed +}; + +static const int32_t sss_filter_min_npr_vpt_unival_max[] = { + //0, 0, 0, + 0, 0, // 0th removed +}; + +static const int32_t sss_filter_min_npr_fpt_unival_max[] = { + //0, 0, 0, + 0, 0, // 0th removed +}; + +static const int32_t sss_filter_gauss_2d_vpt_unival_max[] = { + //0, 0, 0, + 0, 0, // 0th removed +}; + +static const int32_t sss_filter_gauss_2d_fpt_unival_max[] = { + //1, 0, 0, + 0, 0, // 0th removed +}; + +/*static const int32_t hair_default_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 14th added + 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 0th removed, 14th added +}; + +static const int32_t hair_default_fpt_unival_max[] = { + //1, 0, 2, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, // 14th added + 0, 2, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, // 0th removed, 14th added +}; + +static const int32_t hair_aniso_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 14th added + 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 0th removed, 14th added +}; + +static const int32_t hair_aniso_fpt_unival_max[] = { + //1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, // 14th added + 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, // 0th removed, 14th added +};*/ + +static const int32_t hair_default_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 14th added + 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 0th removed, 14th added +}; + +static const int32_t hair_default_fpt_unival_max[] = { + //1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, // 14th added + 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, // 0th removed, 14th added +}; + +static const int32_t hair_npr1_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 14th added + 1, 0, 0, 1, 0, 0, 3, 0, 2, 1, 0, 0, 0, 0, // 0th removed, 14th added +}; + +static const int32_t hair_npr1_fpt_unival_max[] = { + //1, 0, 0, 0, 0, 1, 0, 3, 1, 0, 0, 0, 0, 0, 1, // 14th added + 0, 0, 0, 0, 1, 0, 3, 1, 0, 0, 0, 0, 0, 1, // 0th removed, 14th added +}; + +static const int32_t cloth_default_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, // 0th removed +}; + +static const int32_t cloth_default_fpt_unival_max[] = { + //1, 0, 2, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, + 0, 2, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, // 0th removed +}; + +static const int32_t cloth_aniso_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, // 0th removed +}; + +static const int32_t cloth_aniso_fpt_unival_max[] = { + //1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 3, 0, 0, 1, 1, + 0, 0, 1, 0, 1, 1, 1, 0, 1, 3, 0, 0, 1, 1, // 0th removed +}; + +static const int32_t cloth_npr1_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, // 0th removed +}; + +static const int32_t cloth_npr1_fpt_unival_max[] = { + //1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, // 0th removed +}; + +static const int32_t tights_vpt_unival_max[] = { + //1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, // 0th removed +}; + +static const int32_t tights_fpt_unival_max[] = { + //1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, + 1, 1, 1, 0, 1, 0, 1, 1, 1, // 0th removed +}; + +static const int32_t sky_default_vpt_unival_max[] = { + 0, 0, 0, 1, 1, 3, 0, // 6th added +}; + +static const int32_t sky_default_fpt_unival_max[] = { + 3, 3, 2, 0, 0, 3, 1, // 6th added +}; + +/*static const int32_t eye_ball_vpt_unival_max[] = { + 1, 0, +}; + +static const int32_t eye_ball_fpt_unival_max[] = { + 0, 1, +};*/ + +/*static const int32_t eye_lens_vpt_unival_max[] = { + 1, 0, 0, +}; + +static const int32_t eye_lens_fpt_unival_max[] = { + 0, 1, 1, +};*/ + +static const int32_t glass_eye_vpt_unival_max[] = { + //1, 1, 0, 2, 0, 1, 0, 0, + 1, 0, 2, 0, 1, 0, 0, // 0th removed +}; + +static const int32_t glass_eye_fpt_unival_max[] = { + //1, 1, 1, 0, 1, 0, 1, 1, + 1, 1, 0, 1, 0, 1, 1, // 0th removed +}; + +/*static const int32_t membrane_vpt_unival_max[] = { + 1, 1, 0, +}; + +static const int32_t membrane_fpt_unival_max[] = { + 0, 1, 3, +};*/ + +/*static const int32_t shadowmap_vpt_unival_max[] = { + 1, 2, 1, 0, 0, +}; + +static const int32_t shadowmap_fpt_unival_max[] = { + 0, 2, 1, 1, 5, +};*/ + +/*static const int32_t esm_vpt_unival_max[] = { + //1, 1, 2, 1, + 1, 2, 1, // 0th removed +}; + +static const int32_t esm_fpt_unival_max[] = { + //0, 0, 2, 1, + 0, 2, 1, // 0th removed +};*/ + +static const int32_t esm_gauss_vpt_unival_max[] = { + 0, +}; + +static const int32_t esm_gauss_fpt_unival_max[] = { + 1, +}; + +/*static const int32_t esm_filter_vpt_unival_max[] = { + 0, +}; + +static const int32_t esm_filter_fpt_unival_max[] = { + 1, +};*/ + +static const int32_t esm_filter_min_vpt_unival_max[] = { + 0, +}; + +static const int32_t esm_filter_min_fpt_unival_max[] = { + 0, +}; + +static const int32_t esm_filter_erosion_vpt_unival_max[] = { + 0, +}; + +static const int32_t esm_filter_erosion_fpt_unival_max[] = { + 0, +}; + +static const int32_t lit_proj_vpt_unival_max[] = { + //1, 1, 0, 1, 0, 0, + 1, 0, 1, 0, 0, // 0th removed +}; + +static const int32_t lit_proj_fpt_unival_max[] = { + //0, 0, 1, 1, 2, 1, + 0, 1, 1, 2, 1, // 0th removed +}; + +static const int32_t simple_vpt_unival_max[] = { + //1, 1, 0, 0, 1, 0, + 1, 0, // 0th removed, 3rd removed, 4th removed, 5th removed +}; + +static const int32_t simple_fpt_unival_max[] = { + //0, 0, 2, 0, 0, 3, + 0, 2, // 0th removed, 3rd removed, 4th removed, 5th removed +}; + +static const int32_t silhouette_vpt_unival_max[] = { + //1, 1, 1, 2, 1, 1, 0, 0, // 7th added + 1, 1, 2, 1, 1, 0, 0, // 0th removed, 7th added +}; + +static const int32_t silhouette_fpt_unival_max[] = { + //0, 0, 1, 0, 0, 0, 1, 1, // 7th added + 0, 1, 0, 0, 0, 1, 1, // 0th removed, 7th added +}; + +static const int32_t lambert_vpt_unival_max[] = { + //1, 1, 0, 1, 3, 1, 1, 0, 0, // 8th added + 1, 0, 1, 3, 1, 1, 0, 0, // 0th removed, 8th added +}; + +static const int32_t lambert_fpt_unival_max[] = { + //0, 0, 2, 1, 3, 0, 0, 1, 1, // 8th added + 0, 2, 1, 3, 0, 0, 1, 1, // 0th removed, 8th added +}; + +static const int32_t constant_vpt_unival_max[] = { + //1, 1, 0, 3, 1, 1, 0, // 6th added + 1, 0, 3, 1, 1, 0, // 0th removed, 6th added +}; + +static const int32_t constant_fpt_unival_max[] = { + //0, 0, 2, 3, 0, 0, 1, // 6th added + 0, 2, 3, 0, 0, 1, // 0th removed, 6th added +}; + +/*static const int32_t peel_vpt_unival_max[] = { + 0, 1, +}; + +static const int32_t peel_fpt_unival_max[] = { + 1, 0, +};*/ + +static const int32_t tone_map_vpt_unival_max[] = { + //0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, // 0th, 7th removed +}; + +static const int32_t tone_map_fpt_unival_max[] = { + //0, 2, 2, 1, 1, 1, 0, 0, + 2, 2, 1, 1, 1, 0, // 0th, 7th removed +}; + +static const int32_t tone_map_npr1_vpt_unival_max[] = { + //0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, // 0th, 7th removed +}; + +static const int32_t tone_map_npr1_fpt_unival_max[] = { + //1, 0, 0, 1, 1, 0, 0, 1, + 0, 0, 1, 1, 0, 0, // 0th, 7th removed +}; + +/*static const int32_t reduce_tex_vpt_unival_max[] = { + 8, 1, +}; + +static const int32_t reduce_tex_fpt_unival_max[] = { + 8, 1, +};*/ + +static const int32_t reduce_tex_reduce_2_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_2_fpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_2_alphamask_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_2_alphamask_fpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_4_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_4_fpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_4_extract_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_4_extract_fpt_unival_max[] = { + 0, 0, +}; + +static const int32_t ghost_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t ghost_fpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_composite_2_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_composite_2_fpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_composite_blur_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_composite_blur_fpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_composite_4_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t reduce_tex_reduce_composite_4_fpt_unival_max[] = { + 0, 0, +}; + +/*static const int32_t magnify_vpt_unival_max[] = { + 7, +}; + +static const int32_t magnify_fpt_unival_max[] = { + 7, +};*/ + +static const int32_t magnify_linear_vpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_linear_fpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_diff_vpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_diff_fpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_diff2_vpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_diff2_fpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_cone_vpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_cone_fpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_cone2_vpt_unival_max[] = { + 0, +}; + +static const int32_t magnify_cone2_fpt_unival_max[] = { + 0, +}; + +/*static const int32_t mlaa_vpt_unival_max[] = { + //0, 0, 2, 0, + 0, 2, 0, // 0th removed +}; + +static const int32_t mlaa_fpt_unival_max[] = { + //1, 1, 2, 2, + 1, 2, 2, // 0th removed +};*/ + +static const int32_t mlaa_edge_vpt_unival_max[] = { + 0, 0, 0, +}; + +static const int32_t mlaa_edge_fpt_unival_max[] = { + 1, 0, 0, +}; + +static const int32_t mlaa_area_vpt_unival_max[] = { + 0, 0, 0, +}; + +static const int32_t mlaa_area_fpt_unival_max[] = { + 0, 0, 2, +}; + +static const int32_t mlaa_blend_vpt_unival_max[] = { + 0, 0, 0, +}; + +static const int32_t mlaa_blend_fpt_unival_max[] = { + 1, 0, 0, +}; + +static const int32_t contour_vpt_unival_max[] = { + //0, 1, + 1, // 0th removed +}; + +static const int32_t contour_fpt_unival_max[] = { + //1, 1, + 1, // 0th removed +}; + +static const int32_t contour_npr_vpt_unival_max[] = { + -1, +}; + +static const int32_t contour_npr_fpt_unival_max[] = { + -1, +}; + +/*static const int32_t exposure_vpt_unival_max[] = { + 2, +}; + +static const int32_t exposure_fpt_unival_max[] = { + 2, +};*/ + +static const int32_t exposure_minify_vpt_unival_max[] = { + 0, +}; + +static const int32_t exposure_minify_fpt_unival_max[] = { + 0, +}; + +static const int32_t exposure_measure_vpt_unival_max[] = { + 0, +}; + +static const int32_t exposure_measure_fpt_unival_max[] = { + 0, +}; + +static const int32_t exposure_average_vpt_unival_max[] = { + 0, +}; + +static const int32_t exposure_average_fpt_unival_max[] = { + 0, +}; + +/*static const int32_t pp_gauss_vpt_unival_max[] = { + 1, +}; + +static const int32_t pp_gauss_fpt_unival_max[] = { + 1, +};*/ + +static const int32_t pp_gauss_usual_vpt_unival_max[] = { + 0, +}; + +static const int32_t pp_gauss_usual_fpt_unival_max[] = { + 0, +}; + +static const int32_t pp_gauss_cone_vpt_unival_max[] = { + 0, +}; + +static const int32_t pp_gauss_cone_fpt_unival_max[] = { + 0, +}; + +static const int32_t sun_vpt_unival_max[] = { + -1, +}; + +static const int32_t sun_fpt_unival_max[] = { + -1, +}; + +static const int32_t sun_no_textured_vpt_unival_max[] = { + -1, +}; + +static const int32_t sun_no_textured_fpt_unival_max[] = { + -1, +}; + +/*static const int32_t fade_vpt_unival_max[] = { + 5, +}; + +static const int32_t fade_fpt_unival_max[] = { + 5, +};*/ + +static const int32_t water01_vpt_unival_max[] = { + 1, 1, 0, 0, 0, 0, 0, 1, +}; + +static const int32_t water01_fpt_unival_max[] = { + 0, 0, 2, 1, 1, 1, 1, 1, +}; + +/*static const int32_t water02_vpt_unival_max[] = { + -1, +}; + +static const int32_t water02_fpt_unival_max[] = { + -1, +};*/ + +/*static const int32_t water_ring_vpt_unival_max[] = { + 1, 0, +}; + +static const int32_t water_ring_fpt_unival_max[] = { + 1, 1, +};*/ + +static const int32_t water_particle_vpt_unival_max[] = { + -1, +}; + +static const int32_t water_particle_fpt_unival_max[] = { + -1, +}; + +/*static const int32_t snow_particle_vpt_unival_max[] = { + 1, +}; + +static const int32_t snow_particle_fpt_unival_max[] = { + 1, +};*/ + +static const int32_t snow_particle_vpt_unival_max[] = { + 0, +}; + +static const int32_t snow_particle_fpt_unival_max[] = { + 0, +}; + +static const int32_t snow_particle_cpu_vpt_unival_max[] = { + 0, +}; + +static const int32_t snow_particle_cpu_fpt_unival_max[] = { + 0, +}; + +static const int32_t leaf_particle_vpt_unival_max[] = { + -1, +}; + +static const int32_t leaf_particle_fpt_unival_max[] = { + -1, +}; + +/*static const int32_t star_vpt_unival_max[] = { + 1, +}; + +static const int32_t star_fpt_unival_max[] = { + 1, +};*/ + +static const int32_t star_vpt_unival_max[] = { + 0, +}; + +static const int32_t star_fpt_unival_max[] = { + 0, +}; + +static const int32_t star_milky_way_vpt_unival_max[] = { + 0, +}; + +static const int32_t star_milky_way_fpt_unival_max[] = { + 0, +}; + +static const int32_t snow_ring_vpt_unival_max[] = { + 0, 0, 0, 1, 0, +}; + +static const int32_t snow_ring_fpt_unival_max[] = { + 2, 1, 1, 1, 1, +}; + +static const int32_t snow_footprint_vpt_unival_max[] = { + -1, +}; + +static const int32_t snow_footprint_fpt_unival_max[] = { + -1, +}; + +static const int32_t snow_tex_space_light_vpt_unival_max[] = { + -1, +}; + +static const int32_t snow_tex_space_light_fpt_unival_max[] = { + -1, +}; + +static const int32_t snow_calc_normal_vpt_unival_max[] = { + -1, +}; + +static const int32_t snow_calc_normal_fpt_unival_max[] = { + -1, +}; + +static const int32_t floor_vpt_unival_max[] = { + 0, 0, 1, 0, 3, 1, 1, 0, +}; + +static const int32_t floor_fpt_unival_max[] = { + 2, 1, 1, 1, 3, 0, 0, 1, // 7th added +}; + +static const int32_t puddle_vpt_unival_max[] = { + 0, 1, 0, 3, +}; + +static const int32_t puddle_fpt_unival_max[] = { + 1, 1, 1, 3, +}; + +static const int32_t simple_reflect_vpt_unival_max[] = { + //1, 1, 2, 1, 1, 0, 0, 0, 0, 0, + 1, 2, 1, 1, 0, 0, 0, 0, 0, // 0th removed +}; + +static const int32_t simple_reflect_fpt_unival_max[] = { + //0, 0, 2, 0, 0, 1, 1, 2, 1, 1, + 0, 2, 0, 0, 1, 1, 2, 1, 1, // 0th removed +}; + +static const int32_t simple_refract_vpt_unival_max[] = { + 1, 0, +}; + +static const int32_t simple_refract_fpt_unival_max[] = { + 0, 1, +}; + +static const int32_t ripple_emit_vpt_unival_max[] = { + 0, 0, +}; + +static const int32_t ripple_emit_fpt_unival_max[] = { + 1, 1, +}; + +static const int32_t rain_vpt_unival_max[] = { + -1, +}; + +static const int32_t rain_fpt_unival_max[] = { + -1, +}; + +/*static const int32_t volume_light_vpt_unival_max[] = { + -1, +}; + +static const int32_t volume_light_fpt_unival_max[] = { + -1, +};*/ + +/*static const int32_t fence_alpha_vpt_unival_max[] = { + 1, 3, +}; + +static const int32_t fence_alpha_fpt_unival_max[] = { + 0, 3, +};*/ + +static const int32_t ripple_vpt_unival_max[] = { + 0, +}; + +static const int32_t ripple_fpt_unival_max[] = { + 1, +}; + +static const int32_t fog_ptcl_vpt_unival_max[] = { + -1, +}; + +static const int32_t fog_ptcl_fpt_unival_max[] = { + -1, +}; + +static const int32_t particle_vpt_unival_max[] = { + -1, +}; + +static const int32_t particle_fpt_unival_max[] = { + -1, +}; + +static const int32_t glitter_particle_vpt_unival_max[] = { + 2, 0, 3, 0, +}; + +static const int32_t glitter_particle_fpt_unival_max[] = { + 2, 3, 3, 3, +}; + +/*static const int32_t show_vector_vpt_unival_max[] = { + //1, 1, 3, + 1, 3, // 0th removed +}; + +static const int32_t show_vector_fpt_unival_max[] = { + //0, 0, 0, + 0, 0, // 0th removed +};*/ + +static const int32_t font_vpt_unival_max[] = { + //0, + -1, // 0th removed, 1st added +}; + +static const int32_t font_fpt_unival_max[] = { + //1, + -1, // 0th removed, 1st added +}; + +static const int32_t movie_vpt_unival_max[] = { + 0, +}; + +static const int32_t movie_fpt_unival_max[] = { + 1, +}; + +/*static const int32_t imgfilter_vpt_unival_max[] = { + 0, +}; + +static const int32_t imgfilter_fpt_unival_max[] = { + 5, +};*/ + +static const int32_t box4_vpt_unival_max[] = { + 0, +}; + +static const int32_t box4_fpt_unival_max[] = { + 0, +}; + +static const int32_t box8_vpt_unival_max[] = { + 0, +}; + +static const int32_t box8_fpt_unival_max[] = { + 0, +}; + +static const int32_t copy_vpt_unival_max[] = { + 0, +}; + +static const int32_t copy_fpt_unival_max[] = { + 0, +}; +static const int32_t sprite_vpt_unival_max[] = { + 0, 0, 0, +}; + +static const int32_t sprite_fpt_unival_max[] = { + 3, 3, 2, +}; + +static const shader_glsl_sub_table BLINN_table[] = { + { + SHADER_FT_SUB_BLINN_VERT, + blinn_vert_vpt_unival_max, + blinn_vert_fpt_unival_max, + "blinn_per_vert", + "blinn_per_vert", + }, + { + SHADER_FT_SUB_BLINN_FRAG, + blinn_frag_vpt_unival_max, + blinn_frag_fpt_unival_max, + "blinn_per_frag", + "blinn_per_frag", + }, +}; + +static const shader_glsl_sub_table ITEM_table[] = { + { + SHADER_FT_SUB_ITEM_BLINN, + item_blinn_vpt_unival_max, + item_blinn_fpt_unival_max, + "item_blinn", + "item_blinn", + }, +}; + +static const shader_glsl_sub_table STAGE_table[] = { + { + SHADER_FT_SUB_STAGE_BLINN, + stage_blinn_vpt_unival_max, + stage_blinn_fpt_unival_max, + "stage_blinn", + "stage_blinn", + }, +}; + +static const shader_glsl_sub_table SKIN_table[] = { + { + SHADER_FT_SUB_SKIN_DEFAULT, + skin_default_vpt_unival_max, + skin_default_fpt_unival_max, + "skin_default", + "skin_default", + }, +}; + +static const shader_glsl_sub_table SSS_SKIN_table[] = { + { + SHADER_FT_SUB_SSS_SKIN, + sss_skin_vpt_unival_max, + sss_skin_fpt_unival_max, + "sss_skin", + "sss_skin", + }, +}; + +/*static const shader_glsl_sub_table SSS_FILT_table[] = { + { + SHADER_FT_SUB_SSS_FILTER, + sss_filter_vpt_unival_max, + sss_filter_fpt_unival_max, + "sss_filter", + "sss_filter", + }, +};*/ + +static const shader_glsl_sub_table SSS_FILT_table[] = { + { + SHADER_FT_SUB_SSS_FILTER_MIN, + sss_filter_min_vpt_unival_max, + sss_filter_min_fpt_unival_max, + "sss_filter_min", + "sss_filter_min", + }, + { + SHADER_FT_SUB_SSS_FILTER_MIN_NPR, + sss_filter_min_npr_vpt_unival_max, + sss_filter_min_npr_fpt_unival_max, + "sss_filter_min", + "sss_filter_min_npr", + }, + { + SHADER_FT_SUB_SSS_FILTER_GAUSS_2D, + sss_filter_gauss_2d_vpt_unival_max, + sss_filter_gauss_2d_fpt_unival_max, + "sss_filter_gauss_2d", + "sss_filter_gauss_2d", + }, +}; + +/*static const shader_glsl_sub_table HAIR_table[] = { + { + SHADER_FT_SUB_HAIR_DEFAULT, + hair_default_vpt_unival_max, + hair_default_fpt_unival_max, + "hair_default", + "hair_default", + }, + { + SHADER_FT_SUB_HAIR_ANISO, + hair_aniso_vpt_unival_max, + hair_aniso_fpt_unival_max, + "hair_default", + "hair_aniso", + }, + { + SHADER_FT_SUB_HAIR_NPR1, + hair_npr1_vpt_unival_max, + hair_npr1_fpt_unival_max, + "hair_default", + "hair_npr1", + }, +};*/ + +static const shader_glsl_sub_table HAIR_table[] = { + { + SHADER_FT_SUB_HAIR_DEFAULT, + hair_default_vpt_unival_max, + hair_default_fpt_unival_max, + "hair_default", + "hair_default", + }, + { + SHADER_FT_SUB_HAIR_NPR1, + hair_npr1_vpt_unival_max, + hair_npr1_fpt_unival_max, + "hair_default", + "hair_npr1", + }, +}; + +static const shader_glsl_sub_table CLOTH_table[] = { + { + SHADER_FT_SUB_CLOTH_DEFAULT, + cloth_default_vpt_unival_max, + cloth_default_fpt_unival_max, + "cloth_default", + "cloth_default", + }, + { + SHADER_FT_SUB_CLOTH_ANISO, + cloth_aniso_vpt_unival_max, + cloth_aniso_fpt_unival_max, + "cloth_default", + "cloth_aniso", + }, + { + SHADER_FT_SUB_CLOTH_NPR1, + cloth_npr1_vpt_unival_max, + cloth_npr1_fpt_unival_max, + "cloth_default", + "cloth_npr1", + }, +}; + +static const shader_glsl_sub_table TIGHTS_table[] = { + { + SHADER_FT_SUB_TIGHTS, + tights_vpt_unival_max, + tights_fpt_unival_max, + "tights", + "tights", + }, +}; + +static const shader_glsl_sub_table SKY_table[] = { + { + SHADER_FT_SUB_SKY_DEFAULT, + sky_default_vpt_unival_max, + sky_default_fpt_unival_max, + "sky_default", + "sky_default", + }, +}; + +/*static const shader_glsl_sub_table EYEBALL_table[] = { + { + SHADER_FT_SUB_EYE_BALL, + eye_ball_vpt_unival_max, + eye_ball_fpt_unival_max, + "eye_ball", + "eye_ball", + }, +};*/ + +/*static const shader_glsl_sub_table EYELENS_table[] = { + { + SHADER_FT_SUB_EYE_LENS, + eye_lens_vpt_unival_max, + eye_lens_fpt_unival_max, + "eye_lens", + "eye_lens", + }, +};*/ + +static const shader_glsl_sub_table GLASEYE_table[] = { + { + SHADER_FT_SUB_GLASS_EYE, + glass_eye_vpt_unival_max, + glass_eye_fpt_unival_max, + "glass_eye", + "glass_eye", + }, +}; + +/*static const shader_glsl_sub_table MEMBRAN_table[] = { + { + SHADER_FT_SUB_MEMBRANE, + membrane_vpt_unival_max, + membrane_fpt_unival_max, + "membrane", + "membrane", + }, +};*/ + +/*static const shader_glsl_sub_table SHDMAP_table[] = { + { + SHADER_FT_SUB_SHADOWMAP, + shadowmap_vpt_unival_max, + shadowmap_fpt_unival_max, + "shadowmap", + "shadowmap", + }, +};*/ + +/*static const shader_glsl_sub_table ESM_table[] = { + { + SHADER_FT_SUB_ESM, + esm_vpt_unival_max, + esm_fpt_unival_max, + "esm", + "esm", + }, +};*/ + +static const shader_glsl_sub_table ESMGAUSS_table[] = { + { + SHADER_FT_SUB_ESM_GAUSS, + esm_gauss_vpt_unival_max, + esm_gauss_fpt_unival_max, + "esm_gauss", + "esm_gauss", + }, +}; + +/*static const shader_glsl_sub_table ESMFILT_table[] = { + { + SHADER_FT_SUB_ESM_FILTER, + esm_filter_vpt_unival_max, + esm_filter_fpt_unival_max, + "esm_filter", + "esm_filter", + }, +};*/ + +static const shader_glsl_sub_table ESMFILT_table[] = { + { + SHADER_FT_SUB_ESM_FILTER_MIN, + esm_filter_min_vpt_unival_max, + esm_filter_min_fpt_unival_max, + "esm_filter_min", + "esm_filter_min", + }, + { + SHADER_FT_SUB_ESM_FILTER_EROSION, + esm_filter_erosion_vpt_unival_max, + esm_filter_erosion_fpt_unival_max, + "esm_filter_erosion", + "esm_filter_erosion", + }, +}; + +static const shader_glsl_sub_table LITPROJ_table[] = { + { + SHADER_FT_SUB_LIT_PROJ, + lit_proj_vpt_unival_max, + lit_proj_fpt_unival_max, + "lit_proj", + "lit_proj", + }, +}; + +static const shader_glsl_sub_table SIMPLE_table[] = { + { + SHADER_FT_SUB_SIMPLE, + simple_vpt_unival_max, + simple_fpt_unival_max, + "simple", + "simple", + }, +}; + +static const shader_glsl_sub_table SIL_table[] = { + { + SHADER_FT_SUB_SILHOUETTE, + silhouette_vpt_unival_max, + silhouette_fpt_unival_max, + "silhouette", + "silhouette", + }, +}; + +static const shader_glsl_sub_table LAMBERT_table[] = { + { + SHADER_FT_SUB_LAMBERT, + lambert_vpt_unival_max, + lambert_fpt_unival_max, + "lambert", + "lambert", + }, +}; + +static const shader_glsl_sub_table CONSTANT_table[] = { + { + SHADER_FT_SUB_CONSTANT, + constant_vpt_unival_max, + constant_fpt_unival_max, + "constant", + "constant", + }, +}; + +/*static const shader_glsl_sub_table PEEL_table[] = { + { + SHADER_FT_SUB_PEEL, + peel_vpt_unival_max, + peel_fpt_unival_max, + "depth_peel", + "depth_peel", + }, +};*/ + +static const shader_glsl_sub_table TONEMAP_table[] = { + { + SHADER_FT_SUB_TONEMAP, + tone_map_vpt_unival_max, + tone_map_fpt_unival_max, + "tone_map", + "tone_map", + }, + { + SHADER_FT_SUB_TONEMAP_NPR1, + tone_map_npr1_vpt_unival_max, + tone_map_npr1_fpt_unival_max, + "tone_map_npr1", + "tone_map_npr1", + }, +}; + +/*static const shader_glsl_sub_table REDUCE_table[] = { + { + SHADER_FT_SUB_REDUCE_TEX, + reduce_tex_vpt_unival_max, + reduce_tex_fpt_unival_max, + "reduce_tex", + "reduce_tex", + }, +};*/ + +static const shader_glsl_sub_table REDUCE_table[] = { + { + SHADER_FT_SUB_REDUCE_TEX_REDUCE_2, + reduce_tex_reduce_2_vpt_unival_max, + reduce_tex_reduce_2_fpt_unival_max, + "reduce_tex_reduce_2", + "reduce_tex_reduce_2", + }, + { + SHADER_FT_SUB_REDUCE_TEX_REDUCE_2_ALPHAMASK, + reduce_tex_reduce_2_alphamask_vpt_unival_max, + reduce_tex_reduce_2_alphamask_fpt_unival_max, + "reduce_tex_reduce_2_alphamask", + "reduce_tex_reduce_2_alphamask", + }, + { + SHADER_FT_SUB_REDUCE_TEX_REDUCE_4, + reduce_tex_reduce_4_vpt_unival_max, + reduce_tex_reduce_4_fpt_unival_max, + "reduce_tex_reduce_4", + "reduce_tex_reduce_4", + }, + { + SHADER_FT_SUB_REDUCE_TEX_REDUCE_4_EXTRACT, + reduce_tex_reduce_4_extract_vpt_unival_max, + reduce_tex_reduce_4_extract_fpt_unival_max, + "reduce_tex_reduce_4_extract", + "reduce_tex_reduce_4_extract", + }, + { + SHADER_FT_SUB_GHOST, + ghost_vpt_unival_max, + ghost_fpt_unival_max, + "ghost", + "ghost", + }, + { + SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_2, + reduce_tex_reduce_composite_2_vpt_unival_max, + reduce_tex_reduce_composite_2_fpt_unival_max, + "reduce_tex_reduce_composite_2", + "reduce_tex_reduce_composite_2", + }, + { + SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_BLUR, + reduce_tex_reduce_composite_blur_vpt_unival_max, + reduce_tex_reduce_composite_blur_fpt_unival_max, + "reduce_tex_reduce_composite_blur", + "reduce_tex_reduce_composite_blur", + }, + { + SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_4, + reduce_tex_reduce_composite_4_vpt_unival_max, + reduce_tex_reduce_composite_4_fpt_unival_max, + "reduce_tex_reduce_composite_4", + "reduce_tex_reduce_composite_4", + }, +}; + +/*static const shader_glsl_sub_table MAGNIFY_table[] = { + { + SHADER_FT_SUB_MAGNIFY, + magnify_vpt_unival_max, + magnify_fpt_unival_max, + "magnify", + "magnify", + }, +};*/ + +static const shader_glsl_sub_table MAGNIFY_table[] = { + { + SHADER_FT_SUB_MAGNIFY_LINEAR, + magnify_linear_vpt_unival_max, + magnify_linear_fpt_unival_max, + "magnify_linear", + "magnify_linear", + }, + { + SHADER_FT_SUB_MAGNIFY_DIFF, + magnify_diff_vpt_unival_max, + magnify_diff_fpt_unival_max, + "magnify_diff", + "magnify_diff", + }, + { + SHADER_FT_SUB_MAGNIFY_DIFF2, + magnify_diff2_vpt_unival_max, + magnify_diff2_fpt_unival_max, + "magnify_diff2", + "magnify_diff2", + }, + { + SHADER_FT_SUB_MAGNIFY_CONE, + magnify_cone_vpt_unival_max, + magnify_cone_fpt_unival_max, + "magnify_cone", + "magnify_cone", + }, + { + SHADER_FT_SUB_MAGNIFY_CONE2, + magnify_cone2_vpt_unival_max, + magnify_cone2_fpt_unival_max, + "magnify_cone2", + "magnify_cone2", + }, +}; + +/*static const shader_glsl_sub_table MLAA_table[] = { + { + SHADER_FT_SUB_MLAA, + mlaa_vpt_unival_max, + mlaa_fpt_unival_max, + "mlaa", + "mlaa", + }, +};*/ + +static const shader_glsl_sub_table MLAA_table[] = { + { + SHADER_FT_SUB_MLAA_EDGE, + mlaa_edge_vpt_unival_max, + mlaa_edge_fpt_unival_max, + "mlaa_edge", + "mlaa_edge", + }, + { + SHADER_FT_SUB_MLAA_AREA, + mlaa_area_vpt_unival_max, + mlaa_area_fpt_unival_max, + "mlaa_area", + "mlaa_area", + }, + { + SHADER_FT_SUB_MLAA_BLEND, + mlaa_blend_vpt_unival_max, + mlaa_blend_fpt_unival_max, + "mlaa_blend", + "mlaa_blend", + }, +}; + +static const shader_glsl_sub_table CONTOUR_table[] = { + { + SHADER_FT_SUB_CONTOUR, + contour_vpt_unival_max, + contour_fpt_unival_max, + "contour", + "contour", + }, +}; + +static const shader_glsl_sub_table CONTOUR_NPR_table[] = { + { + SHADER_FT_SUB_CONTOUR_NPR, + contour_npr_vpt_unival_max, + contour_npr_fpt_unival_max, + "contour_npr", + "contour_npr", + }, +}; + +/*static const shader_glsl_sub_table EXPOSURE_table[] = { + { + SHADER_FT_SUB_EXPOSURE, + exposure_vpt_unival_max, + exposure_fpt_unival_max, + "exposure", + "exposure", + }, +};*/ + +static const shader_glsl_sub_table EXPOSURE_table[] = { + { + SHADER_FT_SUB_EXPOSURE_MINIFY, + exposure_minify_vpt_unival_max, + exposure_minify_fpt_unival_max, + "exposure_minify", + "exposure_minify", + }, + { + SHADER_FT_SUB_EXPOSURE_MEASURE, + exposure_measure_vpt_unival_max, + exposure_measure_fpt_unival_max, + "exposure_measure", + "exposure_measure", + }, + { + SHADER_FT_SUB_EXPOSURE_AVERAGE, + exposure_average_vpt_unival_max, + exposure_average_fpt_unival_max, + "exposure_average", + "exposure_average", + }, +}; + +/*static const shader_glsl_sub_table GAUSS_table[] = { + { + SHADER_FT_SUB_PP_GAUSS, + pp_gauss_vpt_unival_max, + pp_gauss_fpt_unival_max, + "pp_gauss", + "pp_gauss", + }, +};*/ + +static const shader_glsl_sub_table GAUSS_table[] = { + { + SHADER_FT_SUB_PP_GAUSS_USUAL, + pp_gauss_usual_vpt_unival_max, + pp_gauss_usual_fpt_unival_max, + "pp_gauss_usual", + "pp_gauss_usual", + }, + { + SHADER_FT_SUB_PP_GAUSS_CONE, + pp_gauss_cone_vpt_unival_max, + pp_gauss_cone_fpt_unival_max, + "pp_gauss_cone", + "pp_gauss_cone", + }, +}; + +static const shader_glsl_sub_table SUN_table[] = { + { + SHADER_FT_SUB_SUN, + sun_vpt_unival_max, + sun_fpt_unival_max, + "sun", + "sun", + }, +}; + +static const shader_glsl_sub_table SUN_NO_TEXTURED_table[] = { + { + SHADER_FT_SUB_SUN_NO_TEXTURED, + sun_no_textured_vpt_unival_max, + sun_no_textured_fpt_unival_max, + "sun_no_textured", + "sun_no_textured", + }, +}; + +/*static const shader_glsl_sub_table FADE_table[] = { + { + SHADER_FT_SUB_FADE, + fade_vpt_unival_max, + fade_fpt_unival_max, + "fade", + "fade", + }, +};*/ + +static const shader_glsl_sub_table WATER01_table[] = { + { + SHADER_FT_SUB_WATER01, + water01_vpt_unival_max, + water01_fpt_unival_max, + "water01", + "water01", + }, +}; + +/*static const shader_glsl_sub_table WATER02_table[] = { + { + SHADER_FT_SUB_WATER02, + water02_vpt_unival_max, + water02_fpt_unival_max, + "water02", + "water02", + }, +};*/ + +/*static const shader_glsl_sub_table WATRING_table[] = { + { + SHADER_FT_SUB_WATER_RING, + water_ring_vpt_unival_max, + water_ring_fpt_unival_max, + "water_ring", + "water_ring", + }, +};*/ + +static const shader_glsl_sub_table W_PTCL_table[] = { + { + SHADER_FT_SUB_WATER_PARTICLE, + water_particle_vpt_unival_max, + water_particle_fpt_unival_max, + "water_particle", + "water_particle", + }, +}; + +/*static const shader_glsl_sub_table SNOW_PT_table[] = { + { + SHADER_FT_SUB_SNOW_PARTICLE, + snow_particle_vpt_unival_max, + snow_particle_fpt_unival_max, + "snow_particle", + "snow_particle", + }, +};*/ + +static const shader_glsl_sub_table SNOW_PT_table[] = { + { + SHADER_FT_SUB_SNOW_PARTICLE, + snow_particle_vpt_unival_max, + snow_particle_fpt_unival_max, + "snow_particle", + "snow_particle", + }, + { + SHADER_FT_SUB_SNOW_PARTICLE_CPU, + snow_particle_cpu_vpt_unival_max, + snow_particle_cpu_fpt_unival_max, + "snow_particle_cpu", + "snow_particle_cpu", + }, +}; + +static const shader_glsl_sub_table LEAF_PT_table[] = { + { + SHADER_FT_SUB_LEAF_PARTICLE, + leaf_particle_vpt_unival_max, + leaf_particle_fpt_unival_max, + "leaf_particle", + "leaf_particle", + }, +}; + +static const shader_glsl_sub_table STAR_table[] = { + { + SHADER_FT_SUB_STAR, + star_vpt_unival_max, + star_fpt_unival_max, + "star", + "star", + }, + { + SHADER_FT_SUB_STAR_MILKY_WAY, + star_milky_way_vpt_unival_max, + star_milky_way_fpt_unival_max, + "star_milky_way", + "star_milky_way", + }, +}; + +/*static const shader_glsl_sub_table SNORING_table[] = { + { + SHADER_FT_SUB_SNOW_RING, + snow_ring_vpt_unival_max, + snow_ring_fpt_unival_max, + "snow_ring", + "snow_ring", + }, +}; + +static const shader_glsl_sub_table SN_FOOT_table[] = { + { + SHADER_FT_SUB_SNOW_FOOTPRINT, + snow_footprint_vpt_unival_max, + snow_footprint_fpt_unival_max, + "snow_footprint", + "snow_footprint", + }, +}; + +static const shader_glsl_sub_table SN_TSL_table[] = { + { + SHADER_FT_SUB_SNOW_TEX_SPACE_LIGHT, + snow_tex_space_light_vpt_unival_max, + snow_tex_space_light_fpt_unival_max, + "snow_tex_space_light", + "snow_tex_space_light", + }, +}; + +static const shader_glsl_sub_table SN_NRM_table[] = { + { + SHADER_FT_SUB_SNOW_CALC_NORMAL, + snow_calc_normal_vpt_unival_max, + snow_calc_normal_fpt_unival_max, + "snow_calc_normal", + "snow_calc_normal", + }, +};*/ + +static const shader_glsl_sub_table FLOOR_table[] = { + { + SHADER_FT_SUB_FLOOR, + floor_vpt_unival_max, + floor_fpt_unival_max, + "floor", + "floor", + }, +}; + +static const shader_glsl_sub_table PUDDLE_table[] = { + { + SHADER_FT_SUB_PUDDLE, + puddle_vpt_unival_max, + puddle_fpt_unival_max, + "puddle", + "puddle", + }, +}; + +static const shader_glsl_sub_table S_REFL_table[] = { + { + SHADER_FT_SUB_SIMPLE_REFLECT, + simple_reflect_vpt_unival_max, + simple_reflect_fpt_unival_max, + "simple_reflect", + "simple_reflect", + }, +}; + +static const shader_glsl_sub_table S_REFR_table[] = { + { + SHADER_FT_SUB_SIMPLE_REFRACT, + simple_refract_vpt_unival_max, + simple_refract_fpt_unival_max, + "simple_refract", + "simple_refract", + }, +}; + +static const shader_glsl_sub_table RIPEMIT_table[] = { + { + SHADER_FT_SUB_RIPPLE_EMIT, + ripple_emit_vpt_unival_max, + ripple_emit_fpt_unival_max, + "ripple_emit", + "ripple_emit", + }, +}; + +static const shader_glsl_sub_table RAIN_table[] = { + { + SHADER_FT_SUB_RAIN, + rain_vpt_unival_max, + rain_fpt_unival_max, + "rain", + "rain", + }, +}; + +/*static const shader_glsl_sub_table VOLLIT_table[] = { + { + SHADER_FT_SUB_VOLUME_LIGHT, + volume_light_vpt_unival_max, + volume_light_fpt_unival_max, + "volume_light", + "volume_light", + }, +};*/ + +/*static const shader_glsl_sub_table FENCE_table[] = { + { + SHADER_FT_SUB_FENCE_ALPHA, + fence_alpha_vpt_unival_max, + fence_alpha_fpt_unival_max, + "fence_alpha", + "fence_alpha", + }, +};*/ + +static const shader_glsl_sub_table RIPPLE_table[] = { + { + SHADER_FT_SUB_RIPPLE, + ripple_vpt_unival_max, + ripple_fpt_unival_max, + "ripple", + "ripple", + }, +}; + +static const shader_glsl_sub_table FOGPTCL_table[] = { + { + SHADER_FT_SUB_FOG_PTCL, + fog_ptcl_vpt_unival_max, + fog_ptcl_fpt_unival_max, + "fog_ptcl", + "fog_ptcl", + }, +}; + +static const shader_glsl_sub_table PARTICL_table[] = { + { + SHADER_FT_SUB_PARTICLE, + particle_vpt_unival_max, + particle_fpt_unival_max, + "particle", + "particle", + }, +}; + +static const shader_glsl_sub_table GLITTER_PT_table[] = { + { + SHADER_FT_SUB_GLITTER_PARTICLE, + glitter_particle_vpt_unival_max, + glitter_particle_fpt_unival_max, + "glitter_particle", + "glitter_particle", + }, +}; + +/*static const shader_glsl_sub_table SHOW_VEC_table[] = { + { + SHADER_FT_SUB_SHOW_VECTOR, + show_vector_vpt_unival_max, + show_vector_fpt_unival_max, + "show_vector", + "show_vector", + }, +};*/ + +static const shader_glsl_sub_table FONT_table[] = { + { + SHADER_FT_SUB_FONT, + font_vpt_unival_max, + font_fpt_unival_max, + "font", + "font", + }, +}; + +static const shader_glsl_sub_table MOVIE_table[] = { + { + SHADER_FT_SUB_MOVIE, + movie_vpt_unival_max, + movie_fpt_unival_max, + "movie", + "movie", + }, +}; + +/*static const shader_glsl_sub_table IMGFILT_table[] = { + { + SHADER_FT_SUB_IMGFILTER, + imgfilter_vpt_unival_max, + imgfilter_fpt_unival_max, + "imgfilter", + "imgfilter", + }, +};*/ + +static const shader_glsl_sub_table IMGFILT_table[] = { + { + SHADER_FT_SUB_BOX4, + box4_vpt_unival_max, + box4_fpt_unival_max, + "box4", + "box4", + }, + { + SHADER_FT_SUB_BOX8, + box8_vpt_unival_max, + box8_fpt_unival_max, + "box8", + "box8", + }, + { + SHADER_FT_SUB_COPY, + copy_vpt_unival_max, + copy_fpt_unival_max, + "copy", + "copy", + }, +}; + +static const shader_glsl_sub_table SPRITE_table[] = { + { + SHADER_FT_SUB_SPRITE, + sprite_vpt_unival_max, + sprite_fpt_unival_max, + "sprite", + "sprite", + }, +}; + +static const uniform_name BLINN_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_TEXTURE_COUNT, + U_LIGHT_0, + U_NORMAL, + U_SPECULAR, + U_ENV_MAP, + U_FOG_HEIGHT, + U_MORPH, + U_MORPH_COLOR, + U_LIGHT_1, + U_ALPHA_TEST, // 11th added +}; + +static const uniform_name ITEM_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_MORPH, + U_SPECULAR_IBL, + U_SPECULAR, + U_NORMAL, + U_TEXTURE_COUNT, + U_ENV_MAP, + U_SELF_SHADOW, + U_FOG, + U_ALPHA_TEST, + U_SHADOW, + U_CHARA_COLOR, + U_TONE_CURVE, +}; + +static const uniform_name STAGE_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_MORPH, + U_MORPH_COLOR, + U_TEXTURE_COUNT, + U_ENV_MAP, + U_LIGHT_0, + U_NORMAL, + U_FOG_HEIGHT, + U_LIGHT_1, + U12, + U_ALPHA_TEST, // 11th added +}; + +static const uniform_name SKIN_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_NORMAL, + U_SELF_SHADOW, + U_FOG, + U_ALPHA_TEST, + U_SHADOW, + U_NPR, + U_CHARA_COLOR, + U_TONE_CURVE, +}; + +static const uniform_name SSS_SKIN_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U37, + U_ALPHA_TEST, + U_SELF_SHADOW, + U_SHADOW, + U_NPR, + U26, +}; + +static const uniform_name SSS_FILT_uniform[] = { + //U16, // 0th removed + U_SSS_FILTER, + U_NPR, +}; + +static const uniform_name HAIR_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_SPECULAR_IBL, + U_SPECULAR, + U_NORMAL, + U_TRANSPARENCY, + U_TRANSLUCENCY, + U_ANISO, + U_SELF_SHADOW, + U_FOG, + U_SHADOW, + U_NPR, + U_CHARA_COLOR, + U_TONE_CURVE, + U_ALPHA_TEST, // 14th added +}; + +static const uniform_name CLOTH_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_SPECULAR_IBL, + U_SPECULAR, + U_NORMAL, + U_TRANSPARENCY, + U_ENV_MAP, + U_SELF_SHADOW, + U_FOG, + U_ALPHA_TEST, + U_ANISO, + U_SHADOW, + U_NPR, + U_CHARA_COLOR, + U_TONE_CURVE, +}; + +static const uniform_name TIGHTS_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_SPECULAR, + U_ENV_MAP, + U_SELF_SHADOW, + U_FOG, + U_ALPHA_TEST, + U_SHADOW, + U_NPR, + U_CHARA_COLOR, + U_TONE_CURVE, +}; + +static const uniform_name SKY_uniform[] = { + U_TEX_0_TYPE, + U_TEX_1_TYPE, + U_TEXTURE_COUNT, + U_MORPH, + U_MORPH_COLOR, + U_FOG_HEIGHT, + U_ALPHA_TEST, // 6th added +}; + +/*static const uniform_name EYEBALL_uniform[] = { + U_BONE_MAT, + U_ENV_MAP, +};*/ + +/*static const uniform_name EYELENS_uniform[] = { + U_BONE_MAT, + U_SPECULAR, + U_ENV_MAP, +};*/ + +static const uniform_name GLASEYE_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_SELF_SHADOW, + U_FOG, + U18, + U_SHADOW, + U_CHARA_COLOR, + U_TONE_CURVE, +}; + +/*static const uniform_name MEMBRAN_uniform[] = { + U_BONE_MAT, + U_NORMAL, + U_MEMBRANE, +};*/ + +/*static const uniform_name SHDMAP_uniform[] = { + U_BONE_MAT, + U_TEXTURE_COUNT, + U_TRANSPARENCY, + U_LIGHT_1, + U2D, +};*/ + +/*static const uniform_name ESM_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_TEXTURE_COUNT, + U_TRANSPARENCY, +};*/ + +static const uniform_name ESMGAUSS_uniform[] = { + U_LIGHT_PROJ, +}; + +static const uniform_name ESMFILT_uniform[] = { + U_ESM_FILTER, +}; + +static const uniform_name LITPROJ_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_SPECULAR, + U_NORMAL, + U_TEXTURE_COUNT, + U_TRANSPARENCY, +}; + +static const uniform_name SIMPLE_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_TEXTURE_COUNT, + //U_NORMAL, // 3rd removed + //U_INSTANCE, // 4th removed + //U2E, // 5th removed +}; + +static const uniform_name SIL_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_TRANSPARENCY, + U_TEXTURE_COUNT, + U_MORPH, + U_MORPH_COLOR, + U0A, + U_ALPHA_TEST, // 7th added +}; + +static const uniform_name LAMBERT_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_TEXTURE_COUNT, + U_LIGHT_0, + U_FOG_HEIGHT, + U_MORPH, + U_MORPH_COLOR, + U_LIGHT_1, + U_ALPHA_TEST, // 8th added +}; + +static const uniform_name CONSTANT_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_TEXTURE_COUNT, + U_FOG_HEIGHT, + U_MORPH, + U_MORPH_COLOR, + U_ALPHA_TEST, // 6th added +}; + +/*static const uniform_name PEEL_uniform[] = { + U_DEPTH_PEEL, + U_BONE_MAT, +};*/ + +static const uniform_name TONEMAP_uniform[] = { + //U16, // 0th removed + U_TONE_MAP, + U_FLARE, + U_SCENE_FADE, + U_AET_BACK, + U_LIGHT_PROJ, + U_NPR, + //U25, 7th removed +}; + +static const uniform_name REDUCE_uniform[] = { + U_REDUCE, + U_ALPHA_MASK, +}; + +static const uniform_name MAGNIFY_uniform[] = { + U_MAGNIFY, +}; + +static const uniform_name MLAA_uniform[] = { + //U16, // 0th removed + U_ALPHA_MASK, + U_MLAA, + U_MLAA_SEARCH, +}; + +static const uniform_name CONTOUR_uniform[] = { + //U16, // 0th removed + U24, +}; + +static const uniform_name CONTOUR_NPR_uniform[] = { + U_INVALID, +}; + +static const uniform_name EXPOSURE_uniform[] = { + U_EXPOSURE, +}; + +static const uniform_name GAUSS_uniform[] = { + U_GAUSS, +}; + +static const uniform_name SUN_uniform[] = { + U_INVALID, +}; + +static const uniform_name SUN_NO_TEXTURED_uniform[] = { + U_INVALID, +}; + +/*static const uniform_name FADE_uniform[] = { + U_FADE, +};*/ + +static const uniform_name WATER01_uniform[] = { + U_MORPH, + U_MORPH_COLOR, + U_TEXTURE_COUNT, + U_NORMAL, + U_WATER_REFLECT, + U_ENV_MAP, + U_SPECULAR, + U_FOG_HEIGHT, +}; + +/*static const uniform_name WATER02_uniform[] = { + U_INVALID, +};*/ + +/*static const uniform_name WATRING_uniform[] = { + U_LIGHT_0, + U_LIGHT_1, +};*/ + +static const uniform_name W_PTCL_uniform[] = { + U_INVALID, +}; + +static const uniform_name SNOW_PT_uniform[] = { + U_SNOW_PARTICLE, +}; + +static const uniform_name LEAF_PT_uniform[] = { + U_INVALID, +}; + +static const uniform_name STAR_uniform[] = { + U_STAR, +}; + +/*static const uniform_name SNORING_uniform[] = { + U_TEXTURE_COUNT, + U_NORMAL, + U_SPECULAR, + U_LIGHT_0, + U_LIGHT_1, +}; + +static const uniform_name SN_FOOT_uniform[] = { + U_INVALID, +}; + +static const uniform_name SN_TSL_uniform[] = { + U_INVALID, +}; + +static const uniform_name SN_NRM_uniform[] = { + U_INVALID, +};*/ + +static const uniform_name FLOOR_uniform[] = { + U_TEXTURE_COUNT, + U_NORMAL, + U_LIGHT_0, + U_LIGHT_1, + U_FOG_HEIGHT, + U_MORPH, + U_MORPH_COLOR, + U_ALPHA_TEST, // 7th added +}; + +static const uniform_name PUDDLE_uniform[] = { + U_NORMAL, + U_LIGHT_0, + U_LIGHT_1, + U_FOG_HEIGHT, +}; + +static const uniform_name S_REFL_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_REFLECT, + U_MORPH, + U_MORPH_COLOR, + U_ALPHA_TEST, + U_CLIP_PLANE, + U_TEXTURE_COUNT, + U_TONE_CURVE, + U_CHARA_COLOR, +}; + +static const uniform_name S_REFR_uniform[] = { + U_BONE_MAT, + U_TRANSPARENCY, +}; + +static const uniform_name RIPEMIT_uniform[] = { + U_RIPPLE, + U_RIPPLE_EMIT, +}; + +static const uniform_name RAIN_uniform[] = { + U_INVALID, +}; + +/*static const uniform_name VOLLIT_uniform[] = { + U_INVALID, +};*/ + +/*static const uniform_name FENCE_uniform[] = { + U_INSTANCE, + U_FOG_HEIGHT, +};*/ + +static const uniform_name RIPPLE_uniform[] = { + U_RIPPLE, +}; + +static const uniform_name FOGPTCL_uniform[] = { + U_INVALID, +}; + +static const uniform_name PARTICL_uniform[] = { + U_INVALID, +}; + +static const uniform_name GLITTER_PT_uniform[] = { + U_TEXTURE_COUNT, + U_TEXTURE_BLEND, + U_FOG_HEIGHT, + U_ALPHA_BLEND, +}; + +/*static const uniform_name SHOW_VEC_uniform[] = { + //U16, // 0th removed + U_BONE_MAT, + U_SHOW_VECTOR, +};*/ + +static const uniform_name FONT_uniform[] = { + //U16, // 0th removed + U_INVALID, // 0th removed, 1st added +}; + +static const uniform_name MOVIE_uniform[] = { + U_MOVIE, +}; + +static const uniform_name IMGFILT_uniform[] = { + U_IMAGE_FILTER, +}; + +static const uniform_name SPRITE_uniform[] = { + U_TEX_0_TYPE, + U_TEX_1_TYPE, + U_COMBINER, +}; + +static const bool BLINN_permut[] = { + // true, // 0th removed + true, + false, + false, + false, + false, + false, + false, + true, + true, + false, + false, // 11th added +}; + +static const bool ITEM_permut[] = { + //true, // 0th removed + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, +}; + +static const bool STAGE_permut[] = { + //true, // 0th removed + true, + true, + true, + false, + false, + false, + false, + false, + false, + false, + false, // 11th added +}; + +static const bool SKIN_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + false, + false, + false, + false, + false, +}; + +static const bool SSS_SKIN_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + false, + false, + false, +}; + +static const bool SSS_FILT_permut[] = { + //true, // 0th removed + true, + true, +}; + +static const bool HAIR_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, // 14th added +}; + +static const bool CLOTH_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, +}; + +static const bool TIGHTS_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + false, + false, + false, + false, + false, + false, +}; + +static const bool SKY_permut[] = { + false, + false, + false, + true, + true, + false, + false, // 6th added +}; + +/*static const bool EYEBALL_permut[] = { + true, + false, +};*/ + +/*static const bool EYELENS_permut[] = { + true, + false, + false, +};*/ + +static const bool GLASEYE_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + false, + false, + false, +}; + +/*static const bool MEMBRAN_permut[] = { + true, + false, + false, +};*/ + +/*static const bool SHDMAP_permut[] = { + true, + false, + false, + false, + true, +};*/ + +/*static const bool ESM_permut[] = { + //true, // 0th removed + true, + false, + false, +};*/ + +static const bool ESMGAUSS_permut[] = { + true, +}; + +static const bool ESMFILT_permut[] = { + true, +}; + +static const bool LITPROJ_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + false, +}; + +static const bool SIMPLE_permut[] = { + //true, // 0th removed + true, + false, + //false, // 3rd removed + //false, // 4th removed + //false, // 5th removed +}; + +static const bool SIL_permut[] = { + //true, // 0th removed + true, + false, + false, + true, + false, + false, + false, // 7th added +}; + +static const bool LAMBERT_permut[] = { + //true, // 0th removed + true, + false, + false, + false, + true, + true, + false, + false, // 8th added +}; + +static const bool CONSTANT_permut[] = { + //true, // 0th removed + true, + false, + false, + true, + true, + false, // 6th added +}; + +/*static const bool PEEL_permut[] = { + false, + true, +};*/ + +static const bool TONEMAP_permut[] = { + //true, // 0th removed + false, + false, + false, + false, + false, + false, + false, +}; + +static const bool REDUCE_permut[] = { + true, + true, +}; + +static const bool MAGNIFY_permut[] = { + true, +}; + +static const bool MLAA_permut[] = { + //true, // 0th removed + true, + true, + true, +}; + +static const bool CONTOUR_permut[] = { + //true, // 0th removed + false, +}; + +static const bool CONTOUR_NPR_permut[] = { + false, +}; + +static const bool EXPOSURE_permut[] = { + true, +}; + +static const bool GAUSS_permut[] = { + true, +}; + +static const bool SUN_permut[] = { + false, +}; + +static const bool SUN_NO_TEXTURED_permut[] = { + false, +}; + +/*static const bool FADE_permut[] = { + false, +};*/ + +static const bool WATER01_permut[] = { + true, + true, + false, + false, + false, + false, + false, + false, +}; + +static const bool WATER02_permut[] = { + false, +}; + +/*static const bool WATRING_permut[] = { + false, + false, +};*/ + +static const bool W_PTCL_permut[] = { + false, +}; + +static const bool SNOW_PT_permut[] = { + false, +}; + +static const bool LEAF_PT_permut[] = { + false, +}; + +static const bool STAR_permut[] = { + false, +}; + +/*static const bool SNORING_permut[] = { + false, + false, + false, + false, + false, +}; + +static const bool SN_FOOT_permut[] = { + false, +}; + +static const bool SN_TSL_permut[] = { + false, +}; + +static const bool SN_NRM_permut[] = { + false, +};*/ + +static const bool FLOOR_permut[] = { + false, + false, + false, + false, + false, + true, + true, + false, // 7th added +}; + +static const bool PUDDLE_permut[] = { + false, + false, + false, + false, +}; + +static const bool S_REFL_permut[] = { + //true, // 0th removed + true, + true, + true, + true, + false, + false, + false, + false, + false, +}; + +static const bool S_REFR_permut[] = { + true, + false, +}; + +static const bool RIPEMIT_permut[] = { + true, + true, +}; + +static const bool RAIN_permut[] = { + false, +}; + +/*static const bool VOLLIT_permut[] = { + false, +};*/ + +/*static const bool FENCE_permut[] = { + false, + false, +};*/ + +static const bool RIPPLE_permut[] = { + true, +}; + +static const bool FOGPTCL_permut[] = { + false, +}; + +static const bool PARTICL_permut[] = { + false, +}; + +static const bool GLITTER_PT_permut[] = { + false, + false, + false, + false, +}; + +/*static const bool SHOW_VEC_permut[] = { + //true, // 0th removed + false, + false, +};*/ + +static const bool FONT_permut[] = { + //true, // 0th removed + false, // 0th removed, 1st added +}; + +static const bool MOVIE_permut[] = { + true, +}; + +static const bool IMGFILT_permut[] = { + false, +}; + +static const bool SPRITE_permut[] = { + false, + false, + false, +}; + +struct glass_eye_struct { + vec4 field_0; + vec4 field_10; + float_t field_20; + float_t field_24; + float_t field_28; + float_t field_2C; + vec3 field_30; + vec3 field_3C; + vec3 field_48; + float_t field_54; + vec3 field_58; + float_t field_64; + vec3 field_68; + vec3 field_74; + vec3 field_80; + float_t field_8C; + vec3 field_90; + uint32_t frame; + vec4 field_A0; + bool field_B0; + bool field_B1; + bool field_B2; + bool field_B3; + int32_t field_B4; + int32_t field_B8; + int32_t field_BC; +}; + +#define shader_table_struct(n) \ +{ \ + #n, \ + SHADER_FT_##n, \ + sizeof(n##_table) / sizeof(shader_glsl_sub_table), \ + n##_table, \ + sizeof(n##_uniform) / sizeof(uniform_name), \ + n##_uniform, \ + n##_permut, \ +} + +const shader_glsl_table shader_ft_table[] = { + { + "SHADER_FFP", + SHADER_FT_FFP, + 0, + 0, + 0, + 0, + 0, + }, + shader_table_struct(BLINN), + shader_table_struct(ITEM), + shader_table_struct(STAGE), + shader_table_struct(SKIN), + shader_table_struct(SSS_SKIN), + shader_table_struct(SSS_FILT), + shader_table_struct(HAIR), + shader_table_struct(CLOTH), + shader_table_struct(TIGHTS), + shader_table_struct(SKY), + //shader_table_struct(EYEBALL), + //shader_table_struct(EYELENS), + shader_table_struct(GLASEYE), + //shader_table_struct(MEMBRAN), + //shader_table_struct(SHDMAP), + //shader_table_struct(ESM), + shader_table_struct(ESMGAUSS), + shader_table_struct(ESMFILT), + shader_table_struct(LITPROJ), + shader_table_struct(SIMPLE), + shader_table_struct(SIL), + shader_table_struct(LAMBERT), + shader_table_struct(CONSTANT), + //shader_table_struct(PEEL), + shader_table_struct(TONEMAP), + shader_table_struct(REDUCE), + shader_table_struct(MAGNIFY), + shader_table_struct(MLAA), + shader_table_struct(CONTOUR), + shader_table_struct(CONTOUR_NPR), + shader_table_struct(EXPOSURE), + shader_table_struct(GAUSS), + shader_table_struct(SUN), + shader_table_struct(SUN_NO_TEXTURED), + //shader_table_struct(FADE), + shader_table_struct(WATER01), + //shader_table_struct(WATER02), + //shader_table_struct(WATRING), + shader_table_struct(W_PTCL), + shader_table_struct(SNOW_PT), + shader_table_struct(LEAF_PT), + shader_table_struct(STAR), + /*shader_table_struct(SNORING), + shader_table_struct(SN_FOOT), + shader_table_struct(SN_TSL), + shader_table_struct(SN_NRM),*/ + shader_table_struct(FLOOR), + shader_table_struct(PUDDLE), + shader_table_struct(S_REFL), + shader_table_struct(S_REFR), + shader_table_struct(RIPEMIT), + shader_table_struct(RAIN), + //shader_table_struct(VOLLIT), + //shader_table_struct(FENCE), + shader_table_struct(RIPPLE), + shader_table_struct(FOGPTCL), + shader_table_struct(PARTICL), + shader_table_struct(GLITTER_PT), + //shader_table_struct(SHOW_VEC), + shader_table_struct(FONT), + shader_table_struct(MOVIE), + shader_table_struct(IMGFILT), + shader_table_struct(SPRITE), +}; + +#undef shader_table_struct +#undef shader_table_struct + +const size_t shader_ft_table_size = + sizeof(shader_ft_table) / sizeof(shader_glsl_table); + +static void glass_eye_calc(glass_eye_struct* glass_eye); +static void glass_eye_set(glass_eye_struct* glass_eye); +static void shader_bind_blinn(shader_glsl_set_data* set, shader_glsl* shad); +static void shader_bind_cloth(shader_glsl_set_data* set, shader_glsl* shad); +static void shader_bind_hair(shader_glsl_set_data* set, shader_glsl* shad); +static void shader_bind_eye_ball(shader_glsl_set_data* set, shader_glsl* shad); +static void shader_bind_tone_map(shader_glsl_set_data* set, shader_glsl* shad); +static void shader_bind_sss_filter(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_esm_filter(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_reduce_tex(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_magnify(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_mlaa(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_exposure(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_gauss(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_snow_particle(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_star(shader_glsl_set_data* set, shader_glsl* shad); // Added +static void shader_bind_imgfilter(shader_glsl_set_data* set, shader_glsl* shad); // Added + +const shader_glsl_bind_func shader_ft_bind_func_table[] = { + { + SHADER_FT_BLINN, + shader_bind_blinn, + }, + { + SHADER_FT_CLOTH, + shader_bind_cloth, + }, + { + SHADER_FT_HAIR, + shader_bind_hair, + }, + { + //SHADER_FT_EYEBALL, + SHADER_FT_GLASEYE, + shader_bind_eye_ball, + }, + { + SHADER_FT_TONEMAP, + shader_bind_tone_map, + }, + { // Added + SHADER_FT_SSS_FILT, + shader_bind_sss_filter, + }, + { // Added + SHADER_FT_ESMFILT, + shader_bind_esm_filter, + }, + { // Added + SHADER_FT_REDUCE, + shader_bind_reduce_tex, + }, + { // Added + SHADER_FT_MAGNIFY, + shader_bind_magnify, + }, + { // Added + SHADER_FT_MLAA, + shader_bind_mlaa, + }, + { // Added + SHADER_FT_EXPOSURE, + shader_bind_exposure, + }, + { // Added + SHADER_FT_GAUSS, + shader_bind_gauss, + }, + { // Added + SHADER_FT_SNOW_PT, + shader_bind_snow_particle, + }, + { // Added + SHADER_FT_STAR, + shader_bind_star, + }, + { // Added + SHADER_FT_IMGFILT, + shader_bind_imgfilter, + }, +}; + +const size_t shader_ft_bind_func_table_size = + sizeof(shader_ft_bind_func_table) / sizeof(shader_glsl_bind_func); + +shader_glsl_set_data shaders_ft; + +static glass_eye_struct glass_eye = { + { 5.0f, 5.0f, 0.5f, 0.5f }, + { 2.5f, 2.5f, 0.5f, 0.5f }, + 1.0f, + 1.45f, + 0.02f, + 0.85f, + { 1.0f, 1.2f, 0.45f }, + { 1.0f, 1.2f, 0.25f }, + { 0.5f, 0.6f, 0.4f }, + -0.2f, + { 1.0f, 1.0f, 1.0f }, + 0.0f, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, + 0.0, + { 0.0f, 0.0f, 0.0f }, + 0, + { 0.0f, 0.0f, 0.0f, 0.0f }, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +int32_t shader_ft_get_index_by_name(const char* name) { + if (!str_utils_compare(name, "EYEBALL")) + return SHADER_FT_GLASEYE; + return -1; +} + +static void glass_eye_calc(glass_eye_struct* glass_eye) { + float_t v2 = glass_eye->field_28; + glass_eye->field_64 = glass_eye->field_2C / v2; + glass_eye->field_90 = glass_eye->field_58; + glass_eye->field_68 = glass_eye->field_30 * v2; + glass_eye->field_74 = glass_eye->field_3C * v2; + glass_eye->field_80 = glass_eye->field_48 * v2; + glass_eye->field_8C = glass_eye->field_54 * v2; + if (glass_eye->field_B0 == 0) { + glass_eye->field_A0 = 0.0f; + return; + } + + uint32_t(FASTCALL * get_frame_counter)() = (uint32_t(FASTCALL*)())0x0000000140192E00; + + uint32_t frame = get_frame_counter(); + if (frame == glass_eye->frame) + return; + + glass_eye->frame = frame; + if (frame == (frame / 90) * 90) { + float_t(FASTCALL * rand_state_array_get_float)(int32_t index) = (float_t(FASTCALL*)(int32_t index))0x00000001404FFE60; + glass_eye->field_A0.x = (rand_state_array_get_float(0) - 0.5f) * 0.015f; + glass_eye->field_A0.y = (rand_state_array_get_float(0) - 0.5f) * 0.015f; + } + + float_t v17 = (float_t)(uint8_t)frame * (float_t)(M_PI * (1.0 / 128.0)); + float_t v19 = sinf(sinf(v17 * 27.0f) + v17 * 2.0f); + float_t v20 = sinf(v17 * 23.0f); + glass_eye->field_A0.w = 0.0f; + glass_eye->field_A0.z = (v19 + v20) * 0.5f * 0.01f; +} + +static void glass_eye_set(glass_eye_struct* glass_eye) { + glass_eye_batch_shader_data glass_eye_batch = {}; + + vec4 temp; + *(vec3*)&temp = glass_eye->field_68 * glass_eye->field_68; + temp.w = temp.z; + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); + glass_eye_batch.g_ellipsoid_radius = temp; + + *(vec3*)&temp = glass_eye->field_68; + temp.w = 1.0f; + glass_eye_batch.g_ellipsoid_scale = temp; + + glass_eye_batch.g_tex_model_param = glass_eye->field_0; + glass_eye_batch.g_tex_offset = glass_eye->field_A0; + + *(vec3*)&temp = glass_eye->field_90 * glass_eye->field_90; + temp.w = temp.z; + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); + glass_eye_batch.g_eb_radius = temp; + + glass_eye_batch.g_eb_tex_model_param = glass_eye->field_10; + + float_t v2 = (glass_eye->field_20 - glass_eye->field_24) / (glass_eye->field_20 + glass_eye->field_24); + v2 *= v2; + glass_eye_batch.g_fresnel = { 1.0f - v2, v2, 0.0f, 0.0f }; + + float_t v3 = (glass_eye->field_20 * glass_eye->field_20) / (glass_eye->field_24 * glass_eye->field_24); + glass_eye_batch.g_refract1 = { v3, 1.0f - v3, glass_eye->field_20 / glass_eye->field_24, 0.0f }; + + float_t v4 = (glass_eye->field_24 * glass_eye->field_24) / (glass_eye->field_20 * glass_eye->field_20); + glass_eye_batch.g_refract2 = { v4, 1.0f - v4, glass_eye->field_24 / glass_eye->field_20, 0.0f }; + + *(vec3*)&temp = glass_eye->field_74 * glass_eye->field_74; + temp.w = -1.0f; + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); + glass_eye_batch.g_iris_radius = temp; + + *(vec3*)&temp = glass_eye->field_68 * glass_eye->field_68; + temp.w = -1.0f; + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); + glass_eye_batch.g_cornea_radius = temp; + + *(vec3*)&temp = glass_eye->field_80 * glass_eye->field_80; + temp.w = -1.0f; + *(vec3*)&temp = vec3::rcp(*(vec3*)&temp); + glass_eye_batch.g_pupil_radius = temp; + + *(vec2*)&temp = *(vec2*)&glass_eye->field_0 * *(vec2*)&glass_eye->field_74; + temp.z = glass_eye->field_64 * 1.442695f; + temp.w = glass_eye->field_8C; + *(vec2*)&temp = vec2::rcp(*(vec2*)&temp); + glass_eye_batch.g_tex_scale = temp; + + rctx->glass_eye_batch_ubo.WriteMemory(glass_eye_batch); + rctx->glass_eye_batch_ubo.Bind(4); +} + +static void shader_bind_blinn(shader_glsl_set_data* set, shader_glsl* shad) { + shad->bind(set, uniform->arr[U_NORMAL] + ? SHADER_FT_SUB_BLINN_FRAG : SHADER_FT_SUB_BLINN_VERT); +} + +static void shader_bind_cloth(shader_glsl_set_data* set, shader_glsl* shad) { + shad->bind(set, uniform->arr[U_NPR] ? SHADER_FT_SUB_CLOTH_NPR1 + : (uniform->arr[U_ANISO] ? SHADER_FT_SUB_CLOTH_ANISO : SHADER_FT_SUB_CLOTH_DEFAULT)); +} + +static void shader_bind_hair(shader_glsl_set_data* set, shader_glsl* shad) { + shad->bind(set, uniform->arr[U_NPR] ? SHADER_FT_SUB_HAIR_NPR1 : SHADER_FT_SUB_HAIR_DEFAULT); +} + +static void shader_bind_eye_ball(shader_glsl_set_data* set, shader_glsl* shad) { + uniform->arr[U18] = 0; + if (set->shaders[SHADER_FT_GLASEYE].bind(set, SHADER_FT_SUB_GLASS_EYE) >= 0) { + glass_eye_calc(&glass_eye); + glass_eye_set(&glass_eye); + } +} + +static void shader_bind_tone_map(shader_glsl_set_data* set, shader_glsl* shad) { + shad->bind(set, uniform->arr[U_NPR] == 1 + ? SHADER_FT_SUB_TONEMAP_NPR1 : SHADER_FT_SUB_TONEMAP); +} + +static void shader_bind_sss_filter(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_SSS_FILTER]) { + case 0: + shad->bind(set, uniform->arr[U_NPR] + ? SHADER_FT_SUB_SSS_FILTER_MIN_NPR : SHADER_FT_SUB_SSS_FILTER_MIN); + break; + case 3: + shad->bind(set, SHADER_FT_SUB_SSS_FILTER_GAUSS_2D); + break; + } +} + +static void shader_bind_esm_filter(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_ESM_FILTER]) { + case 0: + shad->bind(set, SHADER_FT_SUB_ESM_FILTER_MIN); + break; + case 1: + shad->bind(set, SHADER_FT_SUB_ESM_FILTER_EROSION); + break; + } +} + +static void shader_bind_reduce_tex(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_REDUCE]) { + case 0: + switch (uniform->arr[U_ALPHA_MASK]) { + case 0: + shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_2); + break; + default: + shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_2_ALPHAMASK); + break; + } + break; + case 1: + switch (uniform->arr[U_ALPHA_MASK]) { + case 0: + shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_4); + break; + } + break; + case 3: + switch (uniform->arr[U_ALPHA_MASK]) { + case 0: + shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_4_EXTRACT); + break; + } + break; + case 4: + switch (uniform->arr[U_ALPHA_MASK]) { + case 0: + shad->bind(set, SHADER_FT_SUB_GHOST); + break; + } + break; + case 5: + switch (uniform->arr[U_ALPHA_MASK]) { + case 0: + shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_2); + break; + } + break; + case 6: + switch (uniform->arr[U_ALPHA_MASK]) { + case 0: + shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_BLUR); + break; + } + break; + case 7: + switch (uniform->arr[U_ALPHA_MASK]) { + case 0: + shad->bind(set, SHADER_FT_SUB_REDUCE_TEX_REDUCE_COMPOSITE_4); + break; + } + break; + } +} + +static void shader_bind_magnify(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_MAGNIFY]) { + case 0: + shad->bind(set, SHADER_FT_SUB_MAGNIFY_LINEAR); + break; + case 2: + shad->bind(set, SHADER_FT_SUB_MAGNIFY_DIFF); + break; + case 3: + shad->bind(set, SHADER_FT_SUB_MAGNIFY_DIFF2); + break; + case 4: + shad->bind(set, SHADER_FT_SUB_MAGNIFY_CONE); + break; + case 5: + shad->bind(set, SHADER_FT_SUB_MAGNIFY_CONE2); + break; + } +} + +static void shader_bind_mlaa(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_MLAA]) { + case 0: + shad->bind(set, SHADER_FT_SUB_MLAA_EDGE); + break; + case 1: + shad->bind(set, SHADER_FT_SUB_MLAA_AREA); + break; + case 2: + shad->bind(set, SHADER_FT_SUB_MLAA_BLEND); + break; + } +} + +static void shader_bind_exposure(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_EXPOSURE]) { + case 0: + shad->bind(set, SHADER_FT_SUB_EXPOSURE_MINIFY); + break; + case 1: + shad->bind(set, SHADER_FT_SUB_EXPOSURE_MEASURE); + break; + case 2: + shad->bind(set, SHADER_FT_SUB_EXPOSURE_AVERAGE); + break; + } +} + +static void shader_bind_gauss(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_GAUSS]) { + case 0: + shad->bind(set, SHADER_FT_SUB_PP_GAUSS_USUAL); + break; + case 1: + shad->bind(set, SHADER_FT_SUB_PP_GAUSS_CONE); + break; + } +} + +static void shader_bind_snow_particle(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_SNOW_PARTICLE]) { + case 0: + shad->bind(set, SHADER_FT_SUB_SNOW_PARTICLE_CPU); + break; + case 1: + shad->bind(set, SHADER_FT_SUB_SNOW_PARTICLE); + break; + } +} + +static void shader_bind_star(shader_glsl_set_data* set, shader_glsl* shad) { // Added + switch (uniform->arr[U_STAR]) { + case 0: + shad->bind(set, SHADER_FT_SUB_STAR); + break; + case 1: + shad->bind(set, SHADER_FT_SUB_STAR_MILKY_WAY); + break; + } +} + +static void shader_bind_imgfilter(shader_glsl_set_data* set, shader_glsl* shad) { + switch (uniform->arr[U_IMAGE_FILTER]) { + case 0: + shad->bind(set, SHADER_FT_SUB_BOX4); + break; + case 1: + shad->bind(set, SHADER_FT_SUB_BOX8); + break; + case 5: + shad->bind(set, SHADER_FT_SUB_COPY); + break; + } +} diff --git a/src/DivaGL/shader_glsl_ft.hpp b/src/DivaGL/shader_glsl_ft.hpp new file mode 100644 index 0000000..b3e24e6 --- /dev/null +++ b/src/DivaGL/shader_glsl_ft.hpp @@ -0,0 +1,87 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "shader_glsl.hpp" + +enum shader_ft_enum { + SHADER_FT_FFP = 0, + SHADER_FT_BLINN, + SHADER_FT_ITEM, + SHADER_FT_STAGE, + SHADER_FT_SKIN, + SHADER_FT_SSS_SKIN, + SHADER_FT_SSS_FILT, + SHADER_FT_HAIR, + SHADER_FT_CLOTH, + SHADER_FT_TIGHTS, + SHADER_FT_SKY, + //SHADER_FT_EYEBALL, + //SHADER_FT_EYELENS, + SHADER_FT_GLASEYE, + //SHADER_FT_MEMBRAN, + //SHADER_FT_SHDMAP, + //SHADER_FT_ESM, + SHADER_FT_ESMGAUSS, + SHADER_FT_ESMFILT, + SHADER_FT_LITPROJ, + SHADER_FT_SIMPLE, + SHADER_FT_SIL, + SHADER_FT_LAMBERT, + SHADER_FT_CONSTANT, + //SHADER_FT_PEEL, + SHADER_FT_TONEMAP, + SHADER_FT_REDUCE, + SHADER_FT_MAGNIFY, + SHADER_FT_MLAA, + SHADER_FT_CONTOUR, + SHADER_FT_CONTOUR_NPR, + SHADER_FT_EXPOSURE, + SHADER_FT_GAUSS, + SHADER_FT_SUN, + SHADER_FT_SUN_NO_TEXTURED, + //SHADER_FT_FADE, + SHADER_FT_WATER01, + //SHADER_FT_WATER02, + //SHADER_FT_WATRING, + SHADER_FT_W_PTCL, + SHADER_FT_SNOW_PT, + SHADER_FT_LEAF_PT, + SHADER_FT_STAR, + //SHADER_FT_SNORING, + //SHADER_FT_SN_FOOT, + //SHADER_FT_SN_TSL, + //SHADER_FT_SN_NRM, + SHADER_FT_FLOOR, + SHADER_FT_PUDDLE, + SHADER_FT_S_REFL, + SHADER_FT_S_REFR, + SHADER_FT_RIPEMIT, + SHADER_FT_RAIN, + //SHADER_FT_VOLLIT, + //SHADER_FT_FENCE, + SHADER_FT_RIPPLE, + SHADER_FT_FOGPTCL, + SHADER_FT_PARTICL, + SHADER_FT_GLITTER_PT, + //SHADER_FT_SHOW_VEC, + SHADER_FT_FONT, + SHADER_FT_MOVIE, + SHADER_FT_IMGFILT, + SHADER_FT_SPRITE, + SHADER_FT_END, + SHADER_FT_MAX, +}; + +extern const shader_glsl_table shader_ft_table[]; +extern const size_t shader_ft_table_size; +extern const shader_glsl_bind_func shader_ft_bind_func_table[]; +extern const size_t shader_ft_bind_func_table_size; + +extern shader_glsl_set_data shaders_ft; + +extern int32_t shader_ft_get_index_by_name(const char* name); diff --git a/src/DivaGL/shader_table.cpp b/src/DivaGL/shader_table.cpp new file mode 100644 index 0000000..514c86c --- /dev/null +++ b/src/DivaGL/shader_table.cpp @@ -0,0 +1,237 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "shader_table.hpp" +#include "../KKdLib/mat.hpp" +#include "render_context.hpp" +#include "render_texture.hpp" +#include "shader_glsl_ft.hpp" +#include "types.hpp" +#include "wrap.hpp" + +Shader* shaders = (Shader*)0x000000014CC57C10; +ShaderTable* shader_table = (ShaderTable*)0x0000000140A41D20; +ShaderBindFunc* shader_name_bind_func_table = (ShaderBindFunc*)0x0000000140A40F50; +int32_t* current_vp = (int32_t*)0x000000014CC587B0; +int32_t* current_fp = (int32_t*)0x000000014CC587B4; + +void FASTCALL shader_set(ShaderName name) { + if (!name) { + shader_unbind(); + return; + } + + glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 24, + (float)uniform->arr[U_TEXTURE_BLEND], 0.0, 0.0, 0.0); + + Shader* shad = &shaders[name]; + if (shad->bind_func) + shad->bind_func(shad); + else + shader_bind(shad, shad->sub->sub_name); +} + +void FASTCALL shader_bind_blinn(Shader* shad) { + shader_bind(shad, uniform->arr[U_NORMAL] ? BLINN_FRAG : BLINN_VERT); +} + +void FASTCALL shader_bind_cloth(Shader* shad) { + shader_bind(shad, uniform->arr[U_NPR] ? CLOTH_NPR1 + : (uniform->arr[U_ANISO] ? CLOTH_ANISO : CLOTH_DEFAULT)); +} + +void FASTCALL shader_bind_hair(Shader* shad) { + shader_bind(shad, uniform->arr[U_NPR] ? HAIR_NPR1 + : (uniform->arr[U_ANISO] ? HAIR_ANISO : HAIR_DEFAULT)); +} + +void FASTCALL shader_bind_membrane(Shader* shad) { + uniform->arr[U_MEMBRANE] = 3; + if (shader_bind(shad, MEMBRANE) < 0) + return; + + uint32_t(FASTCALL * sub_140192E00)() = (uint32_t(FASTCALL*)())0x0000000140192E00; + uint32_t v1 = sub_140192E00(); + mat4 mat = mat4_identity; + mat4_mul_rotate_x(&mat, (float_t)((v1 & 0x1FF) * (M_PI / 256.0)), &mat); + mat4_mul_rotate_z(&mat, (float_t)((v1 % 0x168) * (M_PI / 180.0)), &mat); + + vec4 vec = { 1.0f, 0.0f, 0.0f, 0.0f }; + mat4_transform_vector(&mat, &vec, &vec); + + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 10, vec.x, vec.y, vec.z, 0.0); +} + +void FASTCALL shader_bind_eye_ball(Shader* shad) { + uniform->arr[U18] = 0; + if (shader_bind(&shaders[_GLASEYE], GLASS_EYE) >= 0) { + float* glass_eye = (float*)0x0000000140CA2D70; + void (FASTCALL * glass_eye_calc)(float* glass_eye) = (void (FASTCALL*)(float* glass_eye))0x00000001405E53D0; + void (FASTCALL * glass_eye_set)(float* glass_eye) = (void (FASTCALL*)(float* glass_eye))0x00000001405E4750; + glass_eye_calc(glass_eye); + glass_eye_set(glass_eye); + } +} + +void FASTCALL shader_bind_tone_map(Shader* shad) { + shader_bind(shad, uniform->arr[U_NPR] == 1 ? TONEMAP_NPR1 : TONEMAP); +} + +int32_t FASTCALL shader_bind(Shader* shad, SubShaderName name) { + int32_t num_sub = shad->num_sub; + int32_t subshader_index = 0; + if (num_sub <= 0) + return -1; + + for (SubShader* i = shad->sub; i->sub_name != name; i++) { + subshader_index++; + if (subshader_index >= num_sub) + return -1; + } + + SubShader* subshader = &shad->sub[subshader_index]; + if (!subshader) + return -1; + + int32_t num_uniform = shad->num_uniform; + int32_t unival_vp_curr = 1; + int32_t unival_fp_curr = 1; + int32_t unival_vp = 0; + int32_t unival_fp = 0; + if (num_uniform > 0) { + int32_t* vp_unival_max = subshader->vp_unival_max; + int32_t* fp_unival_max = subshader->fp_unival_max; + for (size_t i = 0; i < num_uniform; i++) { + int32_t unival = uniform->arr[shad->use_uniform[i]]; + unival_vp += unival_vp_curr * min_def(unival, vp_unival_max[i]); + unival_fp += unival_fp_curr * min_def(unival, fp_unival_max[i]); + unival_vp_curr *= vp_unival_max[i] + 1; + unival_fp_curr *= fp_unival_max[i] + 1; + } + } + + int32_t vp = subshader->vp[unival_vp]; + int32_t fp = subshader->fp[unival_fp]; + if (*current_vp != vp) { + glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vp); + *current_vp = vp; + } + + if (*current_fp != fp) { + glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fp); + *current_fp = fp; + } + + glEnableDLL(GL_VERTEX_PROGRAM_ARB); + glEnableDLL(GL_FRAGMENT_PROGRAM_ARB); + return 0; +} + +void FASTCALL shader_unbind() { + if (current_vp) { + if (*current_vp) + glDisableDLL(GL_VERTEX_PROGRAM_ARB); + *current_vp = 0; + } + + if (current_fp) { + if (*current_fp) + glDisableDLL(GL_FRAGMENT_PROGRAM_ARB); + *current_fp = 0; + } +} + +void FASTCALL shader_load_all_shaders() { + { + farc f; + f.read("F:\\msys64\\ReDIVA\\bin\\rom\\ft_shaders.farc", true, false); + shaders_ft.load(&f, true, "ft", shader_ft_table, shader_ft_table_size, + shader_ft_bind_func_table, shader_ft_bind_func_table_size, + shader_ft_get_index_by_name); + } + return; + + void (FASTCALL * shader_load_program_file)(GLuint program, const char* file_name, bool vertex_program) + = (void (FASTCALL*)(GLuint program, const char* file_name, bool vertex_program))0x00000001405E52D0; + + ShaderTable* shaders_table = &shader_table[_BLINN]; + Shader* shader = &shaders[_BLINN]; + int32_t curr_shader = SHADER_END - 1; + do { + shader->name = shaders_table->name; + shader->name_index = shaders_table->name_index; + shader->num_sub = shaders_table->num_sub; + int32_t num_sub = shaders_table->num_sub; + + const SubShaderTable* sub_table = shaders_table->sub; + SubShader* sub = (SubShader*)_operator_new(sizeof(SubShader) * num_sub); + memset(sub, 0, sizeof(SubShader) * num_sub); + shader->sub = sub; + shader->num_uniform = shaders_table->num_uniform; + shader->use_uniform = shaders_table->use_uniform; + + for (int32_t i = 0; i < num_sub; i++, sub_table++, sub++) { + sub->sub_name = sub_table->sub_name; + sub->vp_unival_max = (int32_t*)sub_table->vp_unival_max; + sub->fp_unival_max = (int32_t*)sub_table->fp_unival_max; + sub->num_vp = sub_table->num_vp; + sub->num_fp = sub_table->num_fp; + sub->vp = (GLuint*)_operator_new(sizeof(GLuint) * sub_table->num_vp); + sub->fp = (GLuint*)_operator_new(sizeof(GLuint) * sub_table->num_fp); + + glGenProgramsARB((GLsizei)sub_table->num_vp, (GLuint*)sub->vp); + glGenProgramsARB((GLsizei)sub_table->num_fp, (GLuint*)sub->fp); + + for (int32_t j = 0; j < sub_table->num_vp; j++) + shader_load_program_file(sub->vp[j], sub_table->vp[j], true); + + for (int32_t j = 0; j < sub_table->num_fp; j++) + shader_load_program_file(sub->fp[j], sub_table->fp[j], false); + } + shader->bind_func = 0; + + ShaderBindFunc* bind_func_table = shader_name_bind_func_table; + ShaderName bind_func_name = _BLINN; + while (shader->name_index != bind_func_name) { + bind_func_name = (++bind_func_table)->name_index; + if (bind_func_table->name_index == SHADER_END) + break; + } + shader->bind_func = bind_func_table->bind_func; + shader++; + shaders_table++; + curr_shader--; + } while (curr_shader); +} + +void FASTCALL shader_free() { + shaders_ft.unload(); + return; + Shader* shader = &shaders[SHADER_FFP]; + for (int32_t i = 0; i < SHADER_END; i++, shader++) { + if (!shader->sub) + continue; + + for (int32_t j = 0; j < shader->num_sub; j++) { + SubShader* sub = shader->sub; + if (sub[j].vp) { + glDeleteProgramsARB(sub[j].num_vp, sub[j].vp); + _operator_delete(sub[j].vp); + sub[j].vp = 0; + } + + if (sub[j].fp) { + glDeleteProgramsARB(sub[j].num_fp, sub[j].fp); + _operator_delete(sub[j].fp); + sub[j].fp = 0; + } + } + + if (shader->sub) { + _operator_delete(shader->sub); + shader->sub = 0; + } + } +} diff --git a/src/DivaGL/shader_table.hpp b/src/DivaGL/shader_table.hpp new file mode 100644 index 0000000..7f27a4f --- /dev/null +++ b/src/DivaGL/shader_table.hpp @@ -0,0 +1,218 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "gl.hpp" +#include "uniform.hpp" + +enum SubShaderName { + SHADER_SUB_FFP = 0, + BLINN_VERT = 1, + BLINN_FRAG = 2, + ITEM_BLINN = 3, + STAGE_BLINN = 4, + SKIN_DEFAULT = 5, + SSS_SKIN = 6, + SSS_FILTER = 7, + HAIR_DEFAULT = 8, + HAIR_ANISO = 9, + HAIR_NPR1 = 10, + CLOTH_DEFAULT = 11, + CLOTH_ANISO = 12, + CLOTH_NPR1 = 13, + TIGHTS = 14, + SKY_DEFAULT = 15, + EYE_BALL = 16, + EYE_LENS = 17, + GLASS_EYE = 18, + MEMBRANE = 19, + SHADOWMAP = 20, + ESM = 21, + ESM_GAUSS = 22, + ESM_FILTER = 23, + LIT_PROJ = 24, + SIMPLE = 25, + SILHOUETTE = 26, + LAMBERT = 27, + CONSTANT = 28, + PEEL = 29, + TONEMAP = 30, + TONEMAP_NPR1 = 31, + REDUCE_TEX = 32, + MAGNIFY = 33, + MLAA = 34, + CONTOUR = 35, + EXPOSURE = 36, + PP_GAUSS = 37, + SUN = 38, + FADE = 39, + WATER01 = 40, + WATER02 = 41, + WATER_RING = 42, + WATER_PARTICLE = 43, + SNOW_PARTICLE = 44, + LEAF_PARTICLE = 45, + STAR = 46, + SNOW_RING = 47, + SNOW_FOOTPRINT = 48, + SNOW_TEX_SPACE_LIGHT = 49, + SNOW_CALC_NORMAL = 50, + FLOOR = 51, + PUDDLE = 52, + SIMPLE_REFLECT = 53, + SIMPLE_REFRACT = 54, + RIPPLE_EMIT = 55, + RAIN = 56, + VOLUME_LIGHT = 57, + FENCE_ALPHA = 58, + RIPPLE = 59, + FOG_PTCL = 60, + PARTICLE = 61, + GLITTER_PARTICLE = 62, + SHOW_VECTOR = 63, + FONT = 64, + MOVIE = 65, + IMGFILTER = 66, + SPRITE = 67, +}; + +enum ShaderName { + SHADER_FFP = 0, + _BLINN = 1, + _ITEM = 2, + _STAGE = 3, + _SKIN = 4, + _SSS_SKIN = 5, + _SSS_FILT = 6, + _HAIR = 7, + _CLOTH = 8, + _TIGHTS = 9, + _SKY = 10, + _EYEBALL = 11, + _EYELENS = 12, + _GLASEYE = 13, + _MEMBRAN = 14, + _SHDMAP = 15, + _ESM = 16, + _ESMGAUSS = 17, + _ESMFILT = 18, + _LITPROJ = 19, + _SIMPLE = 20, + _SIL = 21, + _LAMBERT = 22, + _CONSTANT = 23, + _PEEL = 24, + _TONEMAP = 25, + _REDUCE = 26, + _MAGNIFY = 27, + _MLAA = 28, + _CONTOUR = 29, + _EXPOSURE = 30, + _GAUSS = 31, + _SUN = 32, + _FADE = 33, + _WATER01 = 34, + _WATER02 = 35, + _WATRING = 36, + _W_PTCL = 37, + _SNOW_PT = 38, + _LEAF_PT = 39, + _STAR = 40, + _SNORING = 41, + _SN_FOOT = 42, + _SN_TSL = 43, + _SN_NRM = 44, + _FLOOR = 45, + _PUDDLE = 46, + _S_REFL = 47, + _S_REFR = 48, + _RIPEMIT = 49, + _RAIN = 50, + _VOLLIT = 51, + _FENCE = 52, + _RIPPLE = 53, + _FOGPTCL = 54, + _PARTICL = 55, + _GLITTER_PT = 56, + _SHOWVEC = 57, + _FONT = 58, + _MOVIE = 59, + _IMGFILT = 60, + _SPRITE = 61, + SHADER_END = 62, +}; + +struct SubShaderTable { + SubShaderName sub_name; + int32_t padding; + const int32_t* vp_unival_max; + const int32_t* fp_unival_max; + int32_t num_vp; + int32_t num_fp; + const char** vp; + const char** fp; +}; + +struct ShaderTable { + const char* name; + ShaderName name_index; + int32_t num_sub; + const SubShaderTable* sub; + int32_t num_uniform; + int32_t padding; + uniform_name* use_uniform; +}; + +struct SubShader { + SubShaderName sub_name; + int32_t padding; + int32_t* vp_unival_max; + int32_t* fp_unival_max; + int32_t num_vp; + int32_t num_fp; + GLuint* vp; + GLuint* fp; +}; + +struct Shader; + +typedef void (FASTCALL* PFNSHADERBINDFUNCPROC)(Shader* shad); + +struct Shader { + const char* name; + ShaderName name_index; + int32_t num_sub; + SubShader* sub; + int32_t num_uniform; + int32_t padding; + uniform_name* use_uniform; + PFNSHADERBINDFUNCPROC bind_func; +}; + +struct ShaderBindFunc { + ShaderName name_index; + int32_t padding; + PFNSHADERBINDFUNCPROC bind_func; +}; + +extern Shader* shaders; +extern ShaderTable* shader_table; +extern ShaderBindFunc* shader_name_bind_func_table; +extern int32_t* current_vp; +extern int32_t* current_fp; + +extern void FASTCALL shader_set(ShaderName name); // 0x00000001405E4CE0 +extern void FASTCALL shader_bind_blinn(Shader* shad); // 0x00000001405E4320 +extern void FASTCALL shader_bind_cloth(Shader* shad); // 0x00000001405E4340 +extern void FASTCALL shader_bind_hair(Shader* shad); // 0x00000001405E4370 +extern void FASTCALL shader_bind_membrane(Shader* shas); // 0x00000001405E43A0 +extern void FASTCALL shader_bind_eye_ball(Shader* shad); // 0x00000001405E4530 +extern void FASTCALL shader_bind_tone_map(Shader* shad); // 0x00000001405E4580 +extern int32_t FASTCALL shader_bind(Shader* shad, SubShaderName name); // 0x00000001405E4B50 +extern void FASTCALL shader_unbind(); // 0x00000001405E5660 +extern void FASTCALL shader_load_all_shaders(); // 0x00000001405E4FC0 +extern void FASTCALL shader_free(); // 0x00000001405E4DB0 diff --git a/src/DivaGL/shadow.cpp b/src/DivaGL/shadow.cpp new file mode 100644 index 0000000..bf9bf20 --- /dev/null +++ b/src/DivaGL/shadow.cpp @@ -0,0 +1,12 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "shadow.hpp" + +Shadow** shadow_ptr = (Shadow**)0x000000014CC587B8; + +Shadow* shadow_ptr_get() { + return *shadow_ptr; +} diff --git a/src/DivaGL/shadow.hpp b/src/DivaGL/shadow.hpp new file mode 100644 index 0000000..7ae5594 --- /dev/null +++ b/src/DivaGL/shadow.hpp @@ -0,0 +1,63 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/time.hpp" +#include "../KKdLib/vec.hpp" +#include "render_texture.hpp" +#include "shared.hpp" +#include "types.hpp" + +enum shadow_type_enum { + SHADOW_CHARA = 0, + SHADOW_STAGE, + SHADOW_MAX, +}; + +struct Shadow { + void* __vftable; + RenderTexture render_textures[7]; + RenderTexture* curr_render_textures[3]; + float_t view_region; + float_t range; + vec3 view_point[2]; + vec3 interest[2]; + vec3 field_1A8[2]; + float_t field_1C0[2]; + float_t field_1C8[2]; + prj::vector field_1D0[2]; + int32_t field_200[2]; + float_t field_208; + vec3 direction; + vec3 view_point_shared; + vec3 interest_shared; + mat4 view_mat[2]; + int32_t near_blur; + blur_filter_mode blur_filter; + int32_t far_blur; + int32_t field_2BC; + float_t distance; + float_t field_2C4; + float_t z_near; + float_t z_far; + float_t field_2D0; + float_t field_2D4; + float_t field_2D8; + float_t field_2DC; + float_t field_2E0; + float_t ambient; + bool field_2E8; + int32_t field_2EC; + bool field_2F0[2]; + bool self_shadow; + bool blur_filter_enable[2]; + bool field_2F5; +}; + +static_assert(sizeof(Shadow) == 0x2F8, "\"Shadow\" struct should have a size of 0x2F8"); + +extern Shadow* shadow_ptr_get(); diff --git a/src/DivaGL/shared.cpp b/src/DivaGL/shared.cpp new file mode 100644 index 0000000..030c087 --- /dev/null +++ b/src/DivaGL/shared.cpp @@ -0,0 +1,6 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "shared.hpp" diff --git a/src/DivaGL/shared.hpp b/src/DivaGL/shared.hpp new file mode 100644 index 0000000..67a3f23 --- /dev/null +++ b/src/DivaGL/shared.hpp @@ -0,0 +1,19 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "wrap.hpp" + +enum blur_filter_mode { + BLUR_FILTER_4 = 0, + BLUR_FILTER_9, + BLUR_FILTER_16, + BLUR_FILTER_32, + BLUR_FILTER_MAX, +}; diff --git a/src/DivaGL/sprite.cpp b/src/DivaGL/sprite.cpp new file mode 100644 index 0000000..d1c3b0c --- /dev/null +++ b/src/DivaGL/sprite.cpp @@ -0,0 +1,1133 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "sprite.hpp" +#include "render_context.hpp" +#include "shader_glsl_ft.hpp" +#include + +struct sprite_draw_vertex { + vec3 pos; + vec2 uv[2]; + vec4u8 color; +}; + +struct sprite_draw_param { + bool blend; + GLenum blend_src_rgb; + GLenum blend_src_alpha; + GLenum blend_dst_rgb; + GLenum blend_dst_alpha; + + bool copy_texture; + GLint copy_texture_x; + GLint copy_texture_y; + GLint copy_texture_width; + GLint copy_texture_height; + + int32_t shader; + int32_t tex_0_type; + int32_t tex_1_type; + int32_t combiner; + + GLuint texture[2]; + GLuint sampler; + + GLenum mode; + GLint first; + GLsizei count; +}; + +namespace spr { + struct TexCoord { + struct UV { + float_t u; + float_t v; + }; + + TexCoord::UV uv[4]; + }; + + struct TexParam { + texture* texture; + TexCoord texcoord; + int32_t pad[2]; + }; + + struct SpriteManager { + struct RenderData { + std::vector draw_param_buffer; + std::vector vertex_buffer; + GLuint vao; + GLuint vbo; + size_t vbo_vertex_count; + + RenderData(); + ~RenderData(); + + void Clear(); + void Update(); + }; + + prj::map sets; + prj::list reqlist[4][2][SPR_PRIO_MAX]; + float_t aspect[2]; + prj::pair field_1018[2]; + int32_t index; + mat4 view_projection; + mat4 mat; + resolution_mode resolution_mode; + + void Draw(int32_t index, bool font, texture* tex); + }; + + static_assert(sizeof(spr::SpriteManager) == 0x10C8, "\"spr::SpriteManager\" struct should have a size of 0x10C8"); + + static void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font); + static int32_t calc_sprite_texture_param(SprArgs* args, spr::TexParam* param, vec3* vtx, bool font); + + static void draw_sprite(SprArgs& args, bool font, const mat4& mat, + int32_t x_min, int32_t y_min, int32_t x_max, int32_t y_max, + std::vector& draw_param_buffer, std::vector& vertex_buffer); + static void draw_sprite_begin(); + static void draw_sprite_end(); + static void draw_sprite_scale(spr::SprArgs* args); +} + +size_t(FASTCALL* sprite_manager_get_reqlist_count)(int32_t index) + = (size_t(FASTCALL*)(int32_t index))0x000000014063FA90; + +spr::SpriteManager* sprite_manager = (spr::SpriteManager*)0x000000014CC611C0; + +static mat4 view_projection_aet; + +static spr::SpriteManager::RenderData* sprite_manager_render_data; + +static const GLenum spr_blend_param[6][4] = { + { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE }, + { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE }, + { GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE }, + { GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE }, + { GL_ONE, GL_ZERO, GL_ONE, GL_ZERO }, + { GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE }, +}; + +namespace spr { + void(FASTCALL* put_rgb_cross)(mat4* mat) = (void(FASTCALL*)(mat4 * mat))0x00000001404BC8F0; + + SpriteManager::RenderData::RenderData() { + glGenVertexArrays(1, &vao); + gl_state_bind_vertex_array(vao, true); + + glGenBuffers(1, &vbo); + gl_state_bind_array_buffer(vbo, true); + + vbo_vertex_count = 4096; + + static const GLsizei buffer_size = sizeof(sprite_draw_vertex); + + glBufferData(GL_ARRAY_BUFFER, + (GLsizeiptr)(buffer_size * vbo_vertex_count), 0, GL_DYNAMIC_DRAW); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, pos)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, buffer_size, + (void*)offsetof(sprite_draw_vertex, color)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[0])); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[1])); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + } + + SpriteManager::RenderData::~RenderData() { + if (vbo) { + glDeleteBuffers(1, &vbo); + vbo = 0; + } + + if (vao) { + glDeleteVertexArrays(1, &vao); + vao = 0; + } + } + + void SpriteManager::RenderData::Clear() { + draw_param_buffer.clear(); + vertex_buffer.clear(); + } + + void SpriteManager::RenderData::Update() { + static const GLsizei buffer_size = sizeof(sprite_draw_vertex); + + if (vbo_vertex_count < vertex_buffer.size()) { + while (vbo_vertex_count < vertex_buffer.size()) + vbo_vertex_count *= 2; + + glDeleteBuffers(1, &vbo); + glGenBuffers(1, &vbo); + + gl_state_bind_vertex_array(vao, true); + gl_state_bind_array_buffer(vbo, true); + + glBufferData(GL_ARRAY_BUFFER, + (GLsizeiptr)(buffer_size * vbo_vertex_count), 0, GL_DYNAMIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(buffer_size + * vertex_buffer.size()), vertex_buffer.data()); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, pos)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, buffer_size, + (void*)offsetof(sprite_draw_vertex, color)); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[0])); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, buffer_size, + (void*)offsetof(sprite_draw_vertex, uv[1])); + + gl_state_bind_array_buffer(0); + gl_state_bind_vertex_array(0); + } + else { + gl_state_bind_array_buffer(vbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(buffer_size + * vertex_buffer.size()), vertex_buffer.data()); + gl_state_bind_array_buffer(0); + } + } + + void SpriteManager::Draw(int32_t index, bool font, texture* tex) { + draw_sprite_begin(); + + size_t count = 0; + for (auto& i : reqlist[index]) + for (auto& j : i) + count += j.size(); + + ::resolution_mode mode = res_window_get()->resolution_mode; + if (index == 2 && resolution_mode != RESOLUTION_MODE_MAX) + res_window_get()->resolution_mode = resolution_mode; + + GLint v43[4]; + glGetIntegervDLL(GL_VIEWPORT, v43); + + for (int32_t i = 0; i < 2; i++) { + auto reqlist = this->reqlist[index][i]; + + size_t count = 0; + for (uint32_t j = SPR_PRIO_MAX, k = 0; j; j--, k++) + count += reqlist[k].size(); + + if (!count) + continue; + + int32_t x_min; + int32_t y_min; + int32_t x_max; + int32_t y_max; + if (index == 0 || index == 3) { + float_t sprite_half_width = (float_t)res_window_get()->width * 0.5f; + float_t sprite_half_height = (float_t)res_window_get()->height * 0.5f; + + float_t aet_depth = camera_data->aet_depth; + float_t aet_depth_1 = 1.0f / aet_depth; + + float_t v15a = sprite_half_height * aspect[i] * 0.2f * aet_depth_1; + float_t v15b = sprite_half_height * 0.2f * aet_depth_1; + + mat4 proj; + mat4_frustrum(-v15a, v15a, v15b, -v15b, 0.2, 3000.0, &proj); + + vec3 eye = { sprite_half_width, sprite_half_height, aet_depth }; + vec3 target = { sprite_half_width, sprite_half_height, 0.0f }; + vec3 up = { 0.0f, 1.0f, 0.0f }; + + mat4 view; + mat4_look_at(&eye, &target, &up, &view); + mat4_mul(&view, &proj, &view_projection); + mat4_transpose(&view_projection, &view_projection); + + vec2 min; + vec2 max; + resolution_mode_scale_pos(min, mode, field_1018[i].second.pos, field_1018[i].first); + resolution_mode_scale_pos(max, mode, + field_1018[i].second.pos + field_1018[i].second.size, field_1018[i].first); + x_min = (int32_t)min.x; + y_min = (int32_t)min.y; + x_max = (int32_t)(max.x - min.x); + y_max = (int32_t)(max.y - min.y); + glViewportDLL(x_min, y_min, x_max, y_max); + } + else { + view_projection = view_projection_aet; + + x_min = v43[0]; + y_min = v43[1]; + x_max = v43[2]; + y_max = v43[3]; + } + + float_t v23 = (float_t)x_max * 0.5f; + float_t v24 = (float_t)x_min + v23; + float_t v25 = (float_t)y_max * 0.5f; + float_t v26 = (float_t)y_min + v25; + + mat4 mat = view_projection; + mat.row0.x = v23 * view_projection.row0.x + v24 * view_projection.row0.x; + mat.row0.y = v23 * view_projection.row0.y + v24 * view_projection.row0.y; + mat.row0.z = v23 * view_projection.row0.z + v24 * view_projection.row0.z; + mat.row0.w = v23 * view_projection.row0.w + v24 * view_projection.row0.w; + mat.row1.x = v25 * view_projection.row1.x + v26 * view_projection.row1.x; + mat.row1.y = v25 * view_projection.row1.y + v26 * view_projection.row1.y; + mat.row1.z = v25 * view_projection.row1.z + v26 * view_projection.row1.z; + mat.row1.w = v25 * view_projection.row1.w + v26 * view_projection.row1.w; + this->mat = mat; + + mat4_transpose(&mat, &mat); + + sprite_scene_shader_data shader_data = {}; + shader_data.g_framebuffer_size = { + 1.0f / (float_t)tex->width, + 1.0f / (float_t)tex->height, 0.0f, 0.0f + }; + shader_data.g_transform = view_projection; + rctx->sprite_scene_ubo.WriteMemory(shader_data); + + sprite_manager_render_data->Clear(); + + for (uint32_t j = SPR_PRIO_MAX; j; j--, reqlist++) + for (auto& k : *reqlist) + draw_sprite(k, font, mat, x_min, y_min, x_max, y_max, + sprite_manager_render_data->draw_param_buffer, + sprite_manager_render_data->vertex_buffer); + + static const GLsizei buffer_size = sizeof(sprite_draw_vertex); + + sprite_manager_render_data->Update(); + + rctx->sprite_scene_ubo.Bind(0); + + gl_state_active_bind_texture_2d(7, tex->tex); + + gl_state_bind_vertex_array(sprite_manager_render_data->vao); + for (sprite_draw_param& j : sprite_manager_render_data->draw_param_buffer) { + if (j.blend) { + gl_state_enable_blend(); + gl_state_set_blend_func_separate( + j.blend_src_rgb, j.blend_dst_rgb, + j.blend_src_alpha, j.blend_dst_alpha); + + if (j.copy_texture) { + gl_state_active_texture(7); + glCopyTexSubImage2DDLL(GL_TEXTURE_2D, 0, j.copy_texture_x, j.copy_texture_y, + j.copy_texture_x, j.copy_texture_y, j.copy_texture_width, j.copy_texture_height); + } + } + else + gl_state_disable_blend(); + + if (j.shader == SHADER_FT_SPRITE) { + uniform->arr[U_TEX_0_TYPE] = j.tex_0_type; + uniform->arr[U_TEX_1_TYPE] = j.tex_1_type; + uniform->arr[U_COMBINER] = j.combiner; + } + + if (j.texture[0]) { + gl_state_active_bind_texture_2d(0, j.texture[0]); + gl_state_bind_sampler(0, j.sampler); + + if (j.texture[1]) { + gl_state_active_bind_texture_2d(1, j.texture[1]); + gl_state_bind_sampler(1, j.sampler); + } + } + + shaders_ft.set(j.shader); + shaders_ft.draw_arrays(j.mode, j.first, j.count); + } + gl_state_bind_vertex_array(0); + } + + if (index == 2 && resolution_mode != RESOLUTION_MODE_MAX) + res_window_get()->resolution_mode = mode; + + draw_sprite_end(); + } + + static void calc_sprite_vertex(spr::SprArgs* args, vec3* vtx, mat4* mat, bool font) { + vtx[0].x = 0.0f; + vtx[0].y = 0.0f; + vtx[1].x = 0.0f; + vtx[1].y = args->sprite_size.y; + vtx[1].z = 0.0f; + vtx[2].x = args->sprite_size.x; + vtx[2].y = args->sprite_size.y; + vtx[2].z = 0.0f; + vtx[3].x = args->sprite_size.x; + vtx[3].y = 0.0f; + vtx[3].z = 0.0f; + + mat4 m; + SprAttr attr = args->attr; + if (!(attr & SPR_ATTR_MATRIX)) { + if (attr & SPR_ATTR_CTR) { + if (attr & SPR_ATTR_CTR_LT) + args->center = 0.0f; + else if (attr & SPR_ATTR_CTR_LC) { + args->center.x = 0.0f; + args->center.y = args->sprite_size.y * 0.5f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_LB) { + args->center.x = 0.0f; + args->center.y = args->sprite_size.y; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_CT) { + args->center.x = args->sprite_size.x * 0.5f; + args->center.y = 0.0f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_CC) { + args->center.x = args->sprite_size.x * 0.5f; + args->center.y = args->sprite_size.y * 0.5f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_CB) { + args->center.x = args->sprite_size.x * 0.5f; + args->center.y = args->sprite_size.y; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_RT) { + args->center.x = args->sprite_size.x; + args->center.y = 0.0f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_RC) { + args->center.x = args->sprite_size.x; + args->center.y = args->sprite_size.y * 0.5f; + args->center.z = 0.0f; + } + else if (attr & SPR_ATTR_CTR_RB) { + args->center.x = args->sprite_size.x; + args->center.y = args->sprite_size.y; + args->center.z = 0.0f; + } + } + + if (font) { + if (attr & SPR_ATTR_FLIP_H) { + args->scale.x = -args->scale.x; + args->rot.z = -args->rot.z; + } + if (attr & SPR_ATTR_FLIP_V) { + args->scale.y = -args->scale.y; + args->rot.z = -args->rot.z; + } + } + + if (fabsf(args->skew_angle.x) > 0.000001f) { + float_t skew_width = tanf(args->skew_angle.x) * args->sprite_size.y * 0.5f; + vtx[0].x = vtx[0].x + skew_width; + vtx[1].x = vtx[1].x - skew_width; + vtx[2].x = vtx[2].x - skew_width; + vtx[3].x = vtx[3].x + skew_width; + } + + if (fabsf(args->skew_angle.y) > 0.000001f) { + float_t skew_height = tanf(args->skew_angle.y) * args->sprite_size.x * 0.5f; + vtx[0].y = vtx[0].y - skew_height; + vtx[1].y = vtx[1].y - skew_height; + vtx[2].y = vtx[2].y + skew_height; + vtx[3].y = vtx[3].y + skew_height; + } + + mat4_translate(&args->trans, &m); + if (fabsf(args->rot.x) > 0.000001f) + mat4_mul_rotate_x(&m, args->rot.x, &m); + if (fabsf(args->rot.y) > 0.000001f) + mat4_mul_rotate_y(&m, args->rot.y, &m); + if (fabsf(args->rot.z) > 0.000001f) + mat4_mul_rotate_z(&m, args->rot.z, &m); + mat4_scale_rot(&m, &args->scale, &m); + const vec3 center = -args->center; + mat4_mul_translate(&m, ¢er, &m); + } + else { + mat4_translate(&args->trans, &m); + mat4_scale_rot(&m, &args->scale, &m); + } + + mat4 args_mat; + mat4_transpose(&args->mat, &args_mat); + mat4_mul(&args_mat, &m, &m); + + mat4_transform_point(&m, &vtx[0], &vtx[0]); + mat4_transform_point(&m, &vtx[1], &vtx[1]); + mat4_transform_point(&m, &vtx[2], &vtx[2]); + mat4_transform_point(&m, &vtx[3], &vtx[3]); + + if (mat) + *mat = m; + } + + static int32_t calc_sprite_texture_param(SprArgs* args, spr::TexParam* param, vec3* vtx, bool font) { + int32_t tex_param_count = 0; + texture* tex = args->texture; + while (args) { + param->texture = args->texture; + + float_t width = (float_t)args->texture->width; + float_t height = (float_t)args->texture->height; + + float_t u_scale = 1.0f / width; + float_t v_scale = 1.0f / height; + + if (!args->num_vertex) { + vec2 uv00; + vec2 uv01; + vec2 uv10; + vec2 uv11; + if (args->kind == SPR_KIND_LINE) { + vec3 v42[4]; + mat4 mat; + calc_sprite_vertex(args, v42, &mat, font); + mat4_invert(&mat, &mat); + mat4_transform_point(&mat, &vtx[0], &v42[0]); + mat4_transform_point(&mat, &vtx[1], &v42[1]); + mat4_transform_point(&mat, &vtx[2], &v42[2]); + mat4_transform_point(&mat, &vtx[3], &v42[3]); + uv00 = *(vec2*)&v42[0].x; + uv01 = *(vec2*)&v42[1].x; + uv10 = *(vec2*)&v42[2].x; + uv11 = *(vec2*)&v42[3].x; + } + else { + uv00.x = 0.0f; + uv00.y = 0.0f; + uv01.x = 0.0f; + uv01.y = args->texture_size.y; + uv10.x = args->texture_size.x; + uv10.y = args->texture_size.y; + uv11.x = args->texture_size.x; + uv11.y = 0.0f; + } + + vec2 texture_pos = args->texture_pos; + param->texcoord.uv[0].u = (uv00.x + texture_pos.x) * u_scale; + param->texcoord.uv[0].v = (height - (uv00.y + texture_pos.y)) * v_scale; + param->texcoord.uv[1].u = (uv01.x + texture_pos.x) * u_scale; + param->texcoord.uv[1].v = (height - (uv01.y + texture_pos.y)) * v_scale; + param->texcoord.uv[2].u = (uv10.x + texture_pos.x) * u_scale; + param->texcoord.uv[2].v = (height - (uv10.y + texture_pos.y)) * v_scale; + param->texcoord.uv[3].u = (uv11.x + texture_pos.x) * u_scale; + param->texcoord.uv[3].v = (height - (uv11.y + texture_pos.y)) * v_scale; + } + else if (font) { + SpriteVertex* vtx = args->vertex_array; + for (size_t i = args->num_vertex; i; i--, vtx++) { + vtx->uv.x = vtx->uv.x * u_scale; + vtx->uv.y = (height - vtx->uv.y) * v_scale; + } + } + + args = args->next; + param++; + tex_param_count++; + } + return tex_param_count; + } + + static void draw_sprite(SprArgs& args, bool font, const mat4& mat, + int32_t x_min, int32_t y_min, int32_t x_max, int32_t y_max, + std::vector& draw_param_buffer, std::vector& vertex_buffer) { + if (args.kind == SPR_KIND_LINE) + return; + + // BGRA to RGBA + const vec4u8 color = { args.color.z, args.color.y, args.color.x, args.color.w }; + + if (font) + draw_sprite_scale(&args); + + vec3 vtx[4] = {}; + spr::TexParam tex_param[4] = {}; + + if (args.flags & SprArgs::SPRITE_SIZE) + calc_sprite_vertex(&args, vtx, 0, font); + + int32_t tex_param_count = 0; + if ((args.flags & SprArgs::TEXTURE_POS_SIZE) && args.texture) { + tex_param_count = calc_sprite_texture_param(&args, tex_param, vtx, font); + tex_param_count = min_def(tex_param_count, 2); + } + + mat4 mat_t; + mat4_transpose(&mat, &mat_t); + + draw_param_buffer.push_back({}); + sprite_draw_param& draw_param = draw_param_buffer.back(); + + if (!(args.attr & SPR_ATTR_NOBLEND)) { + const GLenum* blend = spr_blend_param[args.blend]; + draw_param.blend = true; + draw_param.blend_src_rgb = blend[0]; + draw_param.blend_dst_rgb = blend[1]; + draw_param.blend_src_alpha = blend[2]; + draw_param.blend_dst_alpha = blend[3]; + + if (args.blend == 5 && !args.num_vertex && args.kind == SPR_KIND_NORMAL) { + float_t v25 = 0.0f; + float_t v26 = 0.0f; + float_t v27 = 0.0f; + float_t v28 = 0.0f; + for (int32_t i = 0, j = 0; i < 4; i++) { + vec4 v; + *(vec3*)&v = vtx[i]; + v.w = 1.0f; + + float_t v31 = vec4::dot(mat_t.row3, v); + if (v31 * v31 <= 0.0001f) + continue; + + float_t v33 = vec4::dot(mat_t.row0, v) * (1.0f / v31); + float_t v34 = vec4::dot(mat_t.row1, v) * (1.0f / v31); + if (j) { + if (v25 > v33) + v25 = v33; + else if (v27 < v33) + v27 = v33; + + if (v26 > v34) + v26 = v34; + else if (v28 < v34) + v28 = v34; + } + else { + v25 = v33; + v27 = v33; + v26 = v34; + v28 = v34; + } + j++; + } + + int32_t v36 = (int32_t)v27 + 1; + int32_t v37 = (int32_t)v28 + 1; + int32_t v38 = (int32_t)v25 - 1; + int32_t v39 = (int32_t)v26 - 1; + + v36 = clamp_def(v36, x_min, x_min + x_max - 1); + v37 = clamp_def(v37, y_min, y_min + y_max - 1); + v38 = clamp_def(v38, x_min, x_min + x_max - 1); + v39 = clamp_def(v39, y_min, y_min + y_max - 1); + + int32_t v42 = v36 - v38 + 1; + int32_t v43 = v37 - v39 + 1; + if (v42 * v43 > 0) { + draw_param.copy_texture = true; + draw_param.copy_texture_x = v38; + draw_param.copy_texture_y = v39; + draw_param.copy_texture_width = v42; + draw_param.copy_texture_height = v43; + } + } + } + + draw_param.shader = args.shader; + if (draw_param.shader == SHADER_FT_FFP) { + draw_param.shader = SHADER_FT_SPRITE; + draw_param.tex_0_type = 0; + draw_param.tex_1_type = 0; + + if (tex_param_count == 1 || tex_param_count == 2) { + if (tex_param[0].texture->internal_format == GL_COMPRESSED_RED_RGTC1_EXT) + draw_param.tex_0_type = 3; + else if (tex_param[0].texture->internal_format == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) + draw_param.tex_0_type = 2; + else + draw_param.tex_0_type = 1; + + if (tex_param_count == 2) { + if (tex_param[1].texture->internal_format == GL_COMPRESSED_RED_RGTC1_EXT) + draw_param.tex_1_type = 3; + else if (tex_param[1].texture->internal_format == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) + draw_param.tex_1_type = 2; + else + draw_param.tex_1_type = 1; + } + } + + if (args.attr & SPR_ATTR_NOBLEND) + draw_param.combiner = 0; + else if (args.blend != 5) + draw_param.combiner = args.blend == 3 ? 1 : 0; + else + draw_param.combiner = 2; + + } + + switch (tex_param_count) { + case 0: + switch (args.kind) { + case SPR_KIND_LINES: { + if (vtx[0] == 0.0f && vtx[2] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[2]; + spr_vtx[1].color = color; + + draw_param.mode = GL_LINES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 2; + + vertex_buffer.reserve(2); + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + } break; + case SPR_KIND_RECT: { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].color = color; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 6; + + vertex_buffer.reserve(6); + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } break; + case SPR_KIND_MULTI: { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].color = color; + + draw_param.mode = GL_LINE_LOOP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 4; + + vertex_buffer.reserve(4); + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + vertex_buffer.push_back(spr_vtx[2]); + vertex_buffer.push_back(spr_vtx[3]); + } break; + case SPR_KIND_ARROW_B: { + sprite_draw_vertex spr_vtx[2] = {}; + spr_vtx[0].color = color; + spr_vtx[1].color = color; + + if (args.num_vertex) { + size_t vertex_buffer_size = vertex_buffer.size(); + vertex_buffer.reserve(args.num_vertex / 2 * 2); + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex / 2; i; i--, vtx += 2) { + if (vtx[0].pos == 0.0f && vtx[1].pos == 0.0f) + continue; + + spr_vtx[0].pos = vtx[0].pos; + spr_vtx[1].pos = vtx[1].pos; + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + } + + if (vertex_buffer_size == vertex_buffer.size()) { + draw_param_buffer.pop_back(); + return; + } + } + else { + if (vtx[0] == 0.0f && vtx[2] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + spr_vtx[0].pos = vtx[0]; + spr_vtx[1].pos = vtx[2]; + + vertex_buffer.reserve(2); + vertex_buffer.push_back(spr_vtx[0]); + vertex_buffer.push_back(spr_vtx[1]); + } + } break; + case SPR_KIND_ARROW_AB: { + if (!args.num_vertex) { + draw_param_buffer.pop_back(); + return; + } + + draw_param.mode = GL_LINE_STRIP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)args.num_vertex; + + vertex_buffer.reserve(args.num_vertex); + + sprite_draw_vertex spr_vtx = {}; + spr_vtx.color = color; + + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex; i; i--, vtx++) { + spr_vtx.pos = vtx->pos; + vertex_buffer.push_back(spr_vtx); + } + } break; + case SPR_KIND_TRIANGLE: { + if (!args.num_vertex) { + draw_param_buffer.pop_back(); + return; + } + + draw_param.mode = GL_TRIANGLE_STRIP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)args.num_vertex; + + vertex_buffer.reserve(args.num_vertex); + + sprite_draw_vertex spr_vtx = {}; + spr_vtx.color = color; + + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex; i; i--, vtx++) { + spr_vtx.pos = vtx->pos; + vertex_buffer.push_back(spr_vtx); + } + } break; + } + break; + case 1: + draw_param.texture[0] = tex_param[0].texture->tex; + draw_param.sampler = rctx->sprite_samplers[0]; + + if (args.num_vertex) { + if (args.kind == SPR_KIND_TRIANGLE) + draw_param.sampler = rctx->sprite_samplers[1]; + + if (args.kind == SPR_KIND_TRIANGLE) { + draw_param.mode = GL_TRIANGLE_STRIP; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)args.num_vertex; + + vertex_buffer.reserve(args.num_vertex); + + sprite_draw_vertex spr_vtx = {}; + SpriteVertex* vtx = args.vertex_array; + for (size_t i = args.num_vertex; i; i--, vtx++) { + spr_vtx.pos = vtx->pos; + spr_vtx.uv[0] = vtx->uv; + spr_vtx.color = vtx->color; + vertex_buffer.push_back(spr_vtx); + } + } + else { + size_t num_vertex = args.num_vertex / 4 * 6; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = (GLsizei)num_vertex; + + size_t vertex_buffer_size = vertex_buffer.size(); + vertex_buffer.reserve(num_vertex); + + sprite_draw_vertex spr_vtx[4] = {}; + SpriteVertex* vtx = args.vertex_array; + for (size_t i = num_vertex / 6; i; i--, vtx += 4) { + if (vtx[0].pos == 0.0f && vtx[1].pos == 0.0f + && vtx[2].pos == 0.0f && vtx[3].pos == 0.0f) + continue; + + spr_vtx[0].pos = vtx[0].pos; + spr_vtx[0].uv[0] = vtx[0].uv; + spr_vtx[0].color = vtx[0].color; + spr_vtx[1].pos = vtx[1].pos; + spr_vtx[1].uv[0] = vtx[1].uv; + spr_vtx[1].color = vtx[1].color; + spr_vtx[2].pos = vtx[2].pos; + spr_vtx[2].uv[0] = vtx[2].uv; + spr_vtx[2].color = vtx[2].color; + spr_vtx[3].pos = vtx[3].pos; + spr_vtx[3].uv[0] = vtx[3].uv; + spr_vtx[3].color = vtx[3].color; + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } + + if (vertex_buffer_size == vertex_buffer.size()) { + draw_param_buffer.pop_back(); + return; + } + } + } + else { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].uv[0].x = tex_param[0].texcoord.uv[0].u; + spr_vtx[0].uv[0].y = tex_param[0].texcoord.uv[0].v; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].uv[0].x = tex_param[0].texcoord.uv[1].u; + spr_vtx[1].uv[0].y = tex_param[0].texcoord.uv[1].v; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].uv[0].x = tex_param[0].texcoord.uv[2].u; + spr_vtx[2].uv[0].y = tex_param[0].texcoord.uv[2].v; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].uv[0].x = tex_param[0].texcoord.uv[3].u; + spr_vtx[3].uv[0].y = tex_param[0].texcoord.uv[3].v; + spr_vtx[3].color = color; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 6; + + vertex_buffer.reserve(6); + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } + break; + case 2: { + if (vtx[0] == 0.0f && vtx[1] == 0.0f && vtx[2] == 0.0f && vtx[3] == 0.0f) { + draw_param_buffer.pop_back(); + return; + } + + draw_param.texture[0] = tex_param[0].texture->tex; + draw_param.texture[1] = tex_param[1].texture->tex; + draw_param.sampler = rctx->sprite_samplers[2]; + + sprite_draw_vertex spr_vtx[4] = {}; + spr_vtx[0].pos = vtx[0]; + spr_vtx[0].uv[0].x = tex_param[0].texcoord.uv[0].u; + spr_vtx[0].uv[0].y = tex_param[0].texcoord.uv[0].v; + spr_vtx[0].uv[1].x = tex_param[1].texcoord.uv[0].u; + spr_vtx[0].uv[1].y = tex_param[1].texcoord.uv[0].v; + spr_vtx[0].color = color; + + spr_vtx[1].pos = vtx[1]; + spr_vtx[1].uv[0].x = tex_param[0].texcoord.uv[1].u; + spr_vtx[1].uv[0].y = tex_param[0].texcoord.uv[1].v; + spr_vtx[1].uv[1].x = tex_param[1].texcoord.uv[1].u; + spr_vtx[1].uv[1].y = tex_param[1].texcoord.uv[1].v; + spr_vtx[1].color = color; + + spr_vtx[2].pos = vtx[2]; + spr_vtx[2].uv[0].x = tex_param[0].texcoord.uv[2].u; + spr_vtx[2].uv[0].y = tex_param[0].texcoord.uv[2].v; + spr_vtx[2].uv[1].x = tex_param[1].texcoord.uv[2].u; + spr_vtx[2].uv[1].y = tex_param[1].texcoord.uv[2].v; + spr_vtx[2].color = color; + + spr_vtx[3].pos = vtx[3]; + spr_vtx[3].uv[0].x = tex_param[0].texcoord.uv[3].u; + spr_vtx[3].uv[0].y = tex_param[0].texcoord.uv[3].v; + spr_vtx[3].uv[1].x = tex_param[1].texcoord.uv[3].u; + spr_vtx[3].uv[1].y = tex_param[1].texcoord.uv[3].v; + spr_vtx[3].color = color; + + draw_param.mode = GL_TRIANGLES; + draw_param.first = (GLint)vertex_buffer.size(); + draw_param.count = 6; + + vertex_buffer.reserve(6); + vertex_buffer.push_back(spr_vtx[1]); // LT + vertex_buffer.push_back(spr_vtx[0]); // LB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[3]); // RB + vertex_buffer.push_back(spr_vtx[2]); // RT + vertex_buffer.push_back(spr_vtx[0]); // LB + } break; + } + + if (draw_param_buffer.size() >= 2) { + sprite_draw_param& draw_param_2 = draw_param_buffer.data()[draw_param_buffer.size() - 2]; + sprite_draw_param& draw_param_1 = draw_param_buffer.data()[draw_param_buffer.size() - 1]; + + if ((args.index == -1 || args.index == 0 || args.index == 3) + && draw_param_2.mode == draw_param_1.mode + && (draw_param_2.first + draw_param_2.count) == draw_param_1.first + && draw_param_2.blend == draw_param_1.blend + && draw_param_2.blend_src_rgb == draw_param_1.blend_src_rgb + && draw_param_2.blend_src_alpha == draw_param_1.blend_src_alpha + && draw_param_2.blend_dst_rgb == draw_param_1.blend_dst_rgb + && draw_param_2.blend_dst_alpha == draw_param_1.blend_dst_alpha + && !draw_param_2.copy_texture && !draw_param_1.copy_texture + && draw_param_2.shader == draw_param_1.shader + && draw_param_2.tex_0_type == draw_param_1.tex_0_type + && draw_param_2.tex_1_type == draw_param_1.tex_1_type + && draw_param_2.combiner == draw_param_1.combiner + && draw_param_2.texture[0] == draw_param_1.texture[0] + && draw_param_2.texture[1] == draw_param_1.texture[1] + && draw_param_2.sampler == draw_param_1.sampler) { + draw_param_2.count += draw_param_1.count; + draw_param_buffer.pop_back(); + } + } + } + + static void draw_sprite_begin() { + gl_state_disable_blend(true); + gl_state_active_bind_texture_2d(0, rctx->empty_texture_2d, true); + gl_state_bind_sampler(0, 0, true); + gl_state_active_bind_texture_2d(1, rctx->empty_texture_2d, true); + gl_state_bind_sampler(1, 0, true); + gl_state_bind_sampler(7, 0, true); + gl_state_set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO, true); + gl_state_bind_vertex_array(0, true); + gl_state_bind_uniform_buffer_base(0, 0, true); + } + + static void draw_sprite_end() { + gl_state_disable_blend(); + gl_state_active_bind_texture_2d(0, 0); + gl_state_bind_sampler(0, 0); + gl_state_active_bind_texture_2d(1, 0); + gl_state_bind_sampler(1, 0); + gl_state_active_bind_texture_2d(7, 0); + gl_state_bind_sampler(7, 0); + gl_state_set_blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); + shaders_ft.set(-1); + } + + static void draw_sprite_scale(spr::SprArgs* args) { + int32_t index = args->index; + resolution_mode mode = res_window_get()->resolution_mode; + while (args) { + resolution_mode_scale_data data(args->resolution_mode_screen, mode); + if (args->resolution_mode_screen != RESOLUTION_MODE_MAX + && args->resolution_mode_screen != mode && (index == 0 || index == 3)) { + float_t scale_x = data.scale.x; + float_t scale_y = data.scale.y; + float_t src_res_x = data.src_res.x; + float_t src_res_y = data.src_res.y; + float_t dst_res_x = data.dst_res.x; + float_t dst_res_y = data.dst_res.y; + args->trans.x = (args->trans.x - src_res_x) * scale_x + src_res_x; + args->trans.y = (args->trans.y - src_res_y) * scale_y + src_res_y; + args->trans.z = args->trans.z * scale_y; + + SpriteVertex* vtx = args->vertex_array; + for (size_t i = args->num_vertex; i; i--, vtx++) { + vtx->pos.x = (vtx->pos.x - src_res_x) * scale_x + dst_res_x; + vtx->pos.y = (vtx->pos.y - src_res_y) * scale_y + dst_res_y; + } + } + + if (args->resolution_mode_sprite != RESOLUTION_MODE_MAX) { + vec2 scale = resolution_mode_get_scale(mode, args->resolution_mode_sprite); + args->scale.x = scale.x * args->scale.x; + args->scale.y = scale.y * args->scale.y; + } + args = args->next; + } + } +} + + +void sprite_manager_init() { + if (!sprite_manager_render_data) + sprite_manager_render_data = new spr::SpriteManager::RenderData; +} + +void sprite_manager_draw(int32_t index, bool font, texture* tex) { + sprite_manager->Draw(index, font, tex); +} + +void sprite_manager_set_res(double_t aspect, int32_t width, int32_t height) { + sprite_manager->aspect[0] = (float_t)aspect; + sprite_manager->field_1018[0].second = { { 0.0f, 0.0f }, { (float_t)width, (float_t)height } }; + sprite_manager->aspect[1] = (float_t)aspect; + sprite_manager->field_1018[1].second = { { 0.0f, 0.0f }, { (float_t)width, (float_t)height } }; +} + +void sprite_manager_set_view_projection(bool aet_3d) { + view_projection_aet = aet_3d + ? camera_data->view_projection_aet_3d_matrix + : camera_data->view_projection_aet_2d_matrix; +} + +void sprite_manager_free() { + if (sprite_manager_render_data) { + delete sprite_manager_render_data; + sprite_manager_render_data = 0; + } +} + +HOOK(void, FASTCALL, sprite_manager_draw, 0x000000014063F870, int32_t index, bool font, texture* tex) { + sprite_manager_draw(index, font, tex); +} + + +HOOK(void, FASTCALL, sprite_manager_set_view_projection, 0x00000001401F9590, bool aet_3d) { + sprite_manager_set_view_projection(aet_3d); +} + +void sprite_patch() { + INSTALL_HOOK(sprite_manager_draw); + INSTALL_HOOK(sprite_manager_set_view_projection); +} diff --git a/src/DivaGL/sprite.hpp b/src/DivaGL/sprite.hpp new file mode 100644 index 0000000..6ca135e --- /dev/null +++ b/src/DivaGL/sprite.hpp @@ -0,0 +1,201 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "gl_state.hpp" +#include "render_context.hpp" +#include "resolution_mode.hpp" +#include "texture.hpp" +#include "types.hpp" + +struct rectangle { + vec2 pos; + vec2 size; +}; + +struct spr_info { + uint16_t index; + uint16_t set_index; +}; + +struct SpriteHeaderFile { + uint32_t flag; + uint32_t texofs; + int32_t num_of_texture; + int32_t num_of_sprite; + uint32_t sprinfo_offset; + uint32_t texname_offset; + uint32_t sprname_offset; + uint32_t sprdata_offset; +}; + +struct SpriteHeader { + uint32_t flag; + uint32_t texofs; + int32_t num_of_texture; + int32_t num_of_sprite; + spr::SprInfo* sprinfo; + const char** texname; + const char** sprname; + SpriteData* sprdata; +}; + +struct shared_ptr_prj__stack_allocator { + void* ptr; + void* ref; +}; + +struct SprSet { + void* vftable; + int32_t flag; + int32_t index; + SpriteHeaderFile* header_file; + SpriteHeader* header; + texture** textures; + int32_t load_count; + void* file_handler; + bool ready; + shared_ptr_prj__stack_allocator alloc_handler; + prj::string file; +}; + +namespace spr { + enum SprAttr : uint32_t { + SPR_ATTR_FLIP_H = 0x00010000, + SPR_ATTR_FLIP_V = 0x00020000, + SPR_ATTR_CTR_LT = 0x00040000, + SPR_ATTR_CTR_CT = 0x00080000, + SPR_ATTR_CTR_RT = 0x00100000, + SPR_ATTR_CTR_LC = 0x00200000, + SPR_ATTR_CTR_CC = 0x00400000, + SPR_ATTR_CTR_RC = 0x00800000, + SPR_ATTR_CTR_LB = 0x01000000, + SPR_ATTR_CTR_CB = 0x02000000, + SPR_ATTR_CTR_RB = 0x04000000, + SPR_ATTR_MATRIX = 0x08000000, + SPR_ATTR_10000000 = 0x10000000, + SPR_ATTR_NOBLEND = 0x20000000, + + SPR_ATTR_CTR = 0x07FC0000, + }; + + enum SprKind { + SPR_KIND_NORMAL = 0, + SPR_KIND_LINE, + SPR_KIND_LINES, + SPR_KIND_RECT, + SPR_KIND_MULTI, + SPR_KIND_ARROW_A, + SPR_KIND_ARROW_B, + SPR_KIND_ARROW_AB, + SPR_KIND_TRIANGLE, + SPR_KIND_CIRCLE, + }; + + enum SprPrio { + SPR_PRIO_00 = 0, + SPR_PRIO_01, + SPR_PRIO_02, + SPR_PRIO_03, + SPR_PRIO_04, + SPR_PRIO_05, + SPR_PRIO_06, + SPR_PRIO_07, + SPR_PRIO_08, + SPR_PRIO_09, + SPR_PRIO_10, + SPR_PRIO_11, + SPR_PRIO_12, + SPR_PRIO_13, + SPR_PRIO_14, + SPR_PRIO_15, + SPR_PRIO_16, + SPR_PRIO_17, + SPR_PRIO_18, + SPR_PRIO_19, + SPR_PRIO_20, + SPR_PRIO_21, + SPR_PRIO_22, + SPR_PRIO_23, + SPR_PRIO_24, + SPR_PRIO_25, + SPR_PRIO_26, + SPR_PRIO_27, + SPR_PRIO_28, + SPR_PRIO_29, + SPR_PRIO_30, + SPR_PRIO_31, + SPR_PRIO_MAX, + }; + + struct SpriteVertex { + vec3 pos; + vec2 uv; + vec4u8 color; + }; + + struct SprArgs { + enum Flags : uint32_t { + SPRITE_SIZE = 0x01, + TEXTURE_POS_SIZE = 0x02, + }; + + union IDUnion { + int32_t index; + uint32_t id; + spr_info info; + + IDUnion() { + index = -1; + id = -1; + info = {}; + } + }; + + SprKind kind; + IDUnion id; + vec4u8 color; + SprAttr attr; + int32_t blend; + int32_t index; + int32_t layer; + SprPrio prio; + resolution_mode resolution_mode_screen; + resolution_mode resolution_mode_sprite; + vec3 center; + vec3 trans; + vec3 scale; + vec3 rot; + vec2 skew_angle; + mat4 mat; + texture* texture; + int32_t shader; + SpriteVertex* vertex_array; + size_t num_vertex; + Flags flags; + vec2 sprite_size; + int32_t field_CC; + vec2 texture_pos; + vec2 texture_size; + spr::SprArgs* next; + }; + + + extern void(FASTCALL* put_rgb_cross)(mat4* mat); +} + +extern size_t(FASTCALL* sprite_manager_get_reqlist_count)(int32_t index); + +extern void sprite_manager_init(); +extern void sprite_manager_draw(int32_t index, bool font, texture* tex); +extern void sprite_manager_set_res(double_t aspect, int32_t width, int32_t height); +extern void sprite_manager_set_view_projection(bool aet_3d); +extern void sprite_manager_free(); + +extern void sprite_patch(); diff --git a/src/DivaGL/stage.cpp b/src/DivaGL/stage.cpp new file mode 100644 index 0000000..a38f185 --- /dev/null +++ b/src/DivaGL/stage.cpp @@ -0,0 +1,206 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "stage.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "object.hpp" +#include "render_context.hpp" +#include + +enum stage_data_flags { + STAGE_DATA_FLAG_1 = 0x01, + STAGE_DATA_LIGHT_CHARA_AMBIENT = 0x02, + STAGE_DATA_FLAG_4 = 0x04, + STAGE_DATA_FLAG_8 = 0x08, +}; + +struct stage_data_reflect { + reflect_refract_resolution_mode mode; + int32_t blur_num; + blur_filter_mode blur_filter; +}; + +static_assert(sizeof(stage_data_reflect) == 0x0C, "\"stage_data_reflect\" struct should have a size of 0x0C"); + +struct stage_data_refract { + reflect_refract_resolution_mode mode; +}; + +static_assert(sizeof(stage_data_refract) == 0x04, "\"stage_data_refract\" struct should have a size of 0x04"); + +struct stage_data { + const char* name; + const char* auth_3d_name; + int32_t object_set_id; + object_info object_ground; + object_info object_ring; + object_info object_sky; + object_info object_shadow; + object_info object_reflect; + object_info object_refract; + uint32_t lens_flare_texture; + uint32_t lens_shaft_texture; + uint32_t lens_ghost_texture; + float_t lens_shaft_inv_scale; + uint32_t field_3C; + uint32_t render_texture; + uint32_t movie_texture; + const char* collision_file_path; + stage_data_reflect_type reflect_type; + bool refract; + stage_data_reflect* reflect_data; + stage_data_refract* refract_data; + stage_data_flags flags; + float_t ring_rectangle_x; + float_t ring_rectangle_y; + float_t ring_rectangle_width; + float_t ring_rectangle_height; + float_t ring_height; + float_t ring_out_height; + int32_t field_84; +}; + +static_assert(sizeof(stage_data) == 0x88, "\"stage_data\" struct should have a size of 0x88"); + +struct stage { + int32_t index; + uint16_t counter; + int32_t state; + stage_data* stage_data; + bool stage_display; + bool lens_flare; + bool ground; + bool ring; + bool sky; + bool auth_3d_loaded; + mat4 mat; + float_t rot_y; + uint32_t obj_set; +}; + +static_assert(sizeof(stage) == 0x68, "\"stage\" struct should have a size of 0x68"); + + +static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* sphere, mat4* mat); +static bool object_bounding_sphere_check_visibility_shadow_chara(obj_bounding_sphere* sphere); +static bool object_bounding_sphere_check_visibility_shadow_stage(obj_bounding_sphere* sphere); + +HOOK(void, FASTCALL, stage__disp, 0x0000000140649560, stage* s) { + if (s->state != 6 || !s->stage_display) + return; + + mdl::DispManager& disp_manager = *::disp_manager; + + mat4 mat; + mat4_rotate_y(s->rot_y, &mat); + + if (s->stage_data->object_ground.not_null() && s->ground) + disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_ground); + + if (s->stage_data->object_ring.not_null() && s->ring) + disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_ring); + + if (s->stage_data->object_reflect.not_null()) { + disp_manager.set_obj_flags((mdl::ObjFlags)(mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFLECT)); + disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_reflect); + disp_manager.set_obj_flags(); + } + + if (s->stage_data->object_refract.not_null()) { + disp_manager.set_obj_flags((mdl::ObjFlags)(mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_REFRACT)); + disp_manager.entry_obj_by_object_info(&mat, s->stage_data->object_refract); + disp_manager.set_obj_flags(); + } + + if (s->stage_data->object_sky.not_null() && s->sky) { + mat4 t = s->mat; + mat4_mul(&t, &mat, &t); + disp_manager.entry_obj_by_object_info(&t, s->stage_data->object_sky); + } + + if (s->stage_data->lens_flare_texture != -1 && s->lens_flare) { + int32_t object_set_id = s->stage_data->object_set_id; + rndr::Render* rend = render; + rend->lens_flare_texture = obj_database_get_obj_set_texture( + object_set_id, s->stage_data->lens_flare_texture); + if (rend->lens_flare_texture) { + rend->lens_shaft_texture = obj_database_get_obj_set_texture( + object_set_id, s->stage_data->lens_shaft_texture); + rend->lens_ghost_texture = obj_database_get_obj_set_texture( + object_set_id, s->stage_data->lens_ghost_texture); + rend->lens_ghost_count = 16; + rend->lens_shaft_inv_scale = s->stage_data->lens_shaft_inv_scale; + } + } +} + +static void stage__disp_shadow_object(object_info object, mat4* mat) { + mdl::DispManager& disp_manager = *::disp_manager; + + for (int32_t i = SHADOW_CHARA; i < SHADOW_MAX; i++) { + disp_manager.set_shadow_type((shadow_type_enum)i); + disp_manager.set_culling_finc(i == SHADOW_CHARA + ? object_bounding_sphere_check_visibility_shadow_chara + : object_bounding_sphere_check_visibility_shadow_stage); + disp_manager.set_obj_flags((mdl::ObjFlags)(mdl::OBJ_NO_TRANSLUCENCY | mdl::OBJ_SHADOW_OBJECT)); + disp_manager.entry_obj_by_object_info(mat, object); + } + + disp_manager.set_obj_flags(); + disp_manager.set_culling_finc(); + disp_manager.set_shadow_type(); +} + + +HOOK(void, FASTCALL, stage__disp_shadow, 0x00000001406497C0, stage* s) { + if (s->state != 6 || !s->stage_display) + return; + + mat4 mat; + mat4_rotate_y(s->rot_y, &mat); + if (s->stage_data->object_shadow.not_null()) + stage__disp_shadow_object(s->stage_data->object_shadow, &mat); +} + +void stage_patch() { + INSTALL_HOOK(stage__disp); + INSTALL_HOOK(stage__disp_shadow); +} + +static bool object_bounding_sphere_check_visibility_shadow(obj_bounding_sphere* sphere, mat4* mat) { + mat4 view_matrix; + mat4_transpose(&camera_data->view_matrix, &view_matrix); + + vec3 center; + mat4_transform_point(mat, &sphere->center, ¢er); + mat4_transform_point(&view_matrix, ¢er, ¢er); + float_t radius = sphere->radius; + + Shadow* shad = shadow_ptr_get(); + float_t v9 = shad->view_region * shad->range; + if ((center.x + radius) < -v9 + || (center.x - radius) > v9 + || (center.y + radius) < -v9 + || (center.y - radius) > v9 + || (center.z - radius) > -shad->z_near + || (center.z + radius) < -shad->z_far) + return false; + return true; +} + +static bool object_bounding_sphere_check_visibility_shadow_chara(obj_bounding_sphere* sphere) { + mat4 mat; + Shadow* shad = shadow_ptr_get(); + mat4_look_at(&shad->view_point[0], &shad->interest[0], &mat); + return object_bounding_sphere_check_visibility_shadow(sphere, &mat); +} + +static bool object_bounding_sphere_check_visibility_shadow_stage(obj_bounding_sphere* sphere) { + mat4 mat; + Shadow* shad = shadow_ptr_get(); + mat4_look_at(&shad->view_point[1], &shad->interest[1], &mat); + return object_bounding_sphere_check_visibility_shadow(sphere, &mat); +} diff --git a/src/DivaGL/stage.hpp b/src/DivaGL/stage.hpp new file mode 100644 index 0000000..25f44aa --- /dev/null +++ b/src/DivaGL/stage.hpp @@ -0,0 +1,10 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" + +extern void stage_patch(); diff --git a/src/DivaGL/stage_param.cpp b/src/DivaGL/stage_param.cpp new file mode 100644 index 0000000..eee9d05 --- /dev/null +++ b/src/DivaGL/stage_param.cpp @@ -0,0 +1,8 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "stage_param.hpp" + +stage_param_data_litproj** stage_param_data_litproj_current = (stage_param_data_litproj**)0x0000000141194D80; diff --git a/src/DivaGL/stage_param.hpp b/src/DivaGL/stage_param.hpp new file mode 100644 index 0000000..c38b9ee --- /dev/null +++ b/src/DivaGL/stage_param.hpp @@ -0,0 +1,172 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/vec.hpp" +#include "object.hpp" +#include "types.hpp" + +/*struct stage_param_data_coli { + int32_t pv_id; + prj::map stage_ring_data; + prj::map mhd_id_ring_data; + prj::map stage_wind_file; +}; + +static_assert(sizeof(stage_param_data_coli) == 0x38, "\"stage_param_data_coli\" struct should have a size of 0x38");*/ + +struct stage_param_data_fog_ring { + int32_t num_ptcls; + float_t ring_size; + vec3 wind_dir; + int32_t tex_id; + vec4 color; + float_t ptcl_size; + float_t density; + float_t density_offset; +}; + +static_assert(sizeof(stage_param_data_fog_ring) == 0x34, "\"stage_param_data_fog_ring\" struct should have a size of 0x34"); + +struct stage_param_data_leaf_lie_plane_xz { + float_t min_x; + float_t max_x; + float_t min_z; + float_t max_z; +}; + +static_assert(sizeof(stage_param_data_leaf_lie_plane_xz) == 0x10, "\"stage_param_data_fog_ring\" struct should have a size of 0x10"); + +struct stage_param_data_leaf { + int32_t tex_id; + vec4 color; + float_t psize; + int32_t num_initial_ptcls; + float_t frame_speed_coef; + float_t emit_interval; + vec3 wind; + vec3 range; + vec3 offset; + stage_param_data_leaf_lie_plane_xz lie_plane_xz; + bool split_tex; +}; + +static_assert(sizeof(stage_param_data_leaf) == 0x5C, "\"stage_param_data_leaf\" struct should have a size of 0x5C"); + +struct stage_param_data_litproj { + int32_t tex_id; +}; + +static_assert(sizeof(stage_param_data_litproj) == 0x04, "\"stage_param_data_litproj\" struct should have a size of 0x04"); + +struct stage_param_data_rain { + int32_t tex_id; + int32_t num_rain; + vec4 color; + vec3 velocity; + vec3 vel_range; + vec2 psize; + vec3 range; + vec3 offset; +}; + +static_assert(sizeof(stage_param_data_rain) == 0x50, "\"stage_param_data_rain\" struct should have a size of 0x50"); + +struct stage_param_data_ripple { + size_t rain_ripple_num; + float_t rain_ripple_min_value; + float_t rain_ripple_max_value; + float_t ground_y; + float_t emit_pos_scale; + float_t emit_pos_ofs_x; + float_t emit_pos_ofs_z; + float_t wake_attn; + float_t speed; + int32_t ripple_tex_id; + bool use_float_ripplemap; + float_t rob_emitter_size; + vec3* emitter_list; + size_t emitter_num; + float_t emitter_size; +}; + +static_assert(sizeof(stage_param_data_ripple) == 0x50, "\"stage_param_data_ripple\" struct should have a size of 0x50"); + +struct stage_param_data_snow_colli_ground { + float_t min_x; + float_t max_x; + float_t min_z; + float_t max_z; + float_t y; +}; + +static_assert(sizeof(stage_param_data_snow_colli_ground) == 0x14, "\"stage_param_data_snow_colli_ground\" struct should have a size of 0x14"); + +struct stage_param_data_snow { + int32_t tex_id; + int32_t num_snow; + int32_t num_snow_gpu; + vec4 color; + vec3 velocity; + vec3 vel_range; + vec3 range; + vec3 range_gpu; + vec3 offset; + vec3 offset_gpu; + stage_param_data_snow_colli_ground colli_ground; +}; + +static_assert(sizeof(stage_param_data_snow) == 0x78, "\"stage_param_data_snow\" struct should have a size of 0x78"); + +struct stage_param_data_splash { + int32_t splash_tex_id; + object_info splash_obj_id; + float_t particle_size; + int32_t emit_num; + float_t emission_ratio_attn; + float_t emission_velocity_scale; + float_t ripple_emission; + vec4 color; + bool in_water; + bool blink; +}; + +static_assert(sizeof(stage_param_data_splash) == 0x30, "\"stage_param_data_splash\" struct should have a size of 0x30"); + +struct stage_param_data_star_utc { + int32_t year; + int32_t month; + int32_t day; + int32_t hour; + int32_t minute; + float_t second; +}; + +static_assert(sizeof(stage_param_data_star_utc) == 0x18, "\"stage_param_data_star_utc\" struct should have a size of 0x18"); + +struct stage_param_data_star_modifiers { + float_t color_scale; + float_t pos_scale; + float_t offset_scale; + float_t threshold; + float_t size_max; +}; + +static_assert(sizeof(stage_param_data_star_modifiers) == 0x14, "\"stage_param_data_star_modifiers\" struct should have a size of 0x14"); + +struct stage_param_data_star { + int32_t tex_id; + stage_param_data_star_utc utc; + float_t rotation_y_deg; + float_t observer_north_latitude_deg; + float_t observer_east_longitude_deg; + stage_param_data_star_modifiers modifiers[2]; +}; + +static_assert(sizeof(stage_param_data_star) == 0x50, "\"stage_param_data_star\" struct should have a size of 0x50"); + +extern stage_param_data_litproj** stage_param_data_litproj_current; diff --git a/src/DivaGL/texture.cpp b/src/DivaGL/texture.cpp new file mode 100644 index 0000000..eaef4ad --- /dev/null +++ b/src/DivaGL/texture.cpp @@ -0,0 +1,106 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "texture.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/txp.hpp" +#include "gl_state.hpp" +#include + +static void texture_bind(GLenum target, GLuint texture); + +texture* (FASTCALL* _texture_init)(texture_id id) + = (texture * (FASTCALL*)(texture_id id))0x000000014069A390; +texture* (FASTCALL* _texture_copy)(texture_id id, texture* org_tex) + = (texture * (FASTCALL*)(texture_id id, texture * org_tex))0x000000014069B550; +texture* (FASTCALL* texture_load_tex_cubemap)(uint32_t id, GLenum internal_format, + int32_t width, int32_t height, int32_t max_mipmap_level, void** data_ptr) + = (texture * (FASTCALL*)(uint32_t id, GLenum internal_format, int32_t width, + int32_t height, int32_t max_mipmap_level, void** data_ptr))0x000000014069B860; +texture* (FASTCALL* texture_load_tex_2d)(texture_id id, GLenum internal_format, + int32_t width, int32_t height, int32_t max_mipmap_level, void** data_ptr, bool use_high_anisotropy) + = (texture * (FASTCALL*)(texture_id id, GLenum internal_format, int32_t width, int32_t height, + int32_t max_mipmap_level, void** data_ptr, bool use_high_anisotropy))0x000000014069B8E0; +void(FASTCALL* texture_free)(texture* tex) + = (void(FASTCALL*)(texture * tex))0x000000014069DA70; +int32_t(FASTCALL* texture_info_get_id)(const char* name) + = (int32_t(FASTCALL*)(const char* name))0x000000014069CBD0; +texture* (FASTCALL* texture_handler_get_texture)(uint32_t id) + = (texture * (FASTCALL*)(uint32_t id))0x000000014069CD70; + +void texture_set_params(GLenum target, int32_t max_mipmap_level, bool use_high_anisotropy) { + glTexParameteriDLL(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteriDLL(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteriDLL(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + static const vec4 border_color = 0.0f; + glTexParameterfvDLL(target, GL_TEXTURE_BORDER_COLOR, (GLfloat*)&border_color); + glTexParameteriDLL(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteriDLL(target, GL_TEXTURE_MIN_FILTER, + max_mipmap_level > 0 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); + glTexParameteriDLL(target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteriDLL(target, GL_TEXTURE_MAX_LEVEL, max_mipmap_level); + + float_t max_anisotropy; + if (use_high_anisotropy) + max_anisotropy = 16.0f; + else + max_anisotropy = 1.0f; + glTexParameterfDLL(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy); +} + +void texture_params_get(GLuint tex_0, texture_param* tex_0_param, + GLuint tex_1, texture_param* tex_1_param, GLuint tex_2, texture_param* tex_2_param) { + gl_state_disable_depth_test(); + if (tex_0_param) { + tex_0_param->width = 0; + tex_0_param->height = 0; + if (tex_0) { + gl_state_bind_texture_2d(tex_0); + glGetTexLevelParameterivDLL(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_0_param->width); + glGetTexLevelParameterivDLL(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_0_param->height); + } + } + + if (tex_1_param) { + tex_1_param->width = 0; + tex_1_param->height = 0; + if (tex_1) { + gl_state_bind_texture_2d(tex_1); + glGetTexLevelParameterivDLL(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_1_param->width); + glGetTexLevelParameterivDLL(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_1_param->height); + } + } + + if (tex_2_param) { + tex_2_param->width = 0; + tex_2_param->height = 0; + if (tex_2) { + gl_state_bind_texture_2d(tex_2); + glGetTexLevelParameterivDLL(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_2_param->width); + glGetTexLevelParameterivDLL(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_2_param->height); + } + } + gl_state_bind_texture_2d(0); + + if (tex_0_param) + glViewportDLL(0, 0, tex_0_param->width, tex_0_param->height); +} + +void texture_params_restore(texture_param* tex_0_param, + texture_param* tex_1_param, texture_param* tex_2_param) { + for (int32_t i = 0; i < 4; i++) + gl_state_active_bind_texture_2d(i, 0); +} + +inline static void texture_bind(GLenum target, GLuint texture) { + switch (target) { + case GL_TEXTURE_2D: + gl_state_bind_texture_2d(texture, true); + break; + case GL_TEXTURE_CUBE_MAP: + gl_state_bind_texture_cube_map(texture, true); + break; + } +} diff --git a/src/DivaGL/texture.hpp b/src/DivaGL/texture.hpp new file mode 100644 index 0000000..5b16489 --- /dev/null +++ b/src/DivaGL/texture.hpp @@ -0,0 +1,95 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" +#include "../KKdLib/image.hpp" +#include "../KKdLib/txp.hpp" +#include "wrap.hpp" + +enum texture_flags { + TEXTURE_BLOCK_COMPRESSION = 0x01, +}; + +struct texture_id { + uint32_t index : 24; + uint32_t id : 8; + + inline texture_id() { + id = 0; + index = 0; + } + + inline texture_id(uint8_t id, uint32_t index) { + this->id = id; + this->index = index; + } +}; + +inline bool operator >(const texture_id& left, const texture_id& right) { + return left.id > right.id && left.index > right.index; +} + +inline bool operator <(const texture_id& left, const texture_id& right) { + return left.id < right.id && left.index < right.index; +} + +inline bool operator >=(const texture_id& left, const texture_id& right) { + return left.id >= right.id && left.index >= right.index; +} + +inline bool operator <=(const texture_id& left, const texture_id& right) { + return left.id <= right.id && left.index <= right.index; +} + +inline bool operator ==(const texture_id& left, const texture_id& right) { + return left.id == right.id && left.index == right.index; +} + +inline bool operator !=(const texture_id& left, const texture_id& right) { + return left.id != right.id || left.index != right.index; +} + +static_assert(sizeof(texture_id) == 0x04, "\"texture_id\" struct should have a size of 0x04"); + +struct texture { + int32_t init_count; + texture_id id; + texture_flags flags; + int16_t width; + int16_t height; + GLuint tex; + GLenum target; + GLenum internal_format; + int32_t max_mipmap_level; + int32_t size; +}; + +static_assert(sizeof(texture) == 0x24, "\"texture\" struct should have a size of 0x24"); + +struct texture_param { + GLint width; + GLint height; +}; + +static_assert(sizeof(texture_param) == 0x08, "\"texture_param\" struct should have a size of 0x08"); + +extern texture* (FASTCALL* texture_init)(texture_id id); +extern texture* (FASTCALL* texture_copy)(texture_id id, texture* org_tex); +extern texture* (FASTCALL* texture_load_tex_cubemap)(uint32_t id, GLenum internal_format, + int32_t width, int32_t height, int32_t max_mipmap_level, void** data_ptr); +extern texture* (FASTCALL* texture_load_tex_2d)(texture_id id, GLenum internal_format, + int32_t width, int32_t height, int32_t max_mipmap_level, void** data_ptr, bool use_high_anisotropy); +extern void(FASTCALL* texture_free)(texture* tex); +extern int32_t(FASTCALL* texture_info_get_id)(const char* name); +extern texture* (FASTCALL* texture_handler_get_texture)(uint32_t id); + +extern void texture_set_params(GLenum target, int32_t max_mipmap_level, bool use_high_anisotropy); + +extern void texture_params_get(GLuint tex_0 = 0, texture_param* tex_0_param = 0, + GLuint tex_1 = 0, texture_param* tex_1_param = 0, GLuint tex_2 = 0, texture_param* tex_2_param = 0); +extern void texture_params_restore(texture_param* tex_0_param = 0, + texture_param* tex_1_param = 0, texture_param* tex_2_param = 0); diff --git a/src/DivaGL/types.hpp b/src/DivaGL/types.hpp new file mode 100644 index 0000000..3265e2a --- /dev/null +++ b/src/DivaGL/types.hpp @@ -0,0 +1,72 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder + + Original: Allocator.h, Types.h by blueskythlikesclouds from DivaModLoader +*/ + +#include "../KKdLib/default.hpp" +#include +#include +#include + +#pragma once + +typedef enum HeapCMallocType { + HeapCMallocSystem = 0x00, + HeapCMallocTemp = 0x01, + HeapCMallocMode = 0x02, + HeapCMallocEvent = 0x03, + HeapCMallocDebug = 0x04, + HeapCMallocMax = 0x05, +} HeapCMallocType; + +static void* (*HeapCMallocAllocate)(HeapCMallocType type, size_t size, const char* name) + = (void* (*)(HeapCMallocType, size_t, const char*))0x00000001403F2A00; +static void(*HeapCMallocFree)(HeapCMallocType type, void* data) + = (void(*)(HeapCMallocType, void*))0x00000001403F2960; +static void* (*_operator_new)(size_t) = (void* (*)(size_t))0x000000014084530C; +static void(*_operator_delete)(void*) = (void(*)(void*))0x0000000140845378; + +template +class Allocator { +public: + using value_type = T; + + Allocator() noexcept {} + template Allocator(Allocator const&) noexcept {} + + value_type* allocate(std::size_t n) { + return reinterpret_cast(_operator_new(n * sizeof(value_type))); + } + + void deallocate(value_type* p, std::size_t) noexcept { + _operator_delete(reinterpret_cast(p)); + } +}; + +template +bool operator==(Allocator const&, Allocator const&) noexcept { + return true; +} + +template +bool operator!=(Allocator const& x, Allocator const& y) noexcept { + return !(x == y); +} + +namespace prj { + using string = std::basic_string, Allocator>; + + template + using vector = std::vector>; + + template + using list = std::list>; + + template + using map = std::map>>; + + template + using pair = std::pair; +} diff --git a/src/DivaGL/uniform.cpp b/src/DivaGL/uniform.cpp new file mode 100644 index 0000000..33fb947 --- /dev/null +++ b/src/DivaGL/uniform.cpp @@ -0,0 +1,10 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "uniform.hpp" + +uniform_value* uniform = (uniform_value*)0x000000014CC57AF0; + +void(FASTCALL* uniform_value_reset)() = (void(FASTCALL*)())0x0000000140443400; diff --git a/src/DivaGL/uniform.hpp b/src/DivaGL/uniform.hpp new file mode 100644 index 0000000..93d6bbe --- /dev/null +++ b/src/DivaGL/uniform.hpp @@ -0,0 +1,91 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "../KKdLib/default.hpp" + +enum uniform_name { + U_NONE = 0x00, + U_ALPHA_MASK = 0x01, + U_ALPHA_TEST = 0x02, + U_ANISO = 0x03, + U_AET_BACK = 0x04, + U_TEXTURE_BLEND = 0x05, + U_CHARA_COLOR = 0x06, + U_CLIP_PLANE = 0x07, + U08 = 0x08, + U_DEPTH_PEEL = 0x09, + U0A = 0x0A, + U0B = 0x0B, + U_ALPHA_BLEND = 0x0C, + U_RIPPLE_EMIT = 0x0D, + U_ESM_FILTER = 0x0E, + U_EXPOSURE = 0x0F, + U_SCENE_FADE = 0x10, + U_FADE = 0x11, + U12 = 0x12, + U_FLARE = 0x13, + U_FOG_HEIGHT = 0x14, + U_FOG = 0x15, + U16 = 0x16, + U_GAUSS = 0x17, + U18 = 0x18, + U_IMAGE_FILTER = 0x19, + U_INSTANCE = 0x1A, + U_TONE_CURVE = 0x1B, + U_LIGHT_PROJ = 0x1C, + U_MAGNIFY = 0x1D, + U_MEMBRANE = 0x1E, + U_MLAA = 0x1F, + U_MLAA_SEARCH = 0x20, + U_MORPH_COLOR = 0x21, + U_MORPH = 0x22, + U_MOVIE = 0x23, + U24 = 0x24, + U25 = 0x25, + U26 = 0x26, + U_NPR = 0x27, + U_LIGHT_1 = 0x28, + U_REFLECT = 0x29, + U_REDUCE = 0x2A, + U_SELF_SHADOW = 0x2B, + U_SHADOW = 0x2C, + U2D = 0x2D, + U2E = 0x2E, + U_SHOW_VECTOR = 0x2F, + U_BONE_MAT = 0x30, + U_SNOW_PARTICLE = 0x31, + U_SPECULAR_IBL = 0x32, + U_COMBINER = 0x33, + U_TEX_0_TYPE = 0x34, + U_TEX_1_TYPE = 0x35, + U_SSS_FILTER = 0x36, + U37 = 0x37, + U_STAR = 0x38, + U_TEXTURE_COUNT = 0x39, + U_ENV_MAP = 0x3A, + U_RIPPLE = 0x3B, + U_TRANSLUCENCY = 0x3C, + U_NORMAL = 0x3D, + U_TRANSPARENCY = 0x3E, + U_WATER_REFLECT = 0x3F, + U40 = 0x40, + U41 = 0x41, + U_LIGHT_0 = 0x42, + U_SPECULAR = 0x43, + U_TONE_MAP = 0x44, + U45 = 0x45, + U_MAX = 0x46, + U_INVALID = 0xFFFFFFFF, +}; + +struct uniform_value { + int32_t arr[U_MAX]; +}; + +extern uniform_value* uniform; + +extern void(FASTCALL* uniform_value_reset)(); diff --git a/src/DivaGL/wrap.cpp b/src/DivaGL/wrap.cpp new file mode 100644 index 0000000..52a0ee1 --- /dev/null +++ b/src/DivaGL/wrap.cpp @@ -0,0 +1,2580 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#include "wrap.hpp" +#include "../KKdLib/half_t.hpp" +#include "../KKdLib/mat.hpp" +#include "../KKdLib/vec.hpp" +#include "inject.hpp" +#include "print.hpp" +#include "shader_glsl_ft.hpp" +#include +#include + +struct func_struct { + size_t address; + size_t orig_func; + size_t func; +}; + +#define GLALPHAFUNCDLL 0 +#define GLBEGINDLL 1 +#define GLBINDTEXTUREDLL 2 +#define GLCLEARDLL 3 +#define GLCLEARCOLORDLL 4 +#define GLCLEARDEPTHDLL 5 +#define GLCLEARSTENCILDLL 6 +#define GLCOLOR3FDLL 7 +#define GLCOLOR4FDLL 8 +#define GLCOLOR4UBDLL 9 +#define GLCOLOR4UBVDLL 10 +#define GLCOLORPOINTERDLL 11 +#define GLCOPYTEXIMAGE2DDLL 12 +#define GLCOPYTEXSUBIMAGE2DDLL 13 +#define GLCULLFACEDLL 14 +#define GLDEPTHFUNCDLL 15 +#define GLDISABLEDLL 16 +#define GLDISABLECLIENTSTATEDLL 17 +#define GLDRAWARRAYSDLL 18 +#define GLDRAWBUFFERDLL 19 +#define GLDRAWELEMENTSDLL 20 +#define GLENABLEDLL 21 +#define GLENABLECLIENTSTATEDLL 22 +#define GLENDDLL 23 +#define GLFOGFDLL 24 +#define GLFOGFVDLL 25 +#define GLFOGIDLL 26 +#define GLFRONTFACEDLL 27 +#define GLFRUSTUMDLL 28 +#define GLGETBOOLEANVDLL 29 +#define GLGETERRORDLL 30 +#define GLGETFLOATVDLL 31 +#define GLGETINTEGERVDLL 32 +#define GLGETMATERIALFVDLL 33 +#define GLGETTEXIMAGEDLL 34 +#define GLGETTEXLEVELPARAMETERIVDLL 35 +#define GLGETTEXPARAMETERIVDLL 36 +#define GLISENABLEDDLL 37 +#define GLLIGHTFVDLL 38 +#define GLLIGHTMODELFVDLL 39 +#define GLLINEWIDTHDLL 40 +#define GLLOADIDENTITYDLL 41 +#define GLLOADMATRIXFDLL 42 +#define GLMATERIALFDLL 43 +#define GLMATERIALFVDLL 44 +#define GLMATRIXMODEDLL 45 +#define GLMULTMATRIXDDLL 46 +#define GLNORMAL3FDLL 47 +#define GLNORMALPOINTERDLL 48 +#define GLORTHODLL 49 +#define GLPIXELSTOREIDLL 50 +#define GLPOINTSIZEDLL 51 +#define GLPOLYGONMODEDLL 52 +#define GLPOPATTRIBDLL 53 +#define GLPOPCLIENTATTRIBDLL 54 +#define GLPOPMATRIXDLL 55 +#define GLPUSHATTRIBDLL 56 +#define GLPUSHCLIENTATTRIBDLL 57 +#define GLPUSHMATRIXDLL 58 +#define GLREADBUFFERDLL 59 +#define GLREADPIXELSDLL 60 +#define GLROTATEFDLL 61 +#define GLSCALEFDLL 62 +#define GLSHADEMODELDLL 63 +#define GLTEXCOORD2FDLL 64 +#define GLTEXCOORDPOINTERDLL 65 +#define GLTEXENVFDLL 66 +#define GLTEXENVIDLL 67 +#define GLTEXIMAGE1DDLL 68 +#define GLTEXIMAGE2DDLL 69 +#define GLTEXPARAMETERFDLL 70 +#define GLTEXPARAMETERFVDLL 71 +#define GLTEXPARAMETERIDLL 72 +#define GLTEXSUBIMAGE2DDLL 73 +#define GLTRANSLATEFDLL 74 +#define GLVERTEX3FDLL 75 +#define GLVERTEX3FVDLL 76 +#define GLVERTEXPOINTERDLL 77 + +#define GLACTIVETEXTURE 0 +#define GLBINDBUFFERARB 1 +#define GLBINDBUFFERBASENV 2 +#define GLBINDFRAMEBUFFEREXT 3 +#define GLBINDMULTITEXTUREEXT 4 +#define GLBINDRENDERBUFFEREXT 5 +#define GLBUFFERDATAARB 6 +#define GLCLAMPCOLORARB 7 +#define GLCLIENTACTIVETEXTURE 8 +#define GLCOPYMULTITEXSUBIMAGE2DEXT 9 +#define GLDELETEBUFFERSARB 10 +#define GLDELETEFRAMEBUFFERSEXT 11 +#define GLDELETERENDERBUFFERSEXT 12 +#define GLDELETETEXTURES 13 +#define GLDISABLEVERTEXATTRIBARRAYARB 14 +#define GLDRAWRANGEELEMENTS 15 +#define GLENABLEVERTEXATTRIBARRAY 16 +#define GLENABLEVERTEXATTRIBARRAYARB 17 +#define GLFRAMEBUFFERRENDERBUFFEREXT 18 +#define GLFRAMEBUFFERTEXTURE2DEXT 19 +#define GLGENFRAMEBUFFERSEXT 20 +#define GLGENRENDERBUFFERSEXT 21 +#define GLGENTEXTURES 22 +#define GLGETPROGRAMENVPARAMETERFVARB 23 +#define GLGETPROGRAMIVARB 24 +#define GLGETTEXTUREIMAGEEXT 25 +#define GLISBUFFERARB 26 +#define GLLOADTRANSPOSEMATRIXF 27 +#define GLMAPNAMEDBUFFEREXT 28 +#define GLMULTITEXCOORD2F 29 +#define GLMULTITEXCOORD2FV 30 +#define GLMULTTRANSPOSEMATRIXF 31 +#define GLNAMEDBUFFERDATAEXT 32 +#define GLNAMEDBUFFERSUBDATAEXT 33 +#define GLPOINTPARAMETERF 34 +#define GLPOINTPARAMETERFV 35 +#define GLPOINTPARAMETERI 36 +#define GLPRIMITIVERESTARTINDEXNV 37 +#define GLPROGRAMBUFFERPARAMETERSFVNV 38 +#define GLPROGRAMENVPARAMETER4FARB 39 +#define GLPROGRAMENVPARAMETER4FVARB 40 +#define GLPROGRAMENVPARAMETERS4FVEXT 41 +#define GLPROGRAMLOCALPARAMETER4FARB 42 +#define GLPROGRAMLOCALPARAMETER4FVARB 43 +#define GLPROGRAMLOCALPARAMETERS4FVEXT 44 +#define GLRENDERBUFFERSTORAGEEXT 45 +#define GLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENV 46 +#define GLUNMAPNAMEDBUFFEREXT 47 +#define GLUSEPROGRAM 48 +#define GLVERTEXATTRIBPOINTERARB 49 + +#define GLBEGINGLUT 0 +#define GLBITMAPGLUT 1 +#define GLDRAWBUFFERGLUT 2 +#define GLENABLEGLUT 3 +#define GLENDGLUT 4 +#define GLEVALMESH2GLUT 5 +#define GLGETERRORGLUT 6 +#define GLGETINTEGERVGLUT 7 +#define GLGETSTRINGGLUT 8 +#define GLMAP2FGLUT 9 +#define GLMAPGRID2FGLUT 10 +#define GLNORMAL3FGLUT 11 +#define GLNORMAL3FVGLUT 12 +#define GLPIXELSTOREIGLUT 13 +#define GLPOLYGONMODEGLUT 14 +#define GLPOPATTRIBGLUT 15 +#define GLPOPMATRIXGLUT 16 +#define GLPUSHATTRIBGLUT 17 +#define GLPUSHMATRIXGLUT 18 +#define GLREADBUFFERGLUT 19 +#define GLROTATEFGLUT 20 +#define GLSCALEFGLUT 21 +#define GLTRANSLATEFGLUT 22 +#define GLVERTEX2FGLUT 23 +#define GLVERTEX3FGLUT 24 +#define GLVERTEX3FVGLUT 25 +#define WGLCREATECONTEXTGLUT 26 + +typedef void (GLAPIENTRY* PFNGLALPHAFUNCDLLPROC)(GLenum func, GLfloat ref); +typedef void (GLAPIENTRY* PFNGLBEGINDLLPROC)(GLenum mode); +typedef void (GLAPIENTRY* PFNGLBINDTEXTUREDLLPROC)(GLenum target, GLuint texture); +typedef void (GLAPIENTRY* PFNGLCLEARDLLPROC)(GLbitfield mask); +typedef void (GLAPIENTRY* PFNGLCLEARCOLORDLLPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAPIENTRY* PFNGLCLEARDEPTHDLLPROC)(GLdouble depth); +typedef void (GLAPIENTRY* PFNGLCLEARSTENCILDLLPROC)(GLint s); +typedef void (GLAPIENTRY* PFNGLCOLOR3FDLLPROC)(GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY* PFNGLCOLOR4FDLLPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAPIENTRY* PFNGLCOLOR4UBDLLPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +typedef void (GLAPIENTRY* PFNGLCOLOR4UBVDLLPROC)(GLubyte const * v); +typedef void (GLAPIENTRY* PFNGLCOLORPOINTERDLLPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY* PFNGLCOPYTEXIMAGE2DDLLPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY* PFNGLCOPYTEXSUBIMAGE2DDLLPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY* PFNGLCULLFACEDLLPROC)(GLenum mode); +typedef void (GLAPIENTRY* PFNGLDEPTHFUNCDLLPROC)(GLenum func); +typedef void (GLAPIENTRY* PFNGLDISABLEDLLPROC)(GLenum cap); +typedef void (GLAPIENTRY* PFNGLDISABLECLIENTSTATEDLLPROC)(GLenum array); +typedef void (GLAPIENTRY* PFNGLDRAWARRAYSDLLPROC)(GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY* PFNGLDRAWBUFFERDLLPROC)(GLenum buf); +typedef void (GLAPIENTRY* PFNGLDRAWELEMENTSDLLPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); +typedef void (GLAPIENTRY* PFNGLENABLEDLLPROC)(GLenum cap); +typedef void (GLAPIENTRY* PFNGLENABLECLIENTSTATEDLLPROC)(GLenum array); +typedef void (GLAPIENTRY* PFNGLENDDLLPROC)(); +typedef void (GLAPIENTRY* PFNGLFOGFDLLPROC)(GLenum pname, GLfloat param); +typedef void (GLAPIENTRY* PFNGLFOGFVDLLPROC)(GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLFOGIDLLPROC)(GLenum pname, GLint param); +typedef void (GLAPIENTRY* PFNGLFRONTFACEDLLPROC)(GLenum mode); +typedef void (GLAPIENTRY* PFNGLFRUSTUMDLLPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAPIENTRY* PFNGLGETBOOLEANVDLLPROC)(GLenum pname, GLboolean * data); +typedef GLenum (GLAPIENTRY* PFNGLGETERRORDLLPROC)(); +typedef void (GLAPIENTRY* PFNGLGETFLOATVDLLPROC)(GLenum pname, GLfloat * data); +typedef void (GLAPIENTRY* PFNGLGETINTEGERVDLLPROC)(GLenum pname, GLint * data); +typedef void (GLAPIENTRY* PFNGLGETMATERIALFVDLLPROC)(GLenum face, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY* PFNGLGETTEXIMAGEDLLPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef void (GLAPIENTRY* PFNGLGETTEXLEVELPARAMETERIVDLLPROC)(GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAPIENTRY* PFNGLGETTEXPARAMETERIVDLLPROC)(GLenum target, GLenum pname, GLint * params); +typedef GLboolean (GLAPIENTRY* PFNGLISENABLEDDLLPROC)(GLenum cap); +typedef void (GLAPIENTRY* PFNGLLIGHTFVDLLPROC)(GLenum light, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLLIGHTMODELFVDLLPROC)(GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLLINEWIDTHDLLPROC)(GLfloat width); +typedef void (GLAPIENTRY* PFNGLLOADIDENTITYDLLPROC)(); +typedef void (GLAPIENTRY* PFNGLLOADMATRIXFDLLPROC)(GLfloat const * m); +typedef void (GLAPIENTRY* PFNGLMATERIALFDLLPROC)(GLenum face, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY* PFNGLMATERIALFVDLLPROC)(GLenum face, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLMATRIXMODEDLLPROC)(GLenum mode); +typedef void (GLAPIENTRY* PFNGLMULTMATRIXDDLLPROC)(GLdouble const * m); +typedef void (GLAPIENTRY* PFNGLNORMAL3FDLLPROC)(GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (GLAPIENTRY* PFNGLNORMALPOINTERDLLPROC)(GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY* PFNGLORTHODLLPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAPIENTRY* PFNGLPIXELSTOREIDLLPROC)(GLenum pname, GLint param); +typedef void (GLAPIENTRY* PFNGLPOINTSIZEDLLPROC)(GLfloat size); +typedef void (GLAPIENTRY* PFNGLPOLYGONMODEDLLPROC)(GLenum face, GLenum mode); +typedef void (GLAPIENTRY* PFNGLPOPATTRIBDLLPROC)(); +typedef void (GLAPIENTRY* PFNGLPOPCLIENTATTRIBDLLPROC)(); +typedef void (GLAPIENTRY* PFNGLPOPMATRIXDLLPROC)(); +typedef void (GLAPIENTRY* PFNGLPUSHATTRIBDLLPROC)(GLbitfield mask); +typedef void (GLAPIENTRY* PFNGLPUSHCLIENTATTRIBDLLPROC)(GLbitfield mask); +typedef void (GLAPIENTRY* PFNGLPUSHMATRIXDLLPROC)(); +typedef void (GLAPIENTRY* PFNGLREADBUFFERDLLPROC)(GLenum src); +typedef void (GLAPIENTRY* PFNGLREADPIXELSDLLPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); +typedef void (GLAPIENTRY* PFNGLROTATEFDLLPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLSCALEFDLLPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLSHADEMODELDLLPROC)(GLenum mode); +typedef void (GLAPIENTRY* PFNGLTEXCOORD2FDLLPROC)(GLfloat s, GLfloat t); +typedef void (GLAPIENTRY* PFNGLTEXCOORDPOINTERDLLPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY* PFNGLTEXENVFDLLPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY* PFNGLTEXENVIDLLPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY* PFNGLTEXIMAGE1DDLLPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY* PFNGLTEXIMAGE2DDLLPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY* PFNGLTEXPARAMETERFDLLPROC)(GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY* PFNGLTEXPARAMETERFVDLLPROC)(GLenum target, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLTEXPARAMETERIDLLPROC)(GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY* PFNGLTEXSUBIMAGE2DDLLPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY* PFNGLTRANSLATEFDLLPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLVERTEX3FDLLPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLVERTEX3FVDLLPROC)(GLfloat const * v); +typedef void (GLAPIENTRY* PFNGLVERTEXPOINTERDLLPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); + +typedef void (GLAPIENTRY* PFNGLACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAPIENTRY* PFNGLBINDBUFFERARBPROC)(GLenum target, GLuint buffer); +typedef void (GLAPIENTRY* PFNGLBINDBUFFERBASENVPROC)(GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY* PFNGLBINDFRAMEBUFFEREXTPROC)(GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY* PFNGLBINDMULTITEXTUREEXTPROC)(GLenum texunit, GLenum target, GLuint texture); +typedef void (GLAPIENTRY* PFNGLBINDRENDERBUFFEREXTPROC)(GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY* PFNGLBUFFERDATAARBPROC)(GLenum target, GLsizeiptrARB size, const void * data, GLenum usage); +typedef void (GLAPIENTRY* PFNGLCLAMPCOLORARBPROC)(GLenum target, GLenum clamp); +typedef void (GLAPIENTRY* PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); +typedef void (GLAPIENTRY* PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY* PFNGLDELETEBUFFERSARBPROC)(GLsizei n, GLuint const * buffers); +typedef void (GLAPIENTRY* PFNGLDELETEFRAMEBUFFERSEXTPROC)(GLsizei n, GLuint const * framebuffers); +typedef void (GLAPIENTRY* PFNGLDELETERENDERBUFFERSEXTPROC)(GLsizei n, GLuint const * renderbuffers); +typedef void (GLAPIENTRY* PFNGLDELETETEXTURESPROC)(GLsizei n, GLuint const * textures); +typedef void (GLAPIENTRY* PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)(GLuint index); +typedef void (GLAPIENTRY* PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +typedef void (GLAPIENTRY* PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); +typedef void (GLAPIENTRY* PFNGLENABLEVERTEXATTRIBARRAYARBPROC)(GLuint index); +typedef void (GLAPIENTRY* PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY* PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY* PFNGLGENFRAMEBUFFERSEXTPROC)(GLsizei n, GLuint * framebuffers); +typedef void (GLAPIENTRY* PFNGLGENRENDERBUFFERSEXTPROC)(GLsizei n, GLuint * renderbuffers); +typedef void (GLAPIENTRY* PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); +typedef void (GLAPIENTRY* PFNGLGETPROGRAMENVPARAMETERFVARBPROC)(GLenum target, GLuint index, GLfloat * params); +typedef void (GLAPIENTRY* PFNGLGETPROGRAMIVARBPROC)(GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY* PFNGLGETTEXTUREIMAGEEXTPROC)(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef GLboolean (GLAPIENTRY* PFNGLISBUFFERARBPROC)(GLuint buffer); +typedef void (GLAPIENTRY* PFNGLLOADTRANSPOSEMATRIXFPROC)(GLfloat const * m); +typedef void * (GLAPIENTRY* PFNGLMAPNAMEDBUFFEREXTPROC)(GLuint buffer, GLenum access); +typedef void (GLAPIENTRY* PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY* PFNGLMULTITEXCOORD2FVPROC)(GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY* PFNGLMULTTRANSPOSEMATRIXFPROC)(GLfloat const * m); +typedef void (GLAPIENTRY* PFNGLNAMEDBUFFERDATAEXTPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAPIENTRY* PFNGLNAMEDBUFFERSUBDATAEXTPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAPIENTRY* PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); +typedef void (GLAPIENTRY* PFNGLPOINTPARAMETERFVPROC)(GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); +typedef void (GLAPIENTRY* PFNGLPRIMITIVERESTARTINDEXNVPROC)(GLuint index); +typedef void (GLAPIENTRY* PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLPROGRAMENVPARAMETER4FARBPROC)(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY* PFNGLPROGRAMENVPARAMETER4FVARBPROC)(GLenum target, GLuint index, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)(GLenum target, GLuint index, GLsizei count, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLPROGRAMLOCALPARAMETER4FARBPROC)(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY* PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)(GLenum target, GLuint index, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)(GLenum target, GLuint index, GLsizei count, GLfloat const * params); +typedef void (GLAPIENTRY* PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY* PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef GLboolean (GLAPIENTRY* PFNGLUNMAPNAMEDBUFFEREXTPROC)(GLuint buffer); +typedef void (GLAPIENTRY* PFNGLUSEPROGRAMPROC)(GLuint program); +typedef void (GLAPIENTRY* PFNGLVERTEXATTRIBPOINTERARBPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); + +typedef void (GLAPIENTRY* PFNGLBEGINGLUTPROC)(GLenum mode); +typedef void (GLAPIENTRY* PFNGLBITMAPGLUTPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const * bitmap); +typedef void (GLAPIENTRY* PFNGLDRAWBUFFERGLUTPROC)(GLenum buf); +typedef void (GLAPIENTRY* PFNGLENABLEGLUTPROC)(GLenum cap); +typedef void (GLAPIENTRY* PFNGLENDGLUTPROC)(); +typedef void (GLAPIENTRY* PFNGLEVALMESH2GLUTPROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +typedef GLenum (GLAPIENTRY* PFNGLGETERRORGLUTPROC)(); +typedef void (GLAPIENTRY* PFNGLGETINTEGERVGLUTPROC)(GLenum pname, GLint * data); +typedef GLubyte const * (GLAPIENTRY* PFNGLGETSTRINGGLUTPROC)(GLenum name); +typedef void (GLAPIENTRY* PFNGLMAP2FGLUTPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat const * points); +typedef void (GLAPIENTRY* PFNGLMAPGRID2FGLUTPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY* PFNGLNORMAL3FGLUTPROC)(GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (GLAPIENTRY* PFNGLNORMAL3FVGLUTPROC)(GLfloat const * v); +typedef void (GLAPIENTRY* PFNGLPIXELSTOREIGLUTPROC)(GLenum pname, GLint param); +typedef void (GLAPIENTRY* PFNGLPOLYGONMODEGLUTPROC)(GLenum face, GLenum mode); +typedef void (GLAPIENTRY* PFNGLPOPATTRIBGLUTPROC)(); +typedef void (GLAPIENTRY* PFNGLPOPMATRIXGLUTPROC)(); +typedef void (GLAPIENTRY* PFNGLPUSHATTRIBGLUTPROC)(GLbitfield mask); +typedef void (GLAPIENTRY* PFNGLPUSHMATRIXGLUTPROC)(); +typedef void (GLAPIENTRY* PFNGLREADBUFFERGLUTPROC)(GLenum src); +typedef void (GLAPIENTRY* PFNGLROTATEFGLUTPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLSCALEFGLUTPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLTRANSLATEFGLUTPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLVERTEX2FGLUTPROC)(GLfloat x, GLfloat y); +typedef void (GLAPIENTRY* PFNGLVERTEX3FGLUTPROC)(GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY* PFNGLVERTEX3FVGLUTPROC)(GLfloat const * v); +typedef HGLRC (GLAPIENTRY* PFNWGLCREATECONTEXTGLUTPROC)(HDC hDc); + +extern size_t glut_handle; + +func_struct wrap_addr_dll[78] = { + { 0x0000000140965A00, 0, (size_t)&glAlphaFuncDLL, }, // glAlphaFunc + { 0x0000000140965A70, 0, (size_t)&glBeginDLL, }, // glBegin + { 0x0000000140965BF8, 0, (size_t)&glBindTextureDLL, }, // glBindTexture + { 0x0000000140965C58, 0, (size_t)&glClearDLL, }, // glClear + { 0x0000000140965C38, 0, (size_t)&glClearColorDLL, }, // glClearColor + { 0x0000000140965C08, 0, (size_t)&glClearDepthDLL, }, // glClearDepth + { 0x0000000140965C10, 0, (size_t)&glClearStencilDLL, }, // glClearStencil + { 0x0000000140965A88, 0, (size_t)&glColor3fDLL, }, // glColor3f + { 0x0000000140965A90, 0, (size_t)&glColor4fDLL, }, // glColor4f + { 0x0000000140965B88, 0, (size_t)&glColor4ubDLL, }, // glColor4ub + { 0x0000000140965B90, 0, (size_t)&glColor4ubvDLL, }, // glColor4ubv + { 0x0000000140965C30, 0, (size_t)&glColorPointerDLL, }, // glColorPointer + { 0x0000000140965B40, 0, (size_t)&glCopyTexImage2DDLL, }, // glCopyTexImage2D + { 0x0000000140965A98, 0, (size_t)&glCopyTexSubImage2DDLL, }, // glCopyTexSubImage2D + { 0x0000000140965C18, 0, (size_t)&glCullFaceDLL, }, // glCullFace + { 0x0000000140965C40, 0, (size_t)&glDepthFuncDLL, }, // glDepthFunc + { 0x0000000140965C48, 0, (size_t)&glDisableDLL, }, // glDisable + { 0x0000000140965C28, 0, (size_t)&glDisableClientStateDLL, }, // glDisableClientState + { 0x0000000140965BF0, 0, (size_t)&glDrawArraysDLL, }, // glDrawArrays + { 0x0000000140965B60, 0, (size_t)&glDrawBufferDLL, }, // glDrawBuffer + { 0x0000000140965A48, 0, (size_t)&glDrawElementsDLL, }, // glDrawElements + { 0x0000000140965C50, 0, (size_t)&glEnableDLL, }, // glEnable + { 0x0000000140965BE8, 0, (size_t)&glEnableClientStateDLL, }, // glEnableClientState + { 0x0000000140965A78, 0, (size_t)&glEndDLL, }, // glEnd + { 0x0000000140965A58, 0, (size_t)&glFogfDLL, }, // glFogf + { 0x0000000140965A60, 0, (size_t)&glFogfvDLL, }, // glFogfv + { 0x0000000140965A68, 0, (size_t)&glFogiDLL, }, // glFogi + { 0x0000000140965BB0, 0, (size_t)&glFrontFaceDLL, }, // glFrontFace + { 0x0000000140965C98, 0, (size_t)&glFrustumDLL, }, // glFrustum + { 0x0000000140965AF0, 0, (size_t)&glGetBooleanvDLL, }, // glGetBooleanv + { 0x0000000140965BA8, 0, (size_t)&glGetErrorDLL, }, // glGetError + { 0x0000000140965C90, 0, (size_t)&glGetFloatvDLL, }, // glGetFloatv + { 0x0000000140965AF8, 0, (size_t)&glGetIntegervDLL, }, // glGetIntegerv + { 0x0000000140965CB0, 0, (size_t)&glGetMaterialfvDLL, }, // glGetMaterialfv + { 0x0000000140965C00, 0, (size_t)&glGetTexImageDLL, }, // glGetTexImage + { 0x0000000140965AA0, 0, (size_t)&glGetTexLevelParameterivDLL, }, // glGetTexLevelParameteriv + { 0x0000000140965AA8, 0, (size_t)&glGetTexParameterivDLL, }, // glGetTexParameteriv + { 0x0000000140965B08, 0, (size_t)&glIsEnabledDLL, }, // glIsEnabled + { 0x0000000140965AC8, 0, (size_t)&glLightfvDLL, }, // glLightfv + { 0x0000000140965AC0, 0, (size_t)&glLightModelfvDLL, }, // glLightModelfv + { 0x0000000140965B10, 0, (size_t)&glLineWidthDLL, }, // glLineWidth + { 0x0000000140965C88, 0, (size_t)&glLoadIdentityDLL, }, // glLoadIdentity + { 0x0000000140965A50, 0, (size_t)&glLoadMatrixfDLL, }, // glLoadMatrixf + { 0x0000000140965A08, 0, (size_t)&glMaterialfDLL, }, // glMaterialf + { 0x0000000140965A80, 0, (size_t)&glMaterialfvDLL, }, // glMaterialfv + { 0x0000000140965C80, 0, (size_t)&glMatrixModeDLL, }, // glMatrixMode + { 0x0000000140965B48, 0, (size_t)&glMultMatrixdDLL, }, // glMultMatrixd + { 0x0000000140965B18, 0, (size_t)&glNormal3fDLL, }, // glNormal3f + { 0x0000000140965B20, 0, (size_t)&glNormalPointerDLL, }, // glNormalPointer + { 0x0000000140965B50, 0, (size_t)&glOrthoDLL, }, // glOrtho + { 0x0000000140965BA0, 0, (size_t)&glPixelStoreiDLL, }, // glPixelStorei + { 0x0000000140965BE0, 0, (size_t)&glPointSizeDLL, }, // glPointSize + { 0x0000000140965B98, 0, (size_t)&glPolygonModeDLL, }, // glPolygonMode + { 0x0000000140965BD8, 0, (size_t)&glPopAttribDLL, }, // glPopAttrib + { 0x0000000140965BD0, 0, (size_t)&glPopClientAttribDLL, }, // glPopClientAttrib + { 0x0000000140965CA8, 0, (size_t)&glPopMatrixDLL, }, // glPopMatrix + { 0x0000000140965BC8, 0, (size_t)&glPushAttribDLL, }, // glPushAttrib + { 0x0000000140965BC0, 0, (size_t)&glPushClientAttribDLL, }, // glPushClientAttrib + { 0x0000000140965CA0, 0, (size_t)&glPushMatrixDLL, }, // glPushMatrix + { 0x0000000140965B70, 0, (size_t)&glReadBufferDLL, }, // glReadBuffer + { 0x0000000140965B78, 0, (size_t)&glReadPixelsDLL, }, // glReadPixels + { 0x0000000140965C70, 0, (size_t)&glRotatefDLL, }, // glRotatef + { 0x0000000140965C68, 0, (size_t)&glScalefDLL, }, // glScalef + { 0x0000000140965C20, 0, (size_t)&glShadeModelDLL, }, // glShadeModel + { 0x0000000140965B80, 0, (size_t)&glTexCoord2fDLL, }, // glTexCoord2f + { 0x0000000140965A30, 0, (size_t)&glTexCoordPointerDLL, }, // glTexCoordPointer + { 0x0000000140965B28, 0, (size_t)&glTexEnvfDLL, }, // glTexEnvf + { 0x0000000140965BB8, 0, (size_t)&glTexEnviDLL, }, // glTexEnvi + { 0x0000000140965B58, 0, (size_t)&glTexImage1DDLL, }, // glTexImage1D + { 0x0000000140965AE0, 0, (size_t)&glTexImage2DDLL, }, // glTexImage2D + { 0x0000000140965AE8, 0, (size_t)&glTexParameterfDLL, }, // glTexParameterf + { 0x0000000140965A10, 0, (size_t)&glTexParameterfvDLL, }, // glTexParameterfv + { 0x0000000140965A18, 0, (size_t)&glTexParameteriDLL, }, // glTexParameteri + { 0x0000000140965AB0, 0, (size_t)&glTexSubImage2DDLL, }, // glTexSubImage2D + { 0x0000000140965C60, 0, (size_t)&glTranslatefDLL, }, // glTranslatef + { 0x0000000140965AB8, 0, (size_t)&glVertex3fDLL, }, // glVertex3f + { 0x0000000140965B30, 0, (size_t)&glVertex3fvDLL, }, // glVertex3fv + { 0x0000000140965B00, 0, (size_t)&glVertexPointerDLL, }, // glVertexPointer +}; + +func_struct wrap_addr[50] = { + { 0x00000001411A3DB8, 0, (size_t)&glActiveTexture, }, // glActiveTexture + { 0x00000001411A4B10, 0, (size_t)&glBindBufferARB, }, // glBindBufferARB + { 0x00000001411A3578, 0, (size_t)&glBindBufferBaseNV, }, // glBindBufferBaseNV + { 0x00000001411A54D8, 0, (size_t)&glBindFramebufferEXT, }, // glBindFramebufferEXT + { 0x00000001411A3818, 0, (size_t)&glBindMultiTextureEXT, }, // glBindMultiTextureEXT + { 0x00000001411A54A8, 0, (size_t)&glBindRenderbufferEXT, }, // glBindRenderbufferEXT + { 0x00000001411A4B30, 0, (size_t)&glBufferDataARB, }, // glBufferDataARB + { 0x00000001411A4D00, 0, (size_t)&glClampColorARB, }, // glClampColorARB + { 0x00000001411A3DC8, 0, (size_t)&glClientActiveTexture, }, // glClientActiveTexture + { 0x00000001411A37D0, 0, (size_t)&glCopyMultiTexSubImage2DEXT, }, // glCopyMultiTexSubImage2DEXT + { 0x00000001411A4B18, 0, (size_t)&glDeleteBuffersARB, }, // glDeleteBuffersARB + { 0x00000001411A54E0, 0, (size_t)&glDeleteFramebuffersEXT, }, // glDeleteFramebuffersEXT + { 0x00000001411A54B0, 0, (size_t)&glDeleteRenderbuffersEXT, }, // glDeleteRenderbuffersEXT + { 0x00000001411A1A30, 0, (size_t)&glDeleteTextures, }, // glDeleteTextures + { 0x00000001411A4A50, 0, (size_t)&glDisableVertexAttribArrayARB, }, // glDisableVertexAttribArrayARB + { 0x00000001411A3B78, 0, (size_t)&glDrawRangeElements, }, // glDrawRangeElements + { 0x00000001411A42A8, 0, (size_t)&glEnableVertexAttribArray, }, // glEnableVertexAttribArray + { 0x00000001411A4A48, 0, (size_t)&glEnableVertexAttribArrayARB, }, // glEnableVertexAttribArrayARB + { 0x00000001411A5510, 0, (size_t)&glFramebufferRenderbufferEXT, }, // glFramebufferRenderbufferEXT + { 0x00000001411A5500, 0, (size_t)&glFramebufferTexture2DEXT, }, // glFramebufferTexture2DEXT + { 0x00000001411A54E8, 0, (size_t)&glGenFramebuffersEXT, }, // glGenFramebuffersEXT + { 0x00000001411A54B8, 0, (size_t)&glGenRenderbuffersEXT, }, // glGenRenderbuffersEXT + { 0x00000001411A1A38, 0, (size_t)&glGenTextures, }, // glGenTextures + { 0x00000001411A4AC0, 0, (size_t)&glGetProgramEnvParameterfvARB, }, // glGetProgramEnvParameterfvARB + { 0x00000001411A4AD8, 0, (size_t)&glGetProgramivARB, }, // glGetProgramivARB + { 0x00000001411A3738, 0, (size_t)&glGetTextureImageEXT, }, // glGetTextureImageEXT + { 0x00000001411A4B28, 0, (size_t)&glIsBufferARB, }, // glIsBufferARB + { 0x00000001411A3FD8, 0, (size_t)&glLoadTransposeMatrixf, }, // glLoadTransposeMatrixf + { 0x00000001411A3B20, 0, (size_t)&glMapNamedBufferEXT, }, // glMapNamedBufferEXT + { 0x00000001411A3E78, 0, (size_t)&glMultiTexCoord2f, }, // glMultiTexCoord2f + { 0x00000001411A3E88, 0, (size_t)&glMultiTexCoord2fv, }, // glMultiTexCoord2fv + { 0x00000001411A3FE8, 0, (size_t)&glMultTransposeMatrixf, }, // glMultTransposeMatrixf + { 0x00000001411A3B10, 0, (size_t)&glNamedBufferDataEXT, }, // glNamedBufferDataEXT + { 0x00000001411A3B18, 0, (size_t)&glNamedBufferSubDataEXT, }, // glNamedBufferSubDataEXT + { 0x00000001411A4078, 0, (size_t)&glPointParameterf, }, // glPointParameterf + { 0x00000001411A4080, 0, (size_t)&glPointParameterfv, }, // glPointParameterfv + { 0x00000001411A4088, 0, (size_t)&glPointParameteri, }, // glPointParameteri + { 0x00000001411A5488, 0, (size_t)&glPrimitiveRestartIndexNV, }, // glPrimitiveRestartIndexNV + { 0x00000001411A3508, 0, (size_t)&glProgramBufferParametersfvNV, }, // glProgramBufferParametersfvNV + { 0x00000001411A4A88, 0, (size_t)&glProgramEnvParameter4fARB, }, // glProgramEnvParameter4fARB + { 0x00000001411A4A90, 0, (size_t)&glProgramEnvParameter4fvARB, }, // glProgramEnvParameter4fvARB + { 0x00000001411A5548, 0, (size_t)&glProgramEnvParameters4fvEXT, }, // glProgramEnvParameters4fvEXT + { 0x00000001411A4AA8, 0, (size_t)&glProgramLocalParameter4fARB, }, // glProgramLocalParameter4fARB + { 0x00000001411A4AB0, 0, (size_t)&glProgramLocalParameter4fvARB, }, // glProgramLocalParameter4fvARB + { 0x00000001411A5550, 0, (size_t)&glProgramLocalParameters4fvEXT, }, // glProgramLocalParameters4fvEXT + { 0x00000001411A54C0, 0, (size_t)&glRenderbufferStorageEXT, }, // glRenderbufferStorageEXT + { 0x00000001411A3500, 0, (size_t)&glRenderbufferStorageMultisampleCoverageNV, }, // glRenderbufferStorageMultisampleCoverageNV + { 0x00000001411A3B28, 0, (size_t)&glUnmapNamedBufferEXT, }, // glUnmapNamedBufferEXT + { 0x00000001411A4350, 0, (size_t)&glUseProgram, }, // glUseProgram + { 0x00000001411A4A40, 0, (size_t)&glVertexAttribPointerARB, }, // glVertexAttribPointerARB +}; + +func_struct wrap_addr_glut[27] = { + { 0x000000000002A380, 0, (size_t)&glBeginGLUT, }, // glBegin + { 0x000000000002A348, 0, (size_t)&glBitmapGLUT, }, // glBitmap + { 0x000000000002A370, 0, (size_t)&glDrawBufferGLUT, }, // glDrawBuffer + { 0x000000000002A3D8, 0, (size_t)&glEnableGLUT, }, // glEnable + { 0x000000000002A388, 0, (size_t)&glEndGLUT, }, // glEnd + { 0x000000000002A3E0, 0, (size_t)&glEvalMesh2GLUT, }, // glEvalMesh2 + { 0x000000000002A418, 0, (size_t)&glGetErrorGLUT, }, // glGetError + { 0x000000000002A450, 0, (size_t)&glGetIntegervGLUT, }, // glGetIntegerv + { 0x000000000002A360, 0, (size_t)&glGetStringGLUT, }, // glGetString + { 0x000000000002A3E8, 0, (size_t)&glMap2fGLUT, }, // glMap2f + { 0x000000000002A3F0, 0, (size_t)&glMapGrid2fGLUT, }, // glMapGrid2f + { 0x000000000002A390, 0, (size_t)&glNormal3fGLUT, }, // glNormal3f + { 0x000000000002A398, 0, (size_t)&glNormal3fvGLUT, }, // glNormal3fv + { 0x000000000002A350, 0, (size_t)&glPixelStoreiGLUT, }, // glPixelStorei + { 0x000000000002A3A0, 0, (size_t)&glPolygonModeGLUT, }, // glPolygonMode + { 0x000000000002A3A8, 0, (size_t)&glPopAttribGLUT, }, // glPopAttrib + { 0x000000000002A3F8, 0, (size_t)&glPopMatrixGLUT, }, // glPopMatrix + { 0x000000000002A3B0, 0, (size_t)&glPushAttribGLUT, }, // glPushAttrib + { 0x000000000002A400, 0, (size_t)&glPushMatrixGLUT, }, // glPushMatrix + { 0x000000000002A378, 0, (size_t)&glReadBufferGLUT, }, // glReadBuffer + { 0x000000000002A408, 0, (size_t)&glRotatefGLUT, }, // glRotatef + { 0x000000000002A410, 0, (size_t)&glScalefGLUT, }, // glScalef + { 0x000000000002A3C8, 0, (size_t)&glTranslatefGLUT, }, // glTranslatef + { 0x000000000002A3D0, 0, (size_t)&glVertex2fGLUT, }, // glVertex2f + { 0x000000000002A3B8, 0, (size_t)&glVertex3fGLUT, }, // glVertex3f + { 0x000000000002A3C0, 0, (size_t)&glVertex3fvGLUT, }, // glVertex3fv + { 0x000000000002A440, 0, (size_t)&wglCreateContextGLUT, }, // wglCreateContext +}; + +gl_func_struct gl_addr_dll[9] = { + { 0x0000000140965A20, 0, }, // glBlendFunc + { 0x0000000140965A38, 0, }, // glColorMask + { 0x0000000140965AD0, 0, }, // glDeleteTextures + { 0x0000000140965A28, 0, }, // glDepthMask + { 0x0000000140965B68, 0, }, // glFinish + { 0x0000000140965AD8, 0, }, // glGenTextures + { 0x0000000140965A40, 0, }, // glScissor + { 0x0000000140965C78, 0, }, // glViewport + { 0x0000000140965B38, 0, }, // wglGetProcAddress +}; + +gl_func_struct gl_addr[1057] = { + { 0x00000001411A52D0, 0, }, // glActiveStencilFaceEXT + { 0x00000001411A4720, 0, }, // glActiveTextureARB + { 0x00000001411A3588, 0, }, // glActiveVaryingNV + { 0x00000001411A5088, 0, }, // glAreProgramsResidentNV + { 0x00000001411A4E30, 0, }, // glAreTexturesResidentEXT + { 0x00000001411A4E60, 0, }, // glArrayElementEXT + { 0x00000001411A4BE0, 0, }, // glAttachObjectARB + { 0x00000001411A4260, 0, }, // glAttachShader + { 0x00000001411A45B0, 0, }, // glBeginConditionalRender + { 0x00000001411A35F0, 0, }, // glBeginConditionalRenderNV + { 0x00000001411A52A0, 0, }, // glBeginOcclusionQueryNV + { 0x00000001411A41B8, 0, }, // glBeginQuery + { 0x00000001411A4B80, 0, }, // glBeginQueryARB + { 0x00000001411A4580, 0, }, // glBeginTransformFeedback + { 0x00000001411A3550, 0, }, // glBeginTransformFeedbackNV + { 0x00000001411A4268, 0, }, // glBindAttribLocation + { 0x00000001411A4CE0, 0, }, // glBindAttribLocationARB + { 0x00000001411A41E0, 0, }, // glBindBuffer + { 0x0000001411A4598, 0, }, // glBindBufferBase + { 0x00000001411A3570, 0, }, // glBindBufferOffsetNV + { 0x00000001411A4590, 0, }, // glBindBufferRange + { 0x00000001411A3568, 0, }, // glBindBufferRangeNV + { 0x00000001411A4680, 0, }, // glBindFragDataLocation + { 0x00000001411A56C0, 0, }, // glBindFragDataLocationEXT + { 0x00000001411A4D50, 0, }, // glBindFramebuffer + { 0x00000001411A4A60, 0, }, // glBindProgramARB + { 0x00000001411A5090, 0, }, // glBindProgramNV + { 0x00000001411A4D20, 0, }, // glBindRenderbuffer + { 0x00000001411A3FA0, 0, }, // glBindSampler + { 0x00000001411A4E38, 0, }, // glBindTextureEXT + { 0x00000001411A4DF0, 0, }, // glBindVertexArray + { 0x00000001411A3B58, 0, }, // glBlendColor + { 0x00000001411A4E10, 0, }, // glBlendColorEXT + { 0x00000001411A3B68, 0, }, // glBlendEquation + { 0x00000001411A4EA8, 0, }, // glBlendEquationEXT + { 0x00000001411A4238, 0, }, // glBlendEquationSeparate + { 0x00000001411A5498, 0, }, // glBlendEquationSeparateEXT + { 0x00000001411A4038, 0, }, // glBlendFuncSeparate + { 0x00000001411A4FC0, 0, }, // glBlendFuncSeparateEXT + { 0x00000001411A4DA0, 0, }, // glBlitFramebuffer + { 0x00000001411A5528, 0, }, // glBlitFramebufferEXT + { 0x00000001411A4200, 0, }, // glBufferData + { 0x00000001411A4208, 0, }, // glBufferSubData + { 0x00000001411A4B38, 0, }, // glBufferSubDataARB + { 0x00000001411A4D68, 0, }, // glCheckFramebufferStatus + { 0x00000001411A54F0, 0, }, // glCheckFramebufferStatusEXT + { 0x00000001411A3B80, 0, }, // glCheckNamedFramebufferStatusEXT + { 0x00000001411A4708, 0, }, // glClearBufferfi + { 0x00000001411A4700, 0, }, // glClearBufferfv + { 0x00000001411A46F0, 0, }, // glClearBufferiv + { 0x00000001411A46F8, 0, }, // glClearBufferuiv + { 0x00000001411A35E0, 0, }, // glClearColorIiEXT + { 0x00000001411A35E8, 0, }, // glClearColorIuiEXT + { 0x00000001411A34F0, 0, }, // glClearDepthdNV + { 0x00000001411A4728, 0, }, // glClientActiveTextureARB + { 0x00000001411A3630, 0, }, // glClientAttribDefaultEXT + { 0x00000001411A5350, 0, }, // glColor3hNV + { 0x00000001411A5358, 0, }, // glColor3hvNV + { 0x00000001411A5360, 0, }, // glColor4hNV + { 0x00000001411A5368, 0, }, // glColor4hvNV + { 0x00000001411A4550, 0, }, // glColorMaski + { 0x00000001411A3520, 0, }, // glColorMaskIndexedEXT + { 0x00000001411A4E68, 0, }, // glColorPointerEXT + { 0x00000001411A3BF8, 0, }, // glColorSubTable + { 0x00000001411A4EC0, 0, }, // glColorSubTableEXT + { 0x00000001411A3B88, 0, }, // glColorTable + { 0x00000001411A4EC8, 0, }, // glColorTableEXT + { 0x00000001411A3B98, 0, }, // glColorTableParameterfv + { 0x00000001411A3BA8, 0, }, // glColorTableParameteriv + { 0x00000001411A4FF8, 0, }, // glCombinerInputNV + { 0x00000001411A5000, 0, }, // glCombinerOutputNV + { 0x00000001411A4FE0, 0, }, // glCombinerParameterfNV + { 0x00000001411A4FD8, 0, }, // glCombinerParameterfvNV + { 0x00000001411A4FF0, 0, }, // glCombinerParameteriNV + { 0x00000001411A4FE8, 0, }, // glCombinerParameterivNV + { 0x00000001411A5078, 0, }, // glCombinerStageParameterfvNV + { 0x00000001411A4270, 0, }, // glCompileShader + { 0x00000001411A4BD0, 0, }, // glCompileShaderARB + { 0x00000001411A3910, 0, }, // glCompressedMultiTexImage1DEXT + { 0x00000001411A3908, 0, }, // glCompressedMultiTexImage2DEXT + { 0x00000001411A3900, 0, }, // glCompressedMultiTexImage3DEXT + { 0x00000001411A3928, 0, }, // glCompressedMultiTexSubImage1DEXT + { 0x00000001411A3920, 0, }, // glCompressedMultiTexSubImage2DEXT + { 0x00000001411A3918, 0, }, // glCompressedMultiTexSubImage3DEXT + { 0x00000001411A4010, 0, }, // glCompressedTexImage1D + { 0x00000001411A4868, 0, }, // glCompressedTexImage1DARB + { 0x00000001411A4008, 0, }, // glCompressedTexImage2D + { 0x00000001411A4860, 0, }, // glCompressedTexImage2DARB + { 0x00000001411A4000, 0, }, // glCompressedTexImage3D + { 0x00000001411A4858, 0, }, // glCompressedTexImage3DARB + { 0x00000001411A4028, 0, }, // glCompressedTexSubImage1D + { 0x00000001411A4880, 0, }, // glCompressedTexSubImage1DARB + { 0x00000001411A4020, 0, }, // glCompressedTexSubImage2D + { 0x00000001411A4878, 0, }, // glCompressedTexSubImage2DARB + { 0x00000001411A4018, 0, }, // glCompressedTexSubImage3D + { 0x00000001411A4870, 0, }, // glCompressedTexSubImage3DARB + { 0x00000001411A38D8, 0, }, // glCompressedTextureImage1DEXT + { 0x00000001411A38D0, 0, }, // glCompressedTextureImage2DEXT + { 0x00000001411A38C8, 0, }, // glCompressedTextureImage3DEXT + { 0x00000001411A38F0, 0, }, // glCompressedTextureSubImage1DEXT + { 0x00000001411A38E8, 0, }, // glCompressedTextureSubImage2DEXT + { 0x00000001411A38E0, 0, }, // glCompressedTextureSubImage3DEXT + { 0x00000001411A3C18, 0, }, // glConvolutionFilter1D + { 0x00000001411A3C28, 0, }, // glConvolutionFilter2D + { 0x00000001411A3C38, 0, }, // glConvolutionParameterf + { 0x00000001411A3C48, 0, }, // glConvolutionParameterfv + { 0x00000001411A3C58, 0, }, // glConvolutionParameteri + { 0x00000001411A3C68, 0, }, // glConvolutionParameteriv + { 0x00000001411A3C08, 0, }, // glCopyColorSubTable + { 0x00000001411A3BB8, 0, }, // glCopyColorTable + { 0x00000001411A3C78, 0, }, // glCopyConvolutionFilter1D + { 0x00000001411A3C88, 0, }, // glCopyConvolutionFilter2D + { 0x00000001411A4718, 0, }, // glCopyImageSubData + { 0x00000001411A37B8, 0, }, // glCopyMultiTexImage1DEXT + { 0x00000001411A37C0, 0, }, // glCopyMultiTexImage2DEXT + { 0x00000001411A37C8, 0, }, // glCopyMultiTexSubImage1DEXT + { 0x00000001411A3810, 0, }, // glCopyMultiTexSubImage3DEXT + { 0x00000001411A3DA8, 0, }, // glCopyTexSubImage3D + { 0x00000001411A4E28, 0, }, // glCopyTexSubImage3DEXT + { 0x00000001411A3718, 0, }, // glCopyTextureImage1DEXT + { 0x00000001411A3720, 0, }, // glCopyTextureImage2DEXT + { 0x00000001411A3728, 0, }, // glCopyTextureSubImage1DEXT + { 0x00000001411A3730, 0, }, // glCopyTextureSubImage2DEXT + { 0x00000001411A3770, 0, }, // glCopyTextureSubImage3DEXT + { 0x00000001411A4278, 0, }, // glCreateProgram + { 0x00000001411A4BD8, 0, }, // glCreateProgramObjectARB + { 0x00000001411A4280, 0, }, // glCreateShader + { 0x00000001411A4BC0, 0, }, // glCreateShaderObjectARB + { 0x00000001411A41E8, 0, }, // glDeleteBuffers + { 0x00000001411A5040, 0, }, // glDeleteFencesNV + { 0x00000001411A4D58, 0, }, // glDeleteFramebuffers + { 0x00000001411A4BA8, 0, }, // glDeleteObjectARB + { 0x00000001411A5290, 0, }, // glDeleteOcclusionQueriesNV + { 0x00000001411A4288, 0, }, // glDeleteProgram + { 0x00000001411A4A68, 0, }, // glDeleteProgramsARB + { 0x00000001411A5098, 0, }, // glDeleteProgramsNV + { 0x00000001411A41A8, 0, }, // glDeleteQueries + { 0x00000001411A4B70, 0, }, // glDeleteQueriesARB + { 0x00000001411A4D28, 0, }, // glDeleteRenderbuffers + { 0x00000001411A3F90, 0, }, // glDeleteSamplers + { 0x00000001411A4290, 0, }, // glDeleteShader + { 0x00000001411A4E40, 0, }, // glDeleteTexturesEXT + { 0x00000001411A4DF8, 0, }, // glDeleteVertexArrays + { 0x00000001411A34F8, 0, }, // glDepthBoundsdNV + { 0x00000001411A5490, 0, }, // glDepthBoundsEXT + { 0x00000001411A34E8, 0, }, // glDepthRangedNV + { 0x00000001411A4BB8, 0, }, // glDetachObjectARB + { 0x00000001411A4298, 0, }, // glDetachShader + { 0x00000001411A3828, 0, }, // glDisableClientStateIndexedEXT + { 0x00000001411A4570, 0, }, // glDisablei + { 0x00000001411A3540, 0, }, // glDisableIndexedEXT + { 0x00000001411A42A0, 0, }, // glDisableVertexAttribArray + { 0x00000001411A4E70, 0, }, // glDrawArraysEXT + { 0x00000001411A4D08, 0, }, // glDrawArraysInstancedARB + { 0x00000001411A5710, 0, }, // glDrawArraysInstancedEXT + { 0x00000001411A4240, 0, }, // glDrawBuffers + { 0x00000001411A4CF8, 0, }, // glDrawBuffersARB + { 0x00000001411A52D8, 0, }, // glDrawBuffersATI + { 0x00000001411A4D10, 0, }, // glDrawElementsInstancedARB + { 0x00000001411A5718, 0, }, // glDrawElementsInstancedEXT + { 0x00000001411A4EF8, 0, }, // glDrawRangeElementsEXT + { 0x00000001411A4E78, 0, }, // glEdgeFlagPointerEXT + { 0x00000001411A3820, 0, }, // glEnableClientStateIndexedEXT + { 0x00000001411A4568, 0, }, // glEnablei + { 0x00000001411A3538, 0, }, // glEnableIndexedEXT + { 0x00000001411A45B8, 0, }, // glEndConditionalRender + { 0x00000001411A35F8, 0, }, // glEndConditionalRenderNV + { 0x00000001411A52A8, 0, }, // glEndOcclusionQueryNV + { 0x00000001411A41C0, 0, }, // glEndQuery + { 0x00000001411A4B88, 0, }, // glEndQueryARB + { 0x00000001411A4588, 0, }, // glEndTransformFeedback + { 0x00000001411A3558, 0, }, // glEndTransformFeedbackNV + { 0x00000001411A50A0, 0, }, // glExecuteProgramNV + { 0x00000001411A5008, 0, }, // glFinalCombinerInputNV + { 0x00000001411A5068, 0, }, // glFinishFenceNV + { 0x00000001411A4DE0, 0, }, // glFlushMappedBufferRange + { 0x00000001411A5478, 0, }, // glFlushPixelDataRangeNV + { 0x00000001411A4FC8, 0, }, // glFlushVertexArrayRangeNV + { 0x00000001411A4050, 0, }, // glFogCoordd + { 0x00000001411A4FA8, 0, }, // glFogCoorddEXT + { 0x00000001411A4058, 0, }, // glFogCoorddv + { 0x00000001411A4FB0, 0, }, // glFogCoorddvEXT + { 0x00000001411A4040, 0, }, // glFogCoordf + { 0x00000001411A4F98, 0, }, // glFogCoordfEXT + { 0x00000001411A4048, 0, }, // glFogCoordfv + { 0x00000001411A4FA0, 0, }, // glFogCoordfvEXT + { 0x00000001411A53F0, 0, }, // glFogCoordhNV + { 0x00000001411A53F8, 0, }, // glFogCoordhvNV + { 0x00000001411A4060, 0, }, // glFogCoordPointer + { 0x00000001411A4FB8, 0, }, // glFogCoordPointerEXT + { 0x00000001411A3C00, 0, }, // glFramebufferDrawBufferEXT + { 0x00000001411A3C10, 0, }, // glFramebufferDrawBuffersEXT + { 0x00000001411A3C20, 0, }, // glFramebufferReadBufferEXT + { 0x00000001411A4D88, 0, }, // glFramebufferRenderbuffer + { 0x00000001411A3F50, 0, }, // glFramebufferTexture + { 0x00000001411A4D70, 0, }, // glFramebufferTexture1D + { 0x00000001411A54F8, 0, }, // glFramebufferTexture1DEXT + { 0x00000001411A4D78, 0, }, // glFramebufferTexture2D + { 0x00000001411A4D80, 0, }, // glFramebufferTexture3D + { 0x00000001411A5508, 0, }, // glFramebufferTexture3DEXT + { 0x00000001411A4DC0, 0, }, // glFramebufferTextureARB + { 0x00000001411A55E0, 0, }, // glFramebufferTextureEXT + { 0x00000001411A4DD0, 0, }, // glFramebufferTextureFaceARB + { 0x00000001411A55F0, 0, }, // glFramebufferTextureFaceEXT + { 0x00000001411A4DB0, 0, }, // glFramebufferTextureLayer + { 0x00000001411A4DC8, 0, }, // glFramebufferTextureLayerARB + { 0x00000001411A55E8, 0, }, // glFramebufferTextureLayerEXT + { 0x00000001411A41F0, 0, }, // glGenBuffers + { 0x00000001411A4B20, 0, }, // glGenBuffersARB + { 0x00000001411A4D98, 0, }, // glGenerateMipmap + { 0x00000001411A5520, 0, }, // glGenerateMipmapEXT + { 0x00000001411A3BF0, 0, }, // glGenerateMultiTexMipmapEXT + { 0x00000001411A3BE0, 0, }, // glGenerateTextureMipmapEXT + { 0x00000001411A5048, 0, }, // glGenFencesNV + { 0x00000001411A4D60, 0, }, // glGenFramebuffers + { 0x00000001411A5288, 0, }, // glGenOcclusionQueriesNV + { 0x00000001411A4A70, 0, }, // glGenProgramsARB + { 0x00000001411A50A8, 0, }, // glGenProgramsNV + { 0x00000001411A41A0, 0, }, // glGenQueries + { 0x00000001411A4B68, 0, }, // glGenQueriesARB + { 0x00000001411A4D30, 0, }, // glGenRenderbuffers + { 0x00000001411A3F80, 0, }, // glGenSamplers + { 0x00000001411A4E48, 0, }, // glGenTexturesEXT + { 0x00000001411A4E00, 0, }, // glGenVertexArrays + { 0x00000001411A42B0, 0, }, // glGetActiveAttrib + { 0x00000001411A4CE8, 0, }, // glGetActiveAttribARB + { 0x00000001411A42B8, 0, }, // glGetActiveUniform + { 0x00000001411A4CC0, 0, }, // glGetActiveUniformARB + { 0x00000001411A3598, 0, }, // glGetActiveVaryingNV + { 0x00000001411A4CB0, 0, }, // glGetAttachedObjectsARB + { 0x00000001411A42C0, 0, }, // glGetAttachedShaders + { 0x00000001411A42C8, 0, }, // glGetAttribLocation + { 0x00000001411A4CF0, 0, }, // glGetAttribLocationARB + { 0x00000001411A4558, 0, }, // glGetBooleani_v + { 0x00000001411A3528, 0, }, // glGetBooleanIndexedvEXT + { 0x00000001411A4228, 0, }, // glGetBufferParameteriv + { 0x00000001411A4B58, 0, }, // glGetBufferParameterivARB + { 0x00000001411A4230, 0, }, // glGetBufferPointerv + { 0x00000001411A4B60, 0, }, // glGetBufferPointervARB + { 0x00000001411A4210, 0, }, // glGetBufferSubData + { 0x00000001411A4B40, 0, }, // glGetBufferSubDataARB + { 0x00000001411A3BC8, 0, }, // glGetColorTable + { 0x00000001411A4ED0, 0, }, // glGetColorTableEXT + { 0x00000001411A3BD8, 0, }, // glGetColorTableParameterfv + { 0x00000001411A4EE0, 0, }, // glGetColorTableParameterfvEXT + { 0x00000001411A3BE8, 0, }, // glGetColorTableParameteriv + { 0x00000001411A4ED8, 0, }, // glGetColorTableParameterivEXT + { 0x00000001411A5010, 0, }, // glGetCombinerInputParameterfvNV + { 0x00000001411A5018, 0, }, // glGetCombinerInputParameterivNV + { 0x00000001411A5020, 0, }, // glGetCombinerOutputParameterfvNV + { 0x00000001411A5028, 0, }, // glGetCombinerOutputParameterivNV + { 0x00000001411A5080, 0, }, // glGetCombinerStageParameterfvNV + { 0x00000001411A3930, 0, }, // glGetCompressedMultiTexImageEXT + { 0x00000001411A4030, 0, }, // glGetCompressedTexImage + { 0x00000001411A4888, 0, }, // glGetCompressedTexImageARB + { 0x00000001411A38F8, 0, }, // glGetCompressedTextureImageEXT + { 0x00000001411A3C98, 0, }, // glGetConvolutionFilter + { 0x00000001411A3CA8, 0, }, // glGetConvolutionParameterfv + { 0x00000001411A3CB8, 0, }, // glGetConvolutionParameteriv + { 0x00000001411A38B8, 0, }, // glGetDoubleIndexedvEXT + { 0x00000001411A5060, 0, }, // glGetFenceivNV + { 0x00000001411A5030, 0, }, // glGetFinalCombinerInputParameterfvNV + { 0x00000001411A5038, 0, }, // glGetFinalCombinerInputParameterivNV + { 0x00000001411A38B0, 0, }, // glGetFloatIndexedvEXT + { 0x00000001411A4688, 0, }, // glGetFragDataLocation + { 0x00000001411A56C8, 0, }, // glGetFragDataLocationEXT + { 0x00000001411A4D90, 0, }, // glGetFramebufferAttachmentParameteriv + { 0x00000001411A5518, 0, }, // glGetFramebufferAttachmentParameterivEXT + { 0x00000001411A3C30, 0, }, // glGetFramebufferParameterivEXT + { 0x00000001411A4BB0, 0, }, // glGetHandleARB + { 0x00000001411A3CE8, 0, }, // glGetHistogram + { 0x00000001411A3CF8, 0, }, // glGetHistogramParameterfv + { 0x00000001411A3D08, 0, }, // glGetHistogramParameteriv + { 0x00000001411A4CA8, 0, }, // glGetInfoLogARB + { 0x00000001411A4560, 0, }, // glGetIntegeri_v + { 0x00000001411A3530, 0, }, // glGetIntegerIndexedvEXT + { 0x00000001411A3D18, 0, }, // glGetMinmax + { 0x00000001411A3D28, 0, }, // glGetMinmaxParameterfv + { 0x00000001411A3D38, 0, }, // glGetMinmaxParameteriv + { 0x00000001411A3CB0, 0, }, // glGetMultisamplefvNV + { 0x00000001411A3888, 0, }, // glGetMultiTexEnvfvEXT + { 0x00000001411A3890, 0, }, // glGetMultiTexEnvivEXT + { 0x00000001411A3898, 0, }, // glGetMultiTexGendvEXT + { 0x00000001411A38A0, 0, }, // glGetMultiTexGenfvEXT + { 0x00000001411A38A8, 0, }, // glGetMultiTexGenivEXT + { 0x00000001411A37D8, 0, }, // glGetMultiTexImageEXT + { 0x00000001411A37F0, 0, }, // glGetMultiTexLevelParameterfvEXT + { 0x00000001411A37F8, 0, }, // glGetMultiTexLevelParameterivEXT + { 0x00000001411A37E0, 0, }, // glGetMultiTexParameterfvEXT + { 0x00000001411A39F8, 0, }, // glGetMultiTexParameterIivEXT + { 0x00000001411A3A00, 0, }, // glGetMultiTexParameterIuivEXT + { 0x00000001411A37E8, 0, }, // glGetMultiTexParameterivEXT + { 0x00000001411A3B30, 0, }, // glGetNamedBufferParameterivEXT + { 0x00000001411A3B38, 0, }, // glGetNamedBufferPointervEXT + { 0x00000001411A3B40, 0, }, // glGetNamedBufferSubDataEXT + { 0x00000001411A3BD0, 0, }, // glGetNamedFramebufferAttachmentParameterivEXT + { 0x00000001411A3970, 0, }, // glGetNamedProgramivEXT + { 0x00000001411A3960, 0, }, // glGetNamedProgramLocalParameterdvEXT + { 0x00000001411A3968, 0, }, // glGetNamedProgramLocalParameterfvEXT + { 0x00000001411A39B8, 0, }, // glGetNamedProgramLocalParameterIivEXT + { 0x00000001411A39C0, 0, }, // glGetNamedProgramLocalParameterIuivEXT + { 0x00000001411A3978, 0, }, // glGetNamedProgramStringEXT + { 0x00000001411A3B70, 0, }, // glGetNamedRenderbufferParameterivEXT + { 0x00000001411A4C98, 0, }, // glGetObjectParameterfvARB + { 0x00000001411A4CA0, 0, }, // glGetObjectParameterivARB + { 0x00000001411A52B0, 0, }, // glGetOcclusionQueryivNV + { 0x00000001411A52B8, 0, }, // glGetOcclusionQueryuivNV + { 0x00000001411A38C0, 0, }, // glGetPointerIndexedvEXT + { 0x00000001411A4E80, 0, }, // glGetPointervEXT + { 0x00000001411A4AB8, 0, }, // glGetProgramEnvParameterdvARB + { 0x00000001411A55C8, 0, }, // glGetProgramEnvParameterIivNV + { 0x00000001411A55D0, 0, }, // glGetProgramEnvParameterIuivNV + { 0x00000001411A42D8, 0, }, // glGetProgramInfoLog + { 0x00000001411A42D0, 0, }, // glGetProgramiv + { 0x00000001411A50C0, 0, }, // glGetProgramivNV + { 0x00000001411A4AC8, 0, }, // glGetProgramLocalParameterdvARB + { 0x00000001411A4AD0, 0, }, // glGetProgramLocalParameterfvARB + { 0x00000001411A55B8, 0, }, // glGetProgramLocalParameterIivNV + { 0x00000001411A55C0, 0, }, // glGetProgramLocalParameterIuivNV + { 0x00000001411A5308, 0, }, // glGetProgramNamedParameterdvNV + { 0x00000001411A5300, 0, }, // glGetProgramNamedParameterfvNV + { 0x00000001411A50B0, 0, }, // glGetProgramParameterdvNV + { 0x00000001411A50B8, 0, }, // glGetProgramParameterfvNV + { 0x00000001411A4AE0, 0, }, // glGetProgramStringARB + { 0x00000001411A50C8, 0, }, // glGetProgramStringNV + { 0x00000001411A41C8, 0, }, // glGetQueryiv + { 0x00000001411A4B90, 0, }, // glGetQueryivARB + { 0x00000001411A5538, 0, }, // glGetQueryObjecti64vEXT + { 0x00000001411A41D0, 0, }, // glGetQueryObjectiv + { 0x00000001411A4B98, 0, }, // glGetQueryObjectivARB + { 0x00000001411A3F40, 0, }, // glGetQueryObjectui64v + { 0x00000001411A5540, 0, }, // glGetQueryObjectui64vEXT + { 0x00000001411A41D8, 0, }, // glGetQueryObjectuiv + { 0x00000001411A4BA0, 0, }, // glGetQueryObjectuivARB + { 0x00000001411A4D40, 0, }, // glGetRenderbufferParameteriv + { 0x00000001411A54C8, 0, }, // glGetRenderbufferParameterivEXT + { 0x00000001411A3CC8, 0, }, // glGetSeparableFilter + { 0x00000001411A42E8, 0, }, // glGetShaderInfoLog + { 0x00000001411A42E0, 0, }, // glGetShaderiv + { 0x00000001411A42F0, 0, }, // glGetShaderSource + { 0x00000001411A4CD8, 0, }, // glGetShaderSourceARB + { 0x00000001411A4710, 0, }, // glGetStringi + { 0x00000001411A46E0, 0, }, // glGetTexParameterIiv + { 0x00000001411A35D0, 0, }, // glGetTexParameterIivEXT + { 0x00000001411A46E8, 0, }, // glGetTexParameterIuiv + { 0x00000001411A35D8, 0, }, // glGetTexParameterIuivEXT + { 0x00000001411A3750, 0, }, // glGetTextureLevelParameterfvEXT + { 0x00000001411A3758, 0, }, // glGetTextureLevelParameterivEXT + { 0x00000001411A3740, 0, }, // glGetTextureParameterfvEXT + { 0x00000001411A39D8, 0, }, // glGetTextureParameterIivEXT + { 0x00000001411A39E0, 0, }, // glGetTextureParameterIuivEXT + { 0x00000001411A3748, 0, }, // glGetTextureParameterivEXT + { 0x00000001411A50D0, 0, }, // glGetTrackMatrixivNV + { 0x00000001411A45A8, 0, }, // glGetTransformFeedbackVarying + { 0x00000001411A35A0, 0, }, // glGetTransformFeedbackVaryingNV + { 0x00000001411A35B0, 0, }, // glGetUniformBufferSizeEXT + { 0x00000001411A4300, 0, }, // glGetUniformfv + { 0x00000001411A4CC8, 0, }, // glGetUniformfvARB + { 0x00000001411A4308, 0, }, // glGetUniformiv + { 0x00000001411A4CD0, 0, }, // glGetUniformivARB + { 0x00000001411A42F8, 0, }, // glGetUniformLocation + { 0x00000001411A4CB8, 0, }, // glGetUniformLocationARB + { 0x00000001411A35B8, 0, }, // glGetUniformOffsetEXT + { 0x00000001411A4678, 0, }, // glGetUniformuiv + { 0x00000001411A56B8, 0, }, // glGetUniformuivEXT + { 0x00000001411A3590, 0, }, // glGetVaryingLocationNV + { 0x00000001411A4310, 0, }, // glGetVertexAttribdv + { 0x00000001411A4AE8, 0, }, // glGetVertexAttribdvARB + { 0x00000001411A50D8, 0, }, // glGetVertexAttribdvNV + { 0x00000001411A4318, 0, }, // glGetVertexAttribfv + { 0x00000001411A4AF0, 0, }, // glGetVertexAttribfvARB + { 0x00000001411A50E0, 0, }, // glGetVertexAttribfvNV + { 0x00000001411A4668, 0, }, // glGetVertexAttribIiv + { 0x00000001411A56A8, 0, }, // glGetVertexAttribIivEXT + { 0x00000001411A4670, 0, }, // glGetVertexAttribIuiv + { 0x00000001411A56B0, 0, }, // glGetVertexAttribIuivEXT + { 0x00000001411A4320, 0, }, // glGetVertexAttribiv + { 0x00000001411A4AF8, 0, }, // glGetVertexAttribivARB + { 0x00000001411A50E8, 0, }, // glGetVertexAttribivNV + { 0x00000001411A4328, 0, }, // glGetVertexAttribPointerv + { 0x00000001411A4B00, 0, }, // glGetVertexAttribPointervARB + { 0x00000001411A50F0, 0, }, // glGetVertexAttribPointervNV + { 0x00000001411A3620, 0, }, // glGetVideoi64vNV + { 0x00000001411A3610, 0, }, // glGetVideoivNV + { 0x00000001411A3628, 0, }, // glGetVideoui64vNV + { 0x00000001411A3618, 0, }, // glGetVideouivNV + { 0x00000001411A3D48, 0, }, // glHistogram + { 0x00000001411A4E88, 0, }, // glIndexPointerEXT + { 0x00000001411A41F8, 0, }, // glIsBuffer + { 0x00000001411A4578, 0, }, // glIsEnabledi + { 0x00000001411A3548, 0, }, // glIsEnabledIndexedEXT + { 0x00000001411A5050, 0, }, // glIsFenceNV + { 0x00000001411A4D48, 0, }, // glIsFramebuffer + { 0x00000001411A54D0, 0, }, // glIsFramebufferEXT + { 0x00000001411A5298, 0, }, // glIsOcclusionQueryNV + { 0x00000001411A4330, 0, }, // glIsProgram + { 0x00000001411A4B08, 0, }, // glIsProgramARB + { 0x00000001411A50F8, 0, }, // glIsProgramNV + { 0x00000001411A41B0, 0, }, // glIsQuery + { 0x00000001411A4B78, 0, }, // glIsQueryARB + { 0x00000001411A4D18, 0, }, // glIsRenderbuffer + { 0x00000001411A54A0, 0, }, // glIsRenderbufferEXT + { 0x00000001411A4338, 0, }, // glIsShader + { 0x00000001411A4E50, 0, }, // glIsTextureEXT + { 0x00000001411A4E08, 0, }, // glIsVertexArray + { 0x00000001411A4340, 0, }, // glLinkProgram + { 0x00000001411A4BE8, 0, }, // glLinkProgramARB + { 0x00000001411A5100, 0, }, // glLoadProgramNV + { 0x00000001411A3FE0, 0, }, // glLoadTransposeMatrixd + { 0x00000001411A4838, 0, }, // glLoadTransposeMatrixdARB + { 0x00000001411A4830, 0, }, // glLoadTransposeMatrixfARB + { 0x00000001411A4EE8, 0, }, // glLockArraysEXT + { 0x00000001411A4218, 0, }, // glMapBuffer + { 0x00000001411A4B48, 0, }, // glMapBufferARB + { 0x00000001411A4DD8, 0, }, // glMapBufferRange + { 0x00000001411A3698, 0, }, // glMatrixFrustumEXT + { 0x00000001411A3648, 0, }, // glMatrixLoaddEXT + { 0x00000001411A3640, 0, }, // glMatrixLoadfEXT + { 0x00000001411A3660, 0, }, // glMatrixLoadIdentityEXT + { 0x00000001411A36C0, 0, }, // glMatrixLoadTransposedEXT + { 0x00000001411A36B8, 0, }, // glMatrixLoadTransposefEXT + { 0x00000001411A3658, 0, }, // glMatrixMultdEXT + { 0x00000001411A3650, 0, }, // glMatrixMultfEXT + { 0x00000001411A36D0, 0, }, // glMatrixMultTransposedEXT + { 0x00000001411A36C8, 0, }, // glMatrixMultTransposefEXT + { 0x00000001411A36A0, 0, }, // glMatrixOrthoEXT + { 0x00000001411A36A8, 0, }, // glMatrixPopEXT + { 0x00000001411A36B0, 0, }, // glMatrixPushEXT + { 0x00000001411A3670, 0, }, // glMatrixRotatedEXT + { 0x00000001411A3668, 0, }, // glMatrixRotatefEXT + { 0x00000001411A3680, 0, }, // glMatrixScaledEXT + { 0x00000001411A3678, 0, }, // glMatrixScalefEXT + { 0x00000001411A3690, 0, }, // glMatrixTranslatedEXT + { 0x00000001411A3688, 0, }, // glMatrixTranslatefEXT + { 0x00000001411A3D58, 0, }, // glMinmax + { 0x00000001411A4068, 0, }, // glMultiDrawArrays + { 0x00000001411A4F88, 0, }, // glMultiDrawArraysEXT + { 0x00000001411A4070, 0, }, // glMultiDrawElements + { 0x00000001411A4F90, 0, }, // glMultiDrawElementsEXT + { 0x00000001411A3B50, 0, }, // glMultiTexBufferEXT + { 0x00000001411A3DD8, 0, }, // glMultiTexCoord1d + { 0x00000001411A4730, 0, }, // glMultiTexCoord1dARB + { 0x00000001411A3DE8, 0, }, // glMultiTexCoord1dv + { 0x00000001411A4738, 0, }, // glMultiTexCoord1dvARB + { 0x00000001411A3DF8, 0, }, // glMultiTexCoord1f + { 0x00000001411A4740, 0, }, // glMultiTexCoord1fARB + { 0x00000001411A3E08, 0, }, // glMultiTexCoord1fv + { 0x00000001411A4748, 0, }, // glMultiTexCoord1fvARB + { 0x00000001411A53B0, 0, }, // glMultiTexCoord1hNV + { 0x00000001411A53B8, 0, }, // glMultiTexCoord1hvNV + { 0x00000001411A3E18, 0, }, // glMultiTexCoord1i + { 0x00000001411A4750, 0, }, // glMultiTexCoord1iARB + { 0x00000001411A3E28, 0, }, // glMultiTexCoord1iv + { 0x00000001411A4758, 0, }, // glMultiTexCoord1ivARB + { 0x00000001411A3E38, 0, }, // glMultiTexCoord1s + { 0x00000001411A4760, 0, }, // glMultiTexCoord1sARB + { 0x00000001411A3E48, 0, }, // glMultiTexCoord1sv + { 0x00000001411A4768, 0, }, // glMultiTexCoord1svARB + { 0x00000001411A3E58, 0, }, // glMultiTexCoord2d + { 0x00000001411A4770, 0, }, // glMultiTexCoord2dARB + { 0x00000001411A3E68, 0, }, // glMultiTexCoord2dv + { 0x00000001411A4778, 0, }, // glMultiTexCoord2dvARB + { 0x00000001411A4780, 0, }, // glMultiTexCoord2fARB + { 0x00000001411A4788, 0, }, // glMultiTexCoord2fvARB + { 0x00000001411A53C0, 0, }, // glMultiTexCoord2hNV + { 0x00000001411A53C8, 0, }, // glMultiTexCoord2hvNV + { 0x00000001411A3E98, 0, }, // glMultiTexCoord2i + { 0x00000001411A4790, 0, }, // glMultiTexCoord2iARB + { 0x00000001411A3EA8, 0, }, // glMultiTexCoord2iv + { 0x00000001411A4798, 0, }, // glMultiTexCoord2ivARB + { 0x00000001411A3EB8, 0, }, // glMultiTexCoord2s + { 0x00000001411A47A0, 0, }, // glMultiTexCoord2sARB + { 0x00000001411A3EC8, 0, }, // glMultiTexCoord2sv + { 0x00000001411A47A8, 0, }, // glMultiTexCoord2svARB + { 0x00000001411A3ED8, 0, }, // glMultiTexCoord3d + { 0x00000001411A47B0, 0, }, // glMultiTexCoord3dARB + { 0x00000001411A3EE8, 0, }, // glMultiTexCoord3dv + { 0x00000001411A47B8, 0, }, // glMultiTexCoord3dvARB + { 0x00000001411A3EF8, 0, }, // glMultiTexCoord3f + { 0x00000001411A47C0, 0, }, // glMultiTexCoord3fARB + { 0x00000001411A3F08, 0, }, // glMultiTexCoord3fv + { 0x00000001411A47C8, 0, }, // glMultiTexCoord3fvARB + { 0x00000001411A53D0, 0, }, // glMultiTexCoord3hNV + { 0x00000001411A53D8, 0, }, // glMultiTexCoord3hvNV + { 0x00000001411A3F18, 0, }, // glMultiTexCoord3i + { 0x00000001411A47D0, 0, }, // glMultiTexCoord3iARB + { 0x00000001411A3F28, 0, }, // glMultiTexCoord3iv + { 0x00000001411A47D8, 0, }, // glMultiTexCoord3ivARB + { 0x00000001411A3F38, 0, }, // glMultiTexCoord3s + { 0x00000001411A47E0, 0, }, // glMultiTexCoord3sARB + { 0x00000001411A3F48, 0, }, // glMultiTexCoord3sv + { 0x00000001411A47E8, 0, }, // glMultiTexCoord3svARB + { 0x00000001411A3F58, 0, }, // glMultiTexCoord4d + { 0x00000001411A47F0, 0, }, // glMultiTexCoord4dARB + { 0x00000001411A3F68, 0, }, // glMultiTexCoord4dv + { 0x00000001411A47F8, 0, }, // glMultiTexCoord4dvARB + { 0x00000001411A3F78, 0, }, // glMultiTexCoord4f + { 0x00000001411A4800, 0, }, // glMultiTexCoord4fARB + { 0x00000001411A3F88, 0, }, // glMultiTexCoord4fv + { 0x00000001411A4808, 0, }, // glMultiTexCoord4fvARB + { 0x00000001411A53E0, 0, }, // glMultiTexCoord4hNV + { 0x00000001411A53E8, 0, }, // glMultiTexCoord4hvNV + { 0x00000001411A3F98, 0, }, // glMultiTexCoord4i + { 0x00000001411A4810, 0, }, // glMultiTexCoord4iARB + { 0x00000001411A3FA8, 0, }, // glMultiTexCoord4iv + { 0x00000001411A4818, 0, }, // glMultiTexCoord4ivARB + { 0x00000001411A3FB8, 0, }, // glMultiTexCoord4s + { 0x00000001411A4820, 0, }, // glMultiTexCoord4sARB + { 0x00000001411A3FC8, 0, }, // glMultiTexCoord4sv + { 0x00000001411A4828, 0, }, // glMultiTexCoord4svARB + { 0x00000001411A3830, 0, }, // glMultiTexCoordPointerEXT + { 0x00000001411A3838, 0, }, // glMultiTexEnvfEXT + { 0x00000001411A3840, 0, }, // glMultiTexEnvfvEXT + { 0x00000001411A3848, 0, }, // glMultiTexEnviEXT + { 0x00000001411A3850, 0, }, // glMultiTexEnvivEXT + { 0x00000001411A3858, 0, }, // glMultiTexGendEXT + { 0x00000001411A3860, 0, }, // glMultiTexGendvEXT + { 0x00000001411A3868, 0, }, // glMultiTexGenfEXT + { 0x00000001411A3870, 0, }, // glMultiTexGenfvEXT + { 0x00000001411A3878, 0, }, // glMultiTexGeniEXT + { 0x00000001411A3880, 0, }, // glMultiTexGenivEXT + { 0x00000001411A3798, 0, }, // glMultiTexImage1DEXT + { 0x00000001411A37A0, 0, }, // glMultiTexImage2DEXT + { 0x00000001411A3800, 0, }, // glMultiTexImage3DEXT + { 0x00000001411A3778, 0, }, // glMultiTexParameterfEXT + { 0x00000001411A3780, 0, }, // glMultiTexParameterfvEXT + { 0x00000001411A3788, 0, }, // glMultiTexParameteriEXT + { 0x00000001411A39E8, 0, }, // glMultiTexParameterIivEXT + { 0x00000001411A39F0, 0, }, // glMultiTexParameterIuivEXT + { 0x00000001411A3790, 0, }, // glMultiTexParameterivEXT + { 0x00000001411A3CA0, 0, }, // glMultiTexRenderbufferEXT + { 0x00000001411A37A8, 0, }, // glMultiTexSubImage1DEXT + { 0x00000001411A37B0, 0, }, // glMultiTexSubImage2DEXT + { 0x00000001411A3808, 0, }, // glMultiTexSubImage3DEXT + { 0x00000001411A3FF0, 0, }, // glMultTransposeMatrixd + { 0x00000001411A4848, 0, }, // glMultTransposeMatrixdARB + { 0x00000001411A4840, 0, }, // glMultTransposeMatrixfARB + { 0x00000001411A3BC0, 0, }, // glNamedFramebufferRenderbufferEXT + { 0x00000001411A3B90, 0, }, // glNamedFramebufferTexture1DEXT + { 0x00000001411A3BA0, 0, }, // glNamedFramebufferTexture2DEXT + { 0x00000001411A3BB0, 0, }, // glNamedFramebufferTexture3DEXT + { 0x00000001411A3C60, 0, }, // glNamedFramebufferTextureEXT + { 0x00000001411A3C80, 0, }, // glNamedFramebufferTextureFaceEXT + { 0x00000001411A3C70, 0, }, // glNamedFramebufferTextureLayerEXT + { 0x00000001411A3940, 0, }, // glNamedProgramLocalParameter4dEXT + { 0x00000001411A3948, 0, }, // glNamedProgramLocalParameter4dvEXT + { 0x00000001411A3950, 0, }, // glNamedProgramLocalParameter4fEXT + { 0x00000001411A3958, 0, }, // glNamedProgramLocalParameter4fvEXT + { 0x00000001411A3988, 0, }, // glNamedProgramLocalParameterI4iEXT + { 0x00000001411A3990, 0, }, // glNamedProgramLocalParameterI4ivEXT + { 0x00000001411A39A0, 0, }, // glNamedProgramLocalParameterI4uiEXT + { 0x00000001411A39A8, 0, }, // glNamedProgramLocalParameterI4uivEXT + { 0x00000001411A3980, 0, }, // glNamedProgramLocalParameters4fvEXT + { 0x00000001411A3998, 0, }, // glNamedProgramLocalParametersI4ivEXT + { 0x00000001411A39B0, 0, }, // glNamedProgramLocalParametersI4uivEXT + { 0x00000001411A3938, 0, }, // glNamedProgramStringEXT + { 0x00000001411A3B60, 0, }, // glNamedRenderbufferStorageEXT + { 0x00000001411A3C50, 0, }, // glNamedRenderbufferStorageMultisampleCoverageEXT + { 0x00000001411A3C40, 0, }, // glNamedRenderbufferStorageMultisampleEXT + { 0x00000001411A5340, 0, }, // glNormal3hNV + { 0x00000001411A5348, 0, }, // glNormal3hvNV + { 0x00000001411A4E90, 0, }, // glNormalPointerEXT + { 0x00000001411A5470, 0, }, // glPixelDataRangeNV + { 0x00000001411A4890, 0, }, // glPointParameterfARB + { 0x00000001411A4EB0, 0, }, // glPointParameterfEXT + { 0x00000001411A4898, 0, }, // glPointParameterfvARB + { 0x00000001411A4EB8, 0, }, // glPointParameterfvEXT + { 0x00000001411A52C0, 0, }, // glPointParameteriNV + { 0x00000001411A4090, 0, }, // glPointParameteriv + { 0x00000001411A52C8, 0, }, // glPointParameterivNV + { 0x00000001411A3608, 0, }, // glPresentFrameDualFillNV + { 0x00000001411A3600, 0, }, // glPresentFrameKeyedNV + { 0x00000001411A5480, 0, }, // glPrimitiveRestartNV + { 0x00000001411A4E58, 0, }, // glPrioritizeTexturesEXT + { 0x00000001411A3510, 0, }, // glProgramBufferParametersIivNV + { 0x00000001411A3518, 0, }, // glProgramBufferParametersIuivNV + { 0x00000001411A4A78, 0, }, // glProgramEnvParameter4dARB + { 0x00000001411A4A80, 0, }, // glProgramEnvParameter4dvARB + { 0x00000001411A5588, 0, }, // glProgramEnvParameterI4iNV + { 0x00000001411A5590, 0, }, // glProgramEnvParameterI4ivNV + { 0x00000001411A55A0, 0, }, // glProgramEnvParameterI4uiNV + { 0x00000001411A55A8, 0, }, // glProgramEnvParameterI4uivNV + { 0x00000001411A5598, 0, }, // glProgramEnvParametersI4ivNV + { 0x00000001411A55B0, 0, }, // glProgramEnvParametersI4uivNV + { 0x00000001411A4A98, 0, }, // glProgramLocalParameter4dARB + { 0x00000001411A4AA0, 0, }, // glProgramLocalParameter4dvARB + { 0x00000001411A5558, 0, }, // glProgramLocalParameterI4iNV + { 0x00000001411A5560, 0, }, // glProgramLocalParameterI4ivNV + { 0x00000001411A5570, 0, }, // glProgramLocalParameterI4uiNV + { 0x00000001411A5578, 0, }, // glProgramLocalParameterI4uivNV + { 0x00000001411A5568, 0, }, // glProgramLocalParametersI4ivNV + { 0x00000001411A5580, 0, }, // glProgramLocalParametersI4uivNV + { 0x00000001411A52E8, 0, }, // glProgramNamedParameter4dNV + { 0x00000001411A52F8, 0, }, // glProgramNamedParameter4dvNV + { 0x00000001411A52E0, 0, }, // glProgramNamedParameter4fNV + { 0x00000001411A52F0, 0, }, // glProgramNamedParameter4fvNV + { 0x00000001411A5108, 0, }, // glProgramParameter4dNV + { 0x00000001411A5110, 0, }, // glProgramParameter4dvNV + { 0x00000001411A5118, 0, }, // glProgramParameter4fNV + { 0x00000001411A5120, 0, }, // glProgramParameter4fvNV + { 0x00000001411A4DB8, 0, }, // glProgramParameteriARB + { 0x00000001411A55F8, 0, }, // glProgramParameteriEXT + { 0x00000001411A5128, 0, }, // glProgramParameters4dvNV + { 0x00000001411A5130, 0, }, // glProgramParameters4fvNV + { 0x00000001411A4A58, 0, }, // glProgramStringARB + { 0x00000001411A3A08, 0, }, // glProgramUniform1fEXT + { 0x00000001411A3A48, 0, }, // glProgramUniform1fvEXT + { 0x00000001411A3A28, 0, }, // glProgramUniform1iEXT + { 0x00000001411A3A68, 0, }, // glProgramUniform1ivEXT + { 0x00000001411A3AD0, 0, }, // glProgramUniform1uiEXT + { 0x00000001411A3AF0, 0, }, // glProgramUniform1uivEXT + { 0x00000001411A3A10, 0, }, // glProgramUniform2fEXT + { 0x00000001411A3A50, 0, }, // glProgramUniform2fvEXT + { 0x00000001411A3A30, 0, }, // glProgramUniform2iEXT + { 0x00000001411A3A70, 0, }, // glProgramUniform2ivEXT + { 0x00000001411A3AD8, 0, }, // glProgramUniform2uiEXT + { 0x00000001411A3AF8, 0, }, // glProgramUniform2uivEXT + { 0x00000001411A3A18, 0, }, // glProgramUniform3fEXT + { 0x00000001411A3A58, 0, }, // glProgramUniform3fvEXT + { 0x00000001411A3A38, 0, }, // glProgramUniform3iEXT + { 0x00000001411A3A78, 0, }, // glProgramUniform3ivEXT + { 0x00000001411A3AE0, 0, }, // glProgramUniform3uiEXT + { 0x00000001411A3B00, 0, }, // glProgramUniform3uivEXT + { 0x00000001411A3A20, 0, }, // glProgramUniform4fEXT + { 0x00000001411A3A60, 0, }, // glProgramUniform4fvEXT + { 0x00000001411A3A40, 0, }, // glProgramUniform4iEXT + { 0x00000001411A3A80, 0, }, // glProgramUniform4ivEXT + { 0x00000001411A3AE8, 0, }, // glProgramUniform4uiEXT + { 0x00000001411A3B08, 0, }, // glProgramUniform4uivEXT + { 0x00000001411A3A88, 0, }, // glProgramUniformMatrix2fvEXT + { 0x00000001411A3AA0, 0, }, // glProgramUniformMatrix2x3fvEXT + { 0x00000001411A3AB0, 0, }, // glProgramUniformMatrix2x4fvEXT + { 0x00000001411A3A90, 0, }, // glProgramUniformMatrix3fvEXT + { 0x00000001411A3AA8, 0, }, // glProgramUniformMatrix3x2fvEXT + { 0x00000001411A3AC0, 0, }, // glProgramUniformMatrix3x4fvEXT + { 0x00000001411A3A98, 0, }, // glProgramUniformMatrix4fvEXT + { 0x00000001411A3AB8, 0, }, // glProgramUniformMatrix4x2fvEXT + { 0x00000001411A3AC8, 0, }, // glProgramUniformMatrix4x3fvEXT + { 0x00000001411A55D8, 0, }, // glProgramVertexLimitNV + { 0x00000001411A3638, 0, }, // glPushClientAttribDefaultEXT + { 0x00000001411A3F30, 0, }, // glQueryCounter + { 0x00000001411A4D38, 0, }, // glRenderbufferStorage + { 0x00000001411A4DA8, 0, }, // glRenderbufferStorageMultisample + { 0x00000001411A5530, 0, }, // glRenderbufferStorageMultisampleEXT + { 0x00000001411A5138, 0, }, // glRequestResidentProgramsNV + { 0x00000001411A3D68, 0, }, // glResetHistogram + { 0x00000001411A3D78, 0, }, // glResetMinmax + { 0x00000001411A3FF8, 0, }, // glSampleCoverage + { 0x00000001411A4850, 0, }, // glSampleCoverageARB + { 0x00000001411A3CC0, 0, }, // glSampleMaskIndexedNV + { 0x00000001411A3FC0, 0, }, // glSamplerParameterf + { 0x00000001411A3FD0, 0, }, // glSamplerParameterfv + { 0x00000001411A3FB0, 0, }, // glSamplerParameteri + { 0x00000001411A4098, 0, }, // glSecondaryColor3b + { 0x00000001411A4F00, 0, }, // glSecondaryColor3bEXT + { 0x00000001411A40A0, 0, }, // glSecondaryColor3bv + { 0x00000001411A4F08, 0, }, // glSecondaryColor3bvEXT + { 0x00000001411A40A8, 0, }, // glSecondaryColor3d + { 0x00000001411A4F10, 0, }, // glSecondaryColor3dEXT + { 0x00000001411A40B0, 0, }, // glSecondaryColor3dv + { 0x00000001411A4F18, 0, }, // glSecondaryColor3dvEXT + { 0x00000001411A40B8, 0, }, // glSecondaryColor3f + { 0x00000001411A4F20, 0, }, // glSecondaryColor3fEXT + { 0x00000001411A40C0, 0, }, // glSecondaryColor3fv + { 0x00000001411A4F28, 0, }, // glSecondaryColor3fvEXT + { 0x00000001411A5400, 0, }, // glSecondaryColor3hNV + { 0x00000001411A5408, 0, }, // glSecondaryColor3hvNV + { 0x00000001411A40C8, 0, }, // glSecondaryColor3i + { 0x00000001411A4F30, 0, }, // glSecondaryColor3iEXT + { 0x00000001411A40D0, 0, }, // glSecondaryColor3iv + { 0x00000001411A4F38, 0, }, // glSecondaryColor3ivEXT + { 0x00000001411A40D8, 0, }, // glSecondaryColor3s + { 0x00000001411A4F40, 0, }, // glSecondaryColor3sEXT + { 0x00000001411A40E0, 0, }, // glSecondaryColor3sv + { 0x00000001411A4F48, 0, }, // glSecondaryColor3svEXT + { 0x00000001411A40E8, 0, }, // glSecondaryColor3ub + { 0x00000001411A4F50, 0, }, // glSecondaryColor3ubEXT + { 0x00000001411A40F0, 0, }, // glSecondaryColor3ubv + { 0x00000001411A4F58, 0, }, // glSecondaryColor3ubvEXT + { 0x00000001411A40F8, 0, }, // glSecondaryColor3ui + { 0x00000001411A4F60, 0, }, // glSecondaryColor3uiEXT + { 0x00000001411A4100, 0, }, // glSecondaryColor3uiv + { 0x00000001411A4F68, 0, }, // glSecondaryColor3uivEXT + { 0x00000001411A4108, 0, }, // glSecondaryColor3us + { 0x00000001411A4F70, 0, }, // glSecondaryColor3usEXT + { 0x00000001411A4110, 0, }, // glSecondaryColor3usv + { 0x00000001411A4F78, 0, }, // glSecondaryColor3usvEXT + { 0x00000001411A4118, 0, }, // glSecondaryColorPointer + { 0x00000001411A4F80, 0, }, // glSecondaryColorPointerEXT + { 0x00000001411A3CD8, 0, }, // glSeparableFilter2D + { 0x00000001411A5070, 0, }, // glSetFenceNV + { 0x00000001411A4348, 0, }, // glShaderSource + { 0x00000001411A4BC8, 0, }, // glShaderSourceARB + { 0x00000001411A4250, 0, }, // glStencilFuncSeparate + { 0x00000001411A4258, 0, }, // glStencilMaskSeparate + { 0x00000001411A4248, 0, }, // glStencilOpSeparate + { 0x00000001411A5058, 0, }, // glTestFenceNV + { 0x00000001411A4DE8, 0, }, // glTexBufferARB + { 0x00000001411A34E0, 0, }, // glTexBufferEXT + { 0x00000001411A5370, 0, }, // glTexCoord1hNV + { 0x00000001411A5378, 0, }, // glTexCoord1hvNV + { 0x00000001411A5380, 0, }, // glTexCoord2hNV + { 0x00000001411A5388, 0, }, // glTexCoord2hvNV + { 0x00000001411A5390, 0, }, // glTexCoord3hNV + { 0x00000001411A5398, 0, }, // glTexCoord3hvNV + { 0x00000001411A53A0, 0, }, // glTexCoord4hNV + { 0x00000001411A53A8, 0, }, // glTexCoord4hvNV + { 0x00000001411A4E98, 0, }, // glTexCoordPointerEXT + { 0x00000001411A3D88, 0, }, // glTexImage3D + { 0x00000001411A4E18, 0, }, // glTexImage3DEXT + { 0x00000001411A46D0, 0, }, // glTexParameterIiv + { 0x00000001411A35C0, 0, }, // glTexParameterIivEXT + { 0x00000001411A46D8, 0, }, // glTexParameterIuiv + { 0x00000001411A35C8, 0, }, // glTexParameterIuivEXT + { 0x00000001411A3CD0, 0, }, // glTexRenderbufferNV + { 0x00000001411A3F60, 0, }, // glTexStorage2D + { 0x00000001411A3D98, 0, }, // glTexSubImage3D + { 0x00000001411A4E20, 0, }, // glTexSubImage3DEXT + { 0x00000001411A3CE0, 0, }, // glTextureBarrierNV + { 0x00000001411A3B48, 0, }, // glTextureBufferEXT + { 0x00000001411A36F8, 0, }, // glTextureImage1DEXT + { 0x00000001411A3700, 0, }, // glTextureImage2DEXT + { 0x00000001411A3760, 0, }, // glTextureImage3DEXT + { 0x00000001411A36D8, 0, }, // glTextureParameterfEXT + { 0x00000001411A36E0, 0, }, // glTextureParameterfvEXT + { 0x00000001411A36E8, 0, }, // glTextureParameteriEXT + { 0x00000001411A39C8, 0, }, // glTextureParameterIivEXT + { 0x00000001411A39D0, 0, }, // glTextureParameterIuivEXT + { 0x00000001411A36F0, 0, }, // glTextureParameterivEXT + { 0x00000001411A3C90, 0, }, // glTextureRenderbufferEXT + { 0x00000001411A3F70, 0, }, // glTextureStorage2DEXT + { 0x00000001411A3708, 0, }, // glTextureSubImage1DEXT + { 0x00000001411A3710, 0, }, // glTextureSubImage2DEXT + { 0x00000001411A3768, 0, }, // glTextureSubImage3DEXT + { 0x00000001411A5140, 0, }, // glTrackMatrixNV + { 0x00000001411A3560, 0, }, // glTransformFeedbackAttribsNV + { 0x00000001411A45A0, 0, }, // glTransformFeedbackVaryings + { 0x00000001411A3580, 0, }, // glTransformFeedbackVaryingsNV + { 0x00000001411A4358, 0, }, // glUniform1f + { 0x00000001411A4C00, 0, }, // glUniform1fARB + { 0x00000001411A4398, 0, }, // glUniform1fv + { 0x00000001411A4C40, 0, }, // glUniform1fvARB + { 0x00000001411A4378, 0, }, // glUniform1i + { 0x00000001411A4C20, 0, }, // glUniform1iARB + { 0x00000001411A43B8, 0, }, // glUniform1iv + { 0x00000001411A4C60, 0, }, // glUniform1ivARB + { 0x00000001411A4690, 0, }, // glUniform1ui + { 0x00000001411A56D0, 0, }, // glUniform1uiEXT + { 0x00000001411A46B0, 0, }, // glUniform1uiv + { 0x00000001411A56F0, 0, }, // glUniform1uivEXT + { 0x00000001411A4360, 0, }, // glUniform2f + { 0x00000001411A4C08, 0, }, // glUniform2fARB + { 0x00000001411A43A0, 0, }, // glUniform2fv + { 0x00000001411A4C48, 0, }, // glUniform2fvARB + { 0x00000001411A4380, 0, }, // glUniform2i + { 0x00000001411A4C28, 0, }, // glUniform2iARB + { 0x00000001411A43C0, 0, }, // glUniform2iv + { 0x00000001411A4C68, 0, }, // glUniform2ivARB + { 0x00000001411A4698, 0, }, // glUniform2ui + { 0x00000001411A56D8, 0, }, // glUniform2uiEXT + { 0x00000001411A46B8, 0, }, // glUniform2uiv + { 0x00000001411A56F8, 0, }, // glUniform2uivEXT + { 0x00000001411A4368, 0, }, // glUniform3f + { 0x00000001411A4C10, 0, }, // glUniform3fARB + { 0x00000001411A43A8, 0, }, // glUniform3fv + { 0x00000001411A4C50, 0, }, // glUniform3fvARB + { 0x00000001411A4388, 0, }, // glUniform3i + { 0x00000001411A4C30, 0, }, // glUniform3iARB + { 0x00000001411A43C8, 0, }, // glUniform3iv + { 0x00000001411A4C70, 0, }, // glUniform3ivARB + { 0x00000001411A46A0, 0, }, // glUniform3ui + { 0x00000001411A56E0, 0, }, // glUniform3uiEXT + { 0x00000001411A46C0, 0, }, // glUniform3uiv + { 0x00000001411A5700, 0, }, // glUniform3uivEXT + { 0x00000001411A4370, 0, }, // glUniform4f + { 0x00000001411A4C18, 0, }, // glUniform4fARB + { 0x00000001411A43B0, 0, }, // glUniform4fv + { 0x00000001411A4C58, 0, }, // glUniform4fvARB + { 0x00000001411A4390, 0, }, // glUniform4i + { 0x00000001411A4C38, 0, }, // glUniform4iARB + { 0x00000001411A43D0, 0, }, // glUniform4iv + { 0x00000001411A4C78, 0, }, // glUniform4ivARB + { 0x00000001411A46A8, 0, }, // glUniform4ui + { 0x00000001411A56E8, 0, }, // glUniform4uiEXT + { 0x00000001411A46C8, 0, }, // glUniform4uiv + { 0x00000001411A5708, 0, }, // glUniform4uivEXT + { 0x00000001411A35A8, 0, }, // glUniformBufferEXT + { 0x00000001411A43D8, 0, }, // glUniformMatrix2fv + { 0x00000001411A4C80, 0, }, // glUniformMatrix2fvARB + { 0x00000001411A4520, 0, }, // glUniformMatrix2x3fv + { 0x00000001411A4530, 0, }, // glUniformMatrix2x4fv + { 0x00000001411A43E0, 0, }, // glUniformMatrix3fv + { 0x00000001411A4C88, 0, }, // glUniformMatrix3fvARB + { 0x00000001411A4528, 0, }, // glUniformMatrix3x2fv + { 0x00000001411A4540, 0, }, // glUniformMatrix3x4fv + { 0x00000001411A43E8, 0, }, // glUniformMatrix4fv + { 0x00000001411A4C90, 0, }, // glUniformMatrix4fvARB + { 0x00000001411A4538, 0, }, // glUniformMatrix4x2fv + { 0x00000001411A4548, 0, }, // glUniformMatrix4x3fv + { 0x00000001411A4EF0, 0, }, // glUnlockArraysEXT + { 0x00000001411A4220, 0, }, // glUnmapBuffer + { 0x00000001411A4B50, 0, }, // glUnmapBufferARB + { 0x00000001411A4BF0, 0, }, // glUseProgramObjectARB + { 0x00000001411A43F0, 0, }, // glValidateProgram + { 0x00000001411A4BF8, 0, }, // glValidateProgramARB + { 0x00000001411A5310, 0, }, // glVertex2hNV + { 0x00000001411A5318, 0, }, // glVertex2hvNV + { 0x00000001411A5320, 0, }, // glVertex3hNV + { 0x00000001411A5328, 0, }, // glVertex3hvNV + { 0x00000001411A5330, 0, }, // glVertex4hNV + { 0x00000001411A5338, 0, }, // glVertex4hvNV + { 0x00000001411A4FD0, 0, }, // glVertexArrayRangeNV + { 0x00000001411A43F8, 0, }, // glVertexAttrib1d + { 0x00000001411A4920, 0, }, // glVertexAttrib1dARB + { 0x00000001411A5150, 0, }, // glVertexAttrib1dNV + { 0x00000001411A4400, 0, }, // glVertexAttrib1dv + { 0x00000001411A4928, 0, }, // glVertexAttrib1dvARB + { 0x00000001411A5158, 0, }, // glVertexAttrib1dvNV + { 0x00000001411A4408, 0, }, // glVertexAttrib1f + { 0x00000001411A4930, 0, }, // glVertexAttrib1fARB + { 0x00000001411A5160, 0, }, // glVertexAttrib1fNV + { 0x00000001411A4410, 0, }, // glVertexAttrib1fv + { 0x00000001411A4938, 0, }, // glVertexAttrib1fvARB + { 0x00000001411A5168, 0, }, // glVertexAttrib1fvNV + { 0x00000001411A5410, 0, }, // glVertexAttrib1hNV + { 0x00000001411A5418, 0, }, // glVertexAttrib1hvNV + { 0x00000001411A4418, 0, }, // glVertexAttrib1s + { 0x00000001411A4940, 0, }, // glVertexAttrib1sARB + { 0x00000001411A5170, 0, }, // glVertexAttrib1sNV + { 0x00000001411A4420, 0, }, // glVertexAttrib1sv + { 0x00000001411A4948, 0, }, // glVertexAttrib1svARB + { 0x00000001411A5178, 0, }, // glVertexAttrib1svNV + { 0x00000001411A4428, 0, }, // glVertexAttrib2d + { 0x00000001411A4950, 0, }, // glVertexAttrib2dARB + { 0x00000001411A5180, 0, }, // glVertexAttrib2dNV + { 0x00000001411A4430, 0, }, // glVertexAttrib2dv + { 0x00000001411A4958, 0, }, // glVertexAttrib2dvARB + { 0x00000001411A5188, 0, }, // glVertexAttrib2dvNV + { 0x00000001411A4438, 0, }, // glVertexAttrib2f + { 0x00000001411A4960, 0, }, // glVertexAttrib2fARB + { 0x00000001411A5190, 0, }, // glVertexAttrib2fNV + { 0x00000001411A4440, 0, }, // glVertexAttrib2fv + { 0x00000001411A4968, 0, }, // glVertexAttrib2fvARB + { 0x00000001411A5198, 0, }, // glVertexAttrib2fvNV + { 0x00000001411A5420, 0, }, // glVertexAttrib2hNV + { 0x00000001411A5428, 0, }, // glVertexAttrib2hvNV + { 0x00000001411A4448, 0, }, // glVertexAttrib2s + { 0x00000001411A4970, 0, }, // glVertexAttrib2sARB + { 0x00000001411A51A0, 0, }, // glVertexAttrib2sNV + { 0x00000001411A4450, 0, }, // glVertexAttrib2sv + { 0x00000001411A4978, 0, }, // glVertexAttrib2svARB + { 0x00000001411A51A8, 0, }, // glVertexAttrib2svNV + { 0x00000001411A4458, 0, }, // glVertexAttrib3d + { 0x00000001411A4980, 0, }, // glVertexAttrib3dARB + { 0x00000001411A51B0, 0, }, // glVertexAttrib3dNV + { 0x00000001411A4460, 0, }, // glVertexAttrib3dv + { 0x00000001411A4988, 0, }, // glVertexAttrib3dvARB + { 0x00000001411A51B8, 0, }, // glVertexAttrib3dvNV + { 0x00000001411A4468, 0, }, // glVertexAttrib3f + { 0x00000001411A4990, 0, }, // glVertexAttrib3fARB + { 0x00000001411A51C0, 0, }, // glVertexAttrib3fNV + { 0x00000001411A4470, 0, }, // glVertexAttrib3fv + { 0x00000001411A4998, 0, }, // glVertexAttrib3fvARB + { 0x00000001411A51C8, 0, }, // glVertexAttrib3fvNV + { 0x00000001411A5430, 0, }, // glVertexAttrib3hNV + { 0x00000001411A5438, 0, }, // glVertexAttrib3hvNV + { 0x00000001411A4478, 0, }, // glVertexAttrib3s + { 0x00000001411A49A0, 0, }, // glVertexAttrib3sARB + { 0x00000001411A51D0, 0, }, // glVertexAttrib3sNV + { 0x00000001411A4480, 0, }, // glVertexAttrib3sv + { 0x00000001411A49A8, 0, }, // glVertexAttrib3svARB + { 0x00000001411A51D8, 0, }, // glVertexAttrib3svNV + { 0x00000001411A44C0, 0, }, // glVertexAttrib4bv + { 0x00000001411A49E8, 0, }, // glVertexAttrib4bvARB + { 0x00000001411A44C8, 0, }, // glVertexAttrib4d + { 0x00000001411A49F0, 0, }, // glVertexAttrib4dARB + { 0x00000001411A51E0, 0, }, // glVertexAttrib4dNV + { 0x00000001411A44D0, 0, }, // glVertexAttrib4dv + { 0x00000001411A49F8, 0, }, // glVertexAttrib4dvARB + { 0x00000001411A51E8, 0, }, // glVertexAttrib4dvNV + { 0x00000001411A44D8, 0, }, // glVertexAttrib4f + { 0x00000001411A4A00, 0, }, // glVertexAttrib4fARB + { 0x00000001411A51F0, 0, }, // glVertexAttrib4fNV + { 0x00000001411A44E0, 0, }, // glVertexAttrib4fv + { 0x00000001411A4A08, 0, }, // glVertexAttrib4fvARB + { 0x00000001411A51F8, 0, }, // glVertexAttrib4fvNV + { 0x00000001411A5440, 0, }, // glVertexAttrib4hNV + { 0x00000001411A5448, 0, }, // glVertexAttrib4hvNV + { 0x00000001411A44E8, 0, }, // glVertexAttrib4iv + { 0x00000001411A4A10, 0, }, // glVertexAttrib4ivARB + { 0x00000001411A4488, 0, }, // glVertexAttrib4Nbv + { 0x00000001411A49B0, 0, }, // glVertexAttrib4NbvARB + { 0x00000001411A4490, 0, }, // glVertexAttrib4Niv + { 0x00000001411A49B8, 0, }, // glVertexAttrib4NivARB + { 0x00000001411A4498, 0, }, // glVertexAttrib4Nsv + { 0x00000001411A49C0, 0, }, // glVertexAttrib4NsvARB + { 0x00000001411A44A0, 0, }, // glVertexAttrib4Nub + { 0x00000001411A49C8, 0, }, // glVertexAttrib4NubARB + { 0x00000001411A44A8, 0, }, // glVertexAttrib4Nubv + { 0x00000001411A49D0, 0, }, // glVertexAttrib4NubvARB + { 0x00000001411A44B0, 0, }, // glVertexAttrib4Nuiv + { 0x00000001411A49D8, 0, }, // glVertexAttrib4NuivARB + { 0x00000001411A44B8, 0, }, // glVertexAttrib4Nusv + { 0x00000001411A49E0, 0, }, // glVertexAttrib4NusvARB + { 0x00000001411A44F0, 0, }, // glVertexAttrib4s + { 0x00000001411A4A18, 0, }, // glVertexAttrib4sARB + { 0x00000001411A5200, 0, }, // glVertexAttrib4sNV + { 0x00000001411A44F8, 0, }, // glVertexAttrib4sv + { 0x00000001411A4A20, 0, }, // glVertexAttrib4svARB + { 0x00000001411A5208, 0, }, // glVertexAttrib4svNV + { 0x00000001411A5210, 0, }, // glVertexAttrib4ubNV + { 0x00000001411A4500, 0, }, // glVertexAttrib4ubv + { 0x00000001411A4A28, 0, }, // glVertexAttrib4ubvARB + { 0x00000001411A5218, 0, }, // glVertexAttrib4ubvNV + { 0x00000001411A4508, 0, }, // glVertexAttrib4uiv + { 0x00000001411A4A30, 0, }, // glVertexAttrib4uivARB + { 0x00000001411A4510, 0, }, // glVertexAttrib4usv + { 0x00000001411A4A38, 0, }, // glVertexAttrib4usvARB + { 0x00000001411A45C0, 0, }, // glVertexAttribI1i + { 0x00000001411A5600, 0, }, // glVertexAttribI1iEXT + { 0x00000001411A4600, 0, }, // glVertexAttribI1iv + { 0x00000001411A5640, 0, }, // glVertexAttribI1ivEXT + { 0x00000001411A45E0, 0, }, // glVertexAttribI1ui + { 0x00000001411A5620, 0, }, // glVertexAttribI1uiEXT + { 0x00000001411A4620, 0, }, // glVertexAttribI1uiv + { 0x00000001411A5660, 0, }, // glVertexAttribI1uivEXT + { 0x00000001411A45C8, 0, }, // glVertexAttribI2i + { 0x00000001411A5608, 0, }, // glVertexAttribI2iEXT + { 0x00000001411A4608, 0, }, // glVertexAttribI2iv + { 0x00000001411A5648, 0, }, // glVertexAttribI2ivEXT + { 0x00000001411A45E8, 0, }, // glVertexAttribI2ui + { 0x00000001411A5628, 0, }, // glVertexAttribI2uiEXT + { 0x00000001411A4628, 0, }, // glVertexAttribI2uiv + { 0x00000001411A5668, 0, }, // glVertexAttribI2uivEXT + { 0x00000001411A45D0, 0, }, // glVertexAttribI3i + { 0x00000001411A5610, 0, }, // glVertexAttribI3iEXT + { 0x00000001411A4610, 0, }, // glVertexAttribI3iv + { 0x00000001411A5650, 0, }, // glVertexAttribI3ivEXT + { 0x00000001411A45F0, 0, }, // glVertexAttribI3ui + { 0x00000001411A5630, 0, }, // glVertexAttribI3uiEXT + { 0x00000001411A4630, 0, }, // glVertexAttribI3uiv + { 0x00000001411A5670, 0, }, // glVertexAttribI3uivEXT + { 0x00000001411A4640, 0, }, // glVertexAttribI4bv + { 0x00000001411A5680, 0, }, // glVertexAttribI4bvEXT + { 0x00000001411A45D8, 0, }, // glVertexAttribI4i + { 0x00000001411A5618, 0, }, // glVertexAttribI4iEXT + { 0x00000001411A4618, 0, }, // glVertexAttribI4iv + { 0x00000001411A5658, 0, }, // glVertexAttribI4ivEXT + { 0x00000001411A4648, 0, }, // glVertexAttribI4sv + { 0x00000001411A5688, 0, }, // glVertexAttribI4svEXT + { 0x00000001411A4650, 0, }, // glVertexAttribI4ubv + { 0x00000001411A5690, 0, }, // glVertexAttribI4ubvEXT + { 0x00000001411A45F8, 0, }, // glVertexAttribI4ui + { 0x00000001411A5638, 0, }, // glVertexAttribI4uiEXT + { 0x00000001411A4638, 0, }, // glVertexAttribI4uiv + { 0x00000001411A5678, 0, }, // glVertexAttribI4uivEXT + { 0x00000001411A4658, 0, }, // glVertexAttribI4usv + { 0x00000001411A5698, 0, }, // glVertexAttribI4usvEXT + { 0x00000001411A4660, 0, }, // glVertexAttribIPointer + { 0x00000001411A56A0, 0, }, // glVertexAttribIPointerEXT + { 0x00000001411A4518, 0, }, // glVertexAttribPointer + { 0x00000001411A5148, 0, }, // glVertexAttribPointerNV + { 0x00000001411A5220, 0, }, // glVertexAttribs1dvNV + { 0x00000001411A5228, 0, }, // glVertexAttribs1fvNV + { 0x00000001411A5450, 0, }, // glVertexAttribs1hvNV + { 0x00000001411A5230, 0, }, // glVertexAttribs1svNV + { 0x00000001411A5238, 0, }, // glVertexAttribs2dvNV + { 0x00000001411A5240, 0, }, // glVertexAttribs2fvNV + { 0x00000001411A5458, 0, }, // glVertexAttribs2hvNV + { 0x00000001411A5248, 0, }, // glVertexAttribs2svNV + { 0x00000001411A5250, 0, }, // glVertexAttribs3dvNV + { 0x00000001411A5258, 0, }, // glVertexAttribs3fvNV + { 0x00000001411A5460, 0, }, // glVertexAttribs3hvNV + { 0x00000001411A5260, 0, }, // glVertexAttribs3svNV + { 0x00000001411A5268, 0, }, // glVertexAttribs4dvNV + { 0x00000001411A5270, 0, }, // glVertexAttribs4fvNV + { 0x00000001411A5468, 0, }, // glVertexAttribs4hvNV + { 0x00000001411A5278, 0, }, // glVertexAttribs4svNV + { 0x00000001411A5280, 0, }, // glVertexAttribs4ubvNV + { 0x00000001411A4EA0, 0, }, // glVertexPointerEXT + { 0x00000001411A4120, 0, }, // glWindowPos2d + { 0x00000001411A48A0, 0, }, // glWindowPos2dARB + { 0x00000001411A4128, 0, }, // glWindowPos2dv + { 0x00000001411A48A8, 0, }, // glWindowPos2dvARB + { 0x00000001411A4130, 0, }, // glWindowPos2f + { 0x00000001411A48B0, 0, }, // glWindowPos2fARB + { 0x00000001411A4138, 0, }, // glWindowPos2fv + { 0x00000001411A48B8, 0, }, // glWindowPos2fvARB + { 0x00000001411A4140, 0, }, // glWindowPos2i + { 0x00000001411A48C0, 0, }, // glWindowPos2iARB + { 0x00000001411A4148, 0, }, // glWindowPos2iv + { 0x00000001411A48C8, 0, }, // glWindowPos2ivARB + { 0x00000001411A4150, 0, }, // glWindowPos2s + { 0x00000001411A48D0, 0, }, // glWindowPos2sARB + { 0x00000001411A4158, 0, }, // glWindowPos2sv + { 0x00000001411A48D8, 0, }, // glWindowPos2svARB + { 0x00000001411A4160, 0, }, // glWindowPos3d + { 0x00000001411A48E0, 0, }, // glWindowPos3dARB + { 0x00000001411A4168, 0, }, // glWindowPos3dv + { 0x00000001411A48E8, 0, }, // glWindowPos3dvARB + { 0x00000001411A4170, 0, }, // glWindowPos3f + { 0x00000001411A48F0, 0, }, // glWindowPos3fARB + { 0x00000001411A4178, 0, }, // glWindowPos3fv + { 0x00000001411A48F8, 0, }, // glWindowPos3fvARB + { 0x00000001411A4180, 0, }, // glWindowPos3i + { 0x00000001411A4900, 0, }, // glWindowPos3iARB + { 0x00000001411A4188, 0, }, // glWindowPos3iv + { 0x00000001411A4908, 0, }, // glWindowPos3ivARB + { 0x00000001411A4190, 0, }, // glWindowPos3s + { 0x00000001411A4910, 0, }, // glWindowPos3sARB + { 0x00000001411A4198, 0, }, // glWindowPos3sv + { 0x00000001411A4918, 0, }, // glWindowPos3svARB + { 0x00000001411A3E50, 0, }, // wglAllocateMemoryNV + { 0x00000001411A3EE0, 0, }, // wglBindSwapBarrierNV + { 0x00000001411A3DE0, 0, }, // wglBindTexImageARB + { 0x00000001411A3E90, 0, }, // wglBindVideoImageNV + { 0x00000001411A3D60, 0, }, // wglChoosePixelFormatARB + { 0x00000001411A3CF0, 0, }, // wglCreateBufferRegionARB + { 0x00000001411A3E10, 0, }, // wglCreateContextAttribsARB + { 0x00000001411A3D90, 0, }, // wglCreatePbufferARB + { 0x00000001411A3D00, 0, }, // wglDeleteBufferRegionARB + { 0x00000001411A3DC0, 0, }, // wglDestroyPbufferARB + { 0x00000001411A1A48, 0, }, // wglDXCloseDeviceNV + { 0x00000001411A1A68, 0, }, // wglDXLockObjectsNV + { 0x00000001411A1A40, 0, }, // wglDXOpenDeviceNV + { 0x00000001411A1A58, 0, }, // wglDXRegisterObjectNV + { 0x00000001411A1A50, 0, }, // wglDXSetResourceShareHandleNV + { 0x00000001411A1A70, 0, }, // wglDXUnlockObjectsNV + { 0x00000001411A1A60, 0, }, // wglDXUnregisterObjectNV + { 0x00000001411A3E60, 0, }, // wglFreeMemoryNV + { 0x00000001411A1A28, 0, }, // wglGetCurrentContext + { 0x00000001411A3D80, 0, }, // wglGetCurrentReadDCARB + { 0x00000001411A3D30, 0, }, // wglGetExtensionsStringARB + { 0x00000001411A3E20, 0, }, // wglGetExtensionsStringEXT + { 0x00000001411A3DA0, 0, }, // wglGetPbufferDCARB + { 0x00000001411A3D50, 0, }, // wglGetPixelFormatAttribfvARB + { 0x00000001411A3D40, 0, }, // wglGetPixelFormatAttribivARB + { 0x00000001411A1A20, 0, }, // wglGetProcAddress + { 0x00000001411A3E40, 0, }, // wglGetSwapIntervalEXT + { 0x00000001411A3E70, 0, }, // wglGetVideoDeviceNV + { 0x00000001411A3EC0, 0, }, // wglGetVideoInfoNV + { 0x00000001411A3ED0, 0, }, // wglJoinSwapGroupNV + { 0x00000001411A3D70, 0, }, // wglMakeContextCurrentARB + { 0x00000001411A3F10, 0, }, // wglQueryFrameCountNV + { 0x00000001411A3F00, 0, }, // wglQueryMaxSwapGroupsNV + { 0x00000001411A3DD0, 0, }, // wglQueryPbufferARB + { 0x00000001411A3EF0, 0, }, // wglQuerySwapGroupNV + { 0x00000001411A3DB0, 0, }, // wglReleasePbufferDCARB + { 0x00000001411A3DF0, 0, }, // wglReleaseTexImageARB + { 0x00000001411A3E80, 0, }, // wglReleaseVideoDeviceNV + { 0x00000001411A3EA0, 0, }, // wglReleaseVideoImageNV + { 0x00000001411A3F20, 0, }, // wglResetFrameCountNV + { 0x00000001411A3D20, 0, }, // wglRestoreBufferRegionARB + { 0x00000001411A3D10, 0, }, // wglSaveBufferRegionARB + { 0x00000001411A3EB0, 0, }, // wglSendPbufferToVideoNV + { 0x00000001411A3E00, 0, }, // wglSetPbufferAttribARB + { 0x00000001411A3E30, 0, }, // wglSwapIntervalEXT +}; + +gl_func_struct gl_addr_glut[7] = { + { 0x000000000002A358, 0, }, // glFinish + { 0x000000000002A438, 0, }, // glViewport + { 0x000000000002A368, 0, }, // wglDeleteContext + { 0x000000000002A420, 0, }, // wglGetCurrentContext + { 0x000000000002A428, 0, }, // wglGetCurrentDC + { 0x000000000002A448, 0, }, // wglGetProcAddress + { 0x000000000002A430, 0, }, // wglMakeCurrent +}; + +bool GL_VERSION_3_3 = false; +bool GL_VERSION_4_0 = false; +bool GL_VERSION_4_1 = false; +bool GL_VERSION_4_2 = false; +bool GL_VERSION_4_3 = false; +bool GL_VERSION_4_4 = false; +bool GL_VERSION_4_5 = false; +bool GL_VERSION_4_6 = false; + +GLuint current_program; + +extern size_t opengl32_handle; + +#ifdef DEBUG +static void print_debug_error_old(const char* c, const char* e) { + if (e) + printf("DivaGL Deprecated: Debug: %s Error: %s; Time %li\n", c, e, clock()); + else + printf("DivaGL Deprecated: Debug: %s; Time %li\n", c, clock()); +} +#endif + +#ifdef DEBUG +static void print_debug_error(const char* c, const char* e) { + if (e) + printf("DivaGL: Debug: %s Error: %s; Time %li\n", c, e, clock()); +#ifdef PRINT_DEBUG + else + printf("DivaGL: Debug: %s; Time %li\n", c, clock()); +#endif +} +#endif + +void FASTCALL wrap_addresses() { +#ifdef DEBUG + print_debug_error("Patching tables", 0); +#endif + + for (int i = 0; i < 78; i++) + if (wrap_addr_dll[i].func != *(size_t*)wrap_addr_dll[i].address) { + wrap_addr_dll[i].orig_func = *(size_t*)wrap_addr_dll[i].address; + inject_uint64_t((void*)wrap_addr_dll[i].address, wrap_addr_dll[i].func); + } + + for (int i = 0; i < 9; i++) + gl_addr_dll[i].func = *(size_t*)gl_addr_dll[i].address; + +#ifdef DEBUG + print_debug_error("DLL include table patched", 0); +#endif + + for (int i = 0; i < 27; i++) + if (wrap_addr_glut[i].func != *(size_t*)(glut_handle + wrap_addr_glut[i].address)) { + wrap_addr_glut[i].orig_func = *(size_t*)(glut_handle + wrap_addr_glut[i].address); + inject_uint64_t((void*)(glut_handle + wrap_addr_glut[i].address), wrap_addr_glut[i].func); + } + + for (int i = 0; i < 7; i++) + gl_addr_glut[i].func = *(size_t*)(glut_handle + gl_addr_glut[i].address); + +#ifdef DEBUG + print_debug_error("GLUT DLL include table patched", 0); +#endif + + for (int i = 0; i < 50; i++) + if (wrap_addr[i].func != *(size_t*)wrap_addr[i].address) { + wrap_addr[i].orig_func = *(size_t*)wrap_addr[i].address; + inject_uint64_t((void*)wrap_addr[i].address, wrap_addr[i].func); + } + + for (int i = 0; i < 1057; i++) + gl_addr[i].func = *(size_t*)gl_addr[i].address; + +#ifdef DEBUG + print_debug_error("wglGetProcAddresses table patched", 0); +#endif + + const char* version = (const char*)glGetStringGLUT(GL_VERSION); + if (version) { + int32_t major; + int32_t minor; + sscanf_s(version, "%d.%d", &major, &minor); + + GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + GL_VERSION_4_0 = (major == 4 && minor >= 0) || major > 4; + GL_VERSION_4_1 = (major == 4 && minor >= 1) || major > 4; + GL_VERSION_4_2 = (major == 4 && minor >= 2) || major > 4; + GL_VERSION_4_3 = (major == 4 && minor >= 3) || major > 4; + GL_VERSION_4_4 = (major == 4 && minor >= 4) || major > 4; + GL_VERSION_4_5 = (major == 4 && minor >= 5) || major > 4; + GL_VERSION_4_6 = (major == 4 && minor >= 6) || major > 4; + } +} + +HOOK(void, FASTCALL, wglGetProcAddresses, 0x0000000140461B50) { + originalwglGetProcAddresses(); + wrap_addresses(); +} + +HOOK(GLenum, FASTCALL, gl_check_framebuffer_status, 0x0000000140503240) { + return glCheckFramebufferStatus(GL_FRAMEBUFFER); +} + +void wrap_patch() { + // glShadeModel(GL_SMOOTH); + WRITE_NOP_11(0x00000001401948CA); + + // glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_ZERO); + // glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FIXED_ONLY_ARB); + // glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FIXED_ONLY_ARB); + WRITE_JUMP(0x0000000140194932, 0x000000014019495B); + + // glCheckFramebufferStatusEXT -> glCheckFramebufferStatus + //WRITE_NULL(0x0000000140A0C3E0, 0x03); + + INSTALL_HOOK(wglGetProcAddresses); + //INSTALL_HOOK(gl_check_framebuffer_status); +} + +void GLAPIENTRY glAlphaFuncDLL(GLenum func, GLfloat ref) { + if (func == GL_GREATER && ref >= 0.5f) + uniform->arr[U_ALPHA_TEST] = 1; + else + uniform->arr[U_ALPHA_TEST] = 0; + ((PFNGLALPHAFUNCDLLPROC)wrap_addr_dll[GLALPHAFUNCDLL].orig_func)(func, ref); +} + +void GLAPIENTRY glBeginDLL(GLenum mode) { + ((PFNGLBEGINDLLPROC)wrap_addr_dll[GLBEGINDLL].orig_func)(mode); +} + +void GLAPIENTRY glBindTextureDLL(GLenum target, GLuint texture) { + ((PFNGLBINDTEXTUREDLLPROC)wrap_addr_dll[GLBINDTEXTUREDLL].orig_func)(target, texture); +} + +void GLAPIENTRY glClearDLL(GLbitfield mask) { + ((PFNGLCLEARDLLPROC)wrap_addr_dll[GLCLEARDLL].orig_func)(mask); +} + +void GLAPIENTRY glClearColorDLL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + ((PFNGLCLEARCOLORDLLPROC)wrap_addr_dll[GLCLEARCOLORDLL].orig_func)(red, green, blue, alpha); +} + +void GLAPIENTRY glClearDepthDLL(GLdouble depth) { + ((PFNGLCLEARDEPTHDLLPROC)wrap_addr_dll[GLCLEARDEPTHDLL].orig_func)(depth); +} + +void GLAPIENTRY glClearStencilDLL(GLint s) { + ((PFNGLCLEARSTENCILDLLPROC)wrap_addr_dll[GLCLEARSTENCILDLL].orig_func)(s); +} + +void GLAPIENTRY glColor3fDLL(GLfloat red, GLfloat green, GLfloat blue) { + ((PFNGLCOLOR3FDLLPROC)wrap_addr_dll[GLCOLOR3FDLL].orig_func)(red, green, blue); +} + +void GLAPIENTRY glColor4fDLL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + ((PFNGLCOLOR4FDLLPROC)wrap_addr_dll[GLCOLOR4FDLL].orig_func)(red, green, blue, alpha); +} + +void GLAPIENTRY glColor4ubDLL(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { + ((PFNGLCOLOR4UBDLLPROC)wrap_addr_dll[GLCOLOR4UBDLL].orig_func)(red, green, blue, alpha); +} + +void GLAPIENTRY glColor4ubvDLL(GLubyte const * v) { + ((PFNGLCOLOR4UBVDLLPROC)wrap_addr_dll[GLCOLOR4UBVDLL].orig_func)(v); +} + +void GLAPIENTRY glColorPointerDLL(GLint size, GLenum type, GLsizei stride, const void * pointer) { + ((PFNGLCOLORPOINTERDLLPROC)wrap_addr_dll[GLCOLORPOINTERDLL].orig_func)(size, type, stride, pointer); +} + +void GLAPIENTRY glCopyTexImage2DDLL(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { + ((PFNGLCOPYTEXIMAGE2DDLLPROC)wrap_addr_dll[GLCOPYTEXIMAGE2DDLL].orig_func)(target, level, internalformat, x, y, width, height, border); +} + +void GLAPIENTRY glCopyTexSubImage2DDLL(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + ((PFNGLCOPYTEXSUBIMAGE2DDLLPROC)wrap_addr_dll[GLCOPYTEXSUBIMAGE2DDLL].orig_func)(target, level, xoffset, yoffset, x, y, width, height); +} + +void GLAPIENTRY glCullFaceDLL(GLenum mode) { + ((PFNGLCULLFACEDLLPROC)wrap_addr_dll[GLCULLFACEDLL].orig_func)(mode); +} + +void GLAPIENTRY glDepthFuncDLL(GLenum func) { + ((PFNGLDEPTHFUNCDLLPROC)wrap_addr_dll[GLDEPTHFUNCDLL].orig_func)(func); +} + +void GLAPIENTRY glDisableDLL(GLenum cap) { + ((PFNGLDISABLEDLLPROC)wrap_addr_dll[GLDISABLEDLL].orig_func)(cap); +} + +void GLAPIENTRY glDisableClientStateDLL(GLenum array) { + ((PFNGLDISABLECLIENTSTATEDLLPROC)wrap_addr_dll[GLDISABLECLIENTSTATEDLL].orig_func)(array); +} + +void GLAPIENTRY glDrawArraysDLL(GLenum mode, GLint first, GLsizei count) { + ((PFNGLDRAWARRAYSDLLPROC)wrap_addr_dll[GLDRAWARRAYSDLL].orig_func)(mode, first, count); +} + +void GLAPIENTRY glDrawBufferDLL(GLenum buf) { + ((PFNGLDRAWBUFFERDLLPROC)wrap_addr_dll[GLDRAWBUFFERDLL].orig_func)(buf); +} + +void GLAPIENTRY glDrawElementsDLL(GLenum mode, GLsizei count, GLenum type, const void * indices) { + ((PFNGLDRAWELEMENTSDLLPROC)wrap_addr_dll[GLDRAWELEMENTSDLL].orig_func)(mode, count, type, indices); +} + +void GLAPIENTRY glEnableDLL(GLenum cap) { + ((PFNGLENABLEDLLPROC)wrap_addr_dll[GLENABLEDLL].orig_func)(cap); +} + +void GLAPIENTRY glEnableClientStateDLL(GLenum array) { + ((PFNGLENABLECLIENTSTATEDLLPROC)wrap_addr_dll[GLENABLECLIENTSTATEDLL].orig_func)(array); +} + +void GLAPIENTRY glEndDLL() { + ((PFNGLENDDLLPROC)wrap_addr_dll[GLENDDLL].orig_func)(); +} + +void GLAPIENTRY glFogfDLL(GLenum pname, GLfloat param) { + ((PFNGLFOGFDLLPROC)wrap_addr_dll[GLFOGFDLL].orig_func)(pname, param); +} + +void GLAPIENTRY glFogfvDLL(GLenum pname, GLfloat const * params) { + ((PFNGLFOGFVDLLPROC)wrap_addr_dll[GLFOGFVDLL].orig_func)(pname, params); +} + +void GLAPIENTRY glFogiDLL(GLenum pname, GLint param) { + ((PFNGLFOGIDLLPROC)wrap_addr_dll[GLFOGIDLL].orig_func)(pname, param); +} + +void GLAPIENTRY glFrontFaceDLL(GLenum mode) { + ((PFNGLFRONTFACEDLLPROC)wrap_addr_dll[GLFRONTFACEDLL].orig_func)(mode); +} + +void GLAPIENTRY glFrustumDLL(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { + mat4 mat; + mat4_frustrum(left, right, bottom, top, zNear, zFar, &mat); + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLFRUSTUMDLLPROC)wrap_addr_dll[GLFRUSTUMDLL].orig_func)(left, right, bottom, top, zNear, zFar); +} + +void GLAPIENTRY glGetBooleanvDLL(GLenum pname, GLboolean * data) { + switch (pname) { + case GL_VERTEX_PROGRAM_ARB: + case GL_FRAGMENT_PROGRAM_ARB: + if (data) + *data = GL_TRUE; + return; + } + ((PFNGLGETBOOLEANVDLLPROC)wrap_addr_dll[GLGETBOOLEANVDLL].orig_func)(pname, data); +} + +GLenum GLAPIENTRY glGetErrorDLL() { + return ((PFNGLGETERRORDLLPROC)wrap_addr_dll[GLGETERRORDLL].orig_func)(); +} + +void GLAPIENTRY glGetFloatvDLL(GLenum pname, GLfloat * data) { + ((PFNGLGETFLOATVDLLPROC)wrap_addr_dll[GLGETFLOATVDLL].orig_func)(pname, data); +} + +void GLAPIENTRY glGetIntegervDLL(GLenum pname, GLint * data) { + ((PFNGLGETINTEGERVDLLPROC)wrap_addr_dll[GLGETINTEGERVDLL].orig_func)(pname, data); +} + +void GLAPIENTRY glGetMaterialfvDLL(GLenum face, GLenum pname, GLfloat * params) { + ((PFNGLGETMATERIALFVDLLPROC)wrap_addr_dll[GLGETMATERIALFVDLL].orig_func)(face, pname, params); +} + +void GLAPIENTRY glGetTexImageDLL(GLenum target, GLint level, GLenum format, GLenum type, void * pixels) { + ((PFNGLGETTEXIMAGEDLLPROC)wrap_addr_dll[GLGETTEXIMAGEDLL].orig_func)(target, level, format, type, pixels); +} + +void GLAPIENTRY glGetTexLevelParameterivDLL(GLenum target, GLint level, GLenum pname, GLint * params) { + ((PFNGLGETTEXLEVELPARAMETERIVDLLPROC)wrap_addr_dll[GLGETTEXLEVELPARAMETERIVDLL].orig_func)(target, level, pname, params); +} + +void GLAPIENTRY glGetTexParameterivDLL(GLenum target, GLenum pname, GLint * params) { + ((PFNGLGETTEXPARAMETERIVDLLPROC)wrap_addr_dll[GLGETTEXPARAMETERIVDLL].orig_func)(target, pname, params); +} + +GLboolean GLAPIENTRY glIsEnabledDLL(GLenum cap) { + return ((PFNGLISENABLEDDLLPROC)wrap_addr_dll[GLISENABLEDDLL].orig_func)(cap); +} + +void GLAPIENTRY glLightfvDLL(GLenum light, GLenum pname, GLfloat const * params) { + ((PFNGLLIGHTFVDLLPROC)wrap_addr_dll[GLLIGHTFVDLL].orig_func)(light, pname, params); +} + +void GLAPIENTRY glLightModelfvDLL(GLenum pname, GLfloat const * params) { + ((PFNGLLIGHTMODELFVDLLPROC)wrap_addr_dll[GLLIGHTMODELFVDLL].orig_func)(pname, params); +} + +void GLAPIENTRY glLineWidthDLL(GLfloat width) { + ((PFNGLLINEWIDTHDLLPROC)wrap_addr_dll[GLLINEWIDTHDLL].orig_func)(width); +} + +void GLAPIENTRY glLoadIdentityDLL() { + ((PFNGLLOADIDENTITYDLLPROC)wrap_addr_dll[GLLOADIDENTITYDLL].orig_func)(); +} + +void GLAPIENTRY glLoadMatrixfDLL(GLfloat const * m) { + ((PFNGLLOADMATRIXFDLLPROC)wrap_addr_dll[GLLOADMATRIXFDLL].orig_func)(m); +} + +void GLAPIENTRY glMaterialfDLL(GLenum face, GLenum pname, GLfloat param) { + ((PFNGLMATERIALFDLLPROC)wrap_addr_dll[GLMATERIALFDLL].orig_func)(face, pname, param); +} + +void GLAPIENTRY glMaterialfvDLL(GLenum face, GLenum pname, GLfloat const * params) { + ((PFNGLMATERIALFVDLLPROC)wrap_addr_dll[GLMATERIALFVDLL].orig_func)(face, pname, params); +} + +void GLAPIENTRY glMatrixModeDLL(GLenum mode) { + ((PFNGLMATRIXMODEDLLPROC)wrap_addr_dll[GLMATRIXMODEDLL].orig_func)(mode); +} + +void GLAPIENTRY glMultMatrixdDLL(GLdouble const * m) { + ((PFNGLMULTMATRIXDDLLPROC)wrap_addr_dll[GLMULTMATRIXDDLL].orig_func)(m); +} + +void GLAPIENTRY glNormal3fDLL(GLfloat nx, GLfloat ny, GLfloat nz) { + ((PFNGLNORMAL3FDLLPROC)wrap_addr_dll[GLNORMAL3FDLL].orig_func)(nx, ny, nz); +} + +void GLAPIENTRY glNormalPointerDLL(GLenum type, GLsizei stride, const void * pointer) { + ((PFNGLNORMALPOINTERDLLPROC)wrap_addr_dll[GLNORMALPOINTERDLL].orig_func)(type, stride, pointer); +} + +void GLAPIENTRY glOrthoDLL(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { + mat4 mat; + mat4_ortho(left, right, bottom, top, zNear, zFar, &mat); + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLORTHODLLPROC)wrap_addr_dll[GLORTHODLL].orig_func)(left, right, bottom, top, zNear, zFar); +} + +void GLAPIENTRY glPixelStoreiDLL(GLenum pname, GLint param) { + ((PFNGLPIXELSTOREIDLLPROC)wrap_addr_dll[GLPIXELSTOREIDLL].orig_func)(pname, param); +} + +void GLAPIENTRY glPointSizeDLL(GLfloat size) { + ((PFNGLPOINTSIZEDLLPROC)wrap_addr_dll[GLPOINTSIZEDLL].orig_func)(size); +} + +void GLAPIENTRY glPolygonModeDLL(GLenum face, GLenum mode) { + ((PFNGLPOLYGONMODEDLLPROC)wrap_addr_dll[GLPOLYGONMODEDLL].orig_func)(face, mode); +} + +void GLAPIENTRY glPopAttribDLL() { + ((PFNGLPOPATTRIBDLLPROC)wrap_addr_dll[GLPOPATTRIBDLL].orig_func)(); +} + +void GLAPIENTRY glPopClientAttribDLL() { + ((PFNGLPOPCLIENTATTRIBDLLPROC)wrap_addr_dll[GLPOPCLIENTATTRIBDLL].orig_func)(); +} + +void GLAPIENTRY glPopMatrixDLL() { + ((PFNGLPOPMATRIXDLLPROC)wrap_addr_dll[GLPOPMATRIXDLL].orig_func)(); +} + +void GLAPIENTRY glPushAttribDLL(GLbitfield mask) { + ((PFNGLPUSHATTRIBDLLPROC)wrap_addr_dll[GLPUSHATTRIBDLL].orig_func)(mask); +} + +void GLAPIENTRY glPushClientAttribDLL(GLbitfield mask) { + ((PFNGLPUSHCLIENTATTRIBDLLPROC)wrap_addr_dll[GLPUSHCLIENTATTRIBDLL].orig_func)(mask); +} + +void GLAPIENTRY glPushMatrixDLL() { + ((PFNGLPUSHMATRIXDLLPROC)wrap_addr_dll[GLPUSHMATRIXDLL].orig_func)(); +} + +void GLAPIENTRY glReadBufferDLL(GLenum src) { + ((PFNGLREADBUFFERDLLPROC)wrap_addr_dll[GLREADBUFFERDLL].orig_func)(src); +} + +void GLAPIENTRY glReadPixelsDLL(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels) { + ((PFNGLREADPIXELSDLLPROC)wrap_addr_dll[GLREADPIXELSDLL].orig_func)(x, y, width, height, format, type, pixels); +} + +void GLAPIENTRY glRotatefDLL(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + float_t c = cosf(angle * DEG_TO_RAD_FLOAT); + float_t s = sinf(angle * DEG_TO_RAD_FLOAT); + float_t t = 1.0f - c; + + mat4 mat; + mat.row0 = { t * x * x + c, t * x * y + z * s, t * x * z - y * s, 0.0f }; + mat.row1 = { t * y * x - z * s, t * y * y + c, t * y * z + x * s, 0.0f }; + mat.row2 = { t * z * x + y * s, t * z * y - x * s, t * z * z + c, 0.0f }; + mat.row3 = { 0.0f, 0.0f, 0.0f, 1.0f }; + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLROTATEFDLLPROC)wrap_addr_dll[GLROTATEFDLL].orig_func)(angle, x, y, z); +} + +void GLAPIENTRY glScalefDLL(GLfloat x, GLfloat y, GLfloat z) { + mat4 mat; + mat4_scale(x, y, z, &mat); + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLSCALEFDLLPROC)wrap_addr_dll[GLSCALEFDLL].orig_func)(x, y, z); +} + +void GLAPIENTRY glShadeModelDLL(GLenum mode) { + ((PFNGLSHADEMODELDLLPROC)wrap_addr_dll[GLSHADEMODELDLL].orig_func)(mode); +} + +void GLAPIENTRY glTexCoord2fDLL(GLfloat s, GLfloat t) { + ((PFNGLTEXCOORD2FDLLPROC)wrap_addr_dll[GLTEXCOORD2FDLL].orig_func)(s, t); +} + +void GLAPIENTRY glTexCoordPointerDLL(GLint size, GLenum type, GLsizei stride, const void * pointer) { + ((PFNGLTEXCOORDPOINTERDLLPROC)wrap_addr_dll[GLTEXCOORDPOINTERDLL].orig_func)(size, type, stride, pointer); +} + +void GLAPIENTRY glTexEnvfDLL(GLenum target, GLenum pname, GLfloat param) { + ((PFNGLTEXENVFDLLPROC)wrap_addr_dll[GLTEXENVFDLL].orig_func)(target, pname, param); +} + +void GLAPIENTRY glTexEnviDLL(GLenum target, GLenum pname, GLint param) { + ((PFNGLTEXENVIDLLPROC)wrap_addr_dll[GLTEXENVIDLL].orig_func)(target, pname, param); +} + +void GLAPIENTRY glTexImage1DDLL(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels) { + GLint _internalformat; + GLint _format; + switch (internalformat) { + case GL_LUMINANCE_ALPHA16F_ARB: + _internalformat = GL_RG16F; + _format = GL_RG; + break; + default: + _internalformat = internalformat; + _format = format; + break; + } + + ((PFNGLTEXIMAGE1DDLLPROC)wrap_addr_dll[GLTEXIMAGE1DDLL].orig_func)(target, level, _internalformat, width, border, _format, type, pixels); + + switch (internalformat) { + case GL_LUMINANCE_ALPHA16F_ARB: + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_R, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_G, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_B, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_A, GL_GREEN); + break; + } +} + +void GLAPIENTRY glTexImage2DDLL(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels) { + GLint _internalformat; + switch (internalformat) { + case GL_ALPHA8: + _internalformat = GL_R8; + break; + case GL_LUMINANCE8: + _internalformat = GL_R8; + break; + case GL_LUMINANCE8_ALPHA8: + _internalformat = GL_RG8; + break; + default: + _internalformat = internalformat; + break; + } + + ((PFNGLTEXIMAGE2DDLLPROC)wrap_addr_dll[GLTEXIMAGE2DDLL].orig_func)(target, level, _internalformat, width, height, border, format, type, pixels); + + switch (internalformat) { + case GL_ALPHA8: + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_R, GL_ZERO); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_G, GL_ZERO); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_B, GL_ZERO); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_A, GL_RED); + break; + case GL_LUMINANCE8: + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_R, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_G, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_B, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_A, GL_ONE); + break; + case GL_LUMINANCE8_ALPHA8: + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_R, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_G, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_B, GL_RED); + glTexParameteriDLL(target, GL_TEXTURE_SWIZZLE_A, GL_GREEN); + break; + } +} + +void GLAPIENTRY glTexParameterfDLL(GLenum target, GLenum pname, GLfloat param) { + ((PFNGLTEXPARAMETERFDLLPROC)wrap_addr_dll[GLTEXPARAMETERFDLL].orig_func)(target, pname, param); +} + +void GLAPIENTRY glTexParameterfvDLL(GLenum target, GLenum pname, GLfloat const * params) { + ((PFNGLTEXPARAMETERFVDLLPROC)wrap_addr_dll[GLTEXPARAMETERFVDLL].orig_func)(target, pname, params); +} + +void GLAPIENTRY glTexParameteriDLL(GLenum target, GLenum pname, GLint param) { + ((PFNGLTEXPARAMETERIDLLPROC)wrap_addr_dll[GLTEXPARAMETERIDLL].orig_func)(target, pname, param); +} + +void GLAPIENTRY glTexSubImage2DDLL(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels) { + ((PFNGLTEXSUBIMAGE2DDLLPROC)wrap_addr_dll[GLTEXSUBIMAGE2DDLL].orig_func)(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +void GLAPIENTRY glTranslatefDLL(GLfloat x, GLfloat y, GLfloat z) { + mat4 mat; + mat4_translate(x, y, z, &mat); + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLTRANSLATEFDLLPROC)wrap_addr_dll[GLTRANSLATEFDLL].orig_func)(x, y, z); +} + +void GLAPIENTRY glVertex3fDLL(GLfloat x, GLfloat y, GLfloat z) { + ((PFNGLVERTEX3FDLLPROC)wrap_addr_dll[GLVERTEX3FDLL].orig_func)(x, y, z); +} + +void GLAPIENTRY glVertex3fvDLL(GLfloat const * v) { + ((PFNGLVERTEX3FVDLLPROC)wrap_addr_dll[GLVERTEX3FVDLL].orig_func)(v); +} + +void GLAPIENTRY glVertexPointerDLL(GLint size, GLenum type, GLsizei stride, const void * pointer) { + ((PFNGLVERTEXPOINTERDLLPROC)wrap_addr_dll[GLVERTEXPOINTERDLL].orig_func)(size, type, stride, pointer); +} + +void GLAPIENTRY glActiveTexture(GLenum texture) { + ((PFNGLACTIVETEXTUREPROC)wrap_addr[GLACTIVETEXTURE].orig_func)(texture); +} + +void GLAPIENTRY glBindBufferARB(GLenum target, GLuint buffer) { + ((PFNGLBINDBUFFERARBPROC)wrap_addr[GLBINDBUFFERARB].orig_func)(target, buffer); +} + +void GLAPIENTRY glBindBufferBaseNV(GLenum target, GLuint index, GLuint buffer) { + ((PFNGLBINDBUFFERBASENVPROC)wrap_addr[GLBINDBUFFERBASENV].orig_func)(target, index, buffer); +} + +void GLAPIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) { + ((PFNGLBINDFRAMEBUFFEREXTPROC)wrap_addr[GLBINDFRAMEBUFFEREXT].orig_func)(target, framebuffer); +} + +void GLAPIENTRY glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) { + ((PFNGLBINDMULTITEXTUREEXTPROC)wrap_addr[GLBINDMULTITEXTUREEXT].orig_func)(texunit, target, texture); +} + +void GLAPIENTRY glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) { + ((PFNGLBINDRENDERBUFFEREXTPROC)wrap_addr[GLBINDRENDERBUFFEREXT].orig_func)(target, renderbuffer); +} + +void GLAPIENTRY glBufferDataARB(GLenum target, GLsizeiptrARB size, const void * data, GLenum usage) { + ((PFNGLBUFFERDATAARBPROC)wrap_addr[GLBUFFERDATAARB].orig_func)(target, size, data, usage); +} + +void GLAPIENTRY glClampColorARB(GLenum target, GLenum clamp) { + ((PFNGLCLAMPCOLORARBPROC)wrap_addr[GLCLAMPCOLORARB].orig_func)(target, clamp); +} + +void GLAPIENTRY glClientActiveTexture(GLenum texture) { + ((PFNGLCLIENTACTIVETEXTUREPROC)wrap_addr[GLCLIENTACTIVETEXTURE].orig_func)(texture); +} + +void GLAPIENTRY glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + ((PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC)wrap_addr[GLCOPYMULTITEXSUBIMAGE2DEXT].orig_func)(texunit, target, level, xoffset, yoffset, x, y, width, height); +} + +void GLAPIENTRY glDeleteBuffersARB(GLsizei n, GLuint const * buffers) { + ((PFNGLDELETEBUFFERSARBPROC)wrap_addr[GLDELETEBUFFERSARB].orig_func)(n, buffers); +} + +void GLAPIENTRY glDeleteFramebuffersEXT(GLsizei n, GLuint const * framebuffers) { + ((PFNGLDELETEFRAMEBUFFERSEXTPROC)wrap_addr[GLDELETEFRAMEBUFFERSEXT].orig_func)(n, framebuffers); +} + +void GLAPIENTRY glDeleteRenderbuffersEXT(GLsizei n, GLuint const * renderbuffers) { + ((PFNGLDELETERENDERBUFFERSEXTPROC)wrap_addr[GLDELETERENDERBUFFERSEXT].orig_func)(n, renderbuffers); +} + +void GLAPIENTRY glDeleteTextures(GLsizei n, GLuint const * textures) { + glDeleteTexturesDLL(n, textures); + //((PFNGLDELETETEXTURESPROC)wrap_addr[GLDELETETEXTURES].orig_func)(n, textures); +} + +void GLAPIENTRY glDisableVertexAttribArrayARB(GLuint index) { + ((PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)wrap_addr[GLDISABLEVERTEXATTRIBARRAYARB].orig_func)(index); +} + +void GLAPIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) { + ((PFNGLDRAWRANGEELEMENTSPROC)wrap_addr[GLDRAWRANGEELEMENTS].orig_func)(mode, start, end, count, type, indices); +} + +void GLAPIENTRY glEnableVertexAttribArray(GLuint index) { + ((PFNGLENABLEVERTEXATTRIBARRAYPROC)wrap_addr[GLENABLEVERTEXATTRIBARRAY].orig_func)(index); +} + +void GLAPIENTRY glEnableVertexAttribArrayARB(GLuint index) { + ((PFNGLENABLEVERTEXATTRIBARRAYARBPROC)wrap_addr[GLENABLEVERTEXATTRIBARRAYARB].orig_func)(index); +} + +void GLAPIENTRY glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { + ((PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wrap_addr[GLFRAMEBUFFERRENDERBUFFEREXT].orig_func)(target, attachment, renderbuffertarget, renderbuffer); +} + +void GLAPIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + ((PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wrap_addr[GLFRAMEBUFFERTEXTURE2DEXT].orig_func)(target, attachment, textarget, texture, level); +} + +void GLAPIENTRY glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers) { + ((PFNGLGENFRAMEBUFFERSEXTPROC)wrap_addr[GLGENFRAMEBUFFERSEXT].orig_func)(n, framebuffers); +} + +void GLAPIENTRY glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers) { + ((PFNGLGENRENDERBUFFERSEXTPROC)wrap_addr[GLGENRENDERBUFFERSEXT].orig_func)(n, renderbuffers); +} + +void GLAPIENTRY glGenTextures(GLsizei n, GLuint * textures) { + glGenTexturesDLL(n, textures); + //((PFNGLGENTEXTURESPROC)wrap_addr[GLGENTEXTURES].orig_func)(n, textures); +} + +void GLAPIENTRY glGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat * params) { + ((PFNGLGETPROGRAMENVPARAMETERFVARBPROC)wrap_addr[GLGETPROGRAMENVPARAMETERFVARB].orig_func)(target, index, params); +} + +void GLAPIENTRY glGetProgramivARB(GLenum target, GLenum pname, GLint * params) { + switch (pname) { + case GL_VERTEX_PROGRAM_ARB: + case GL_FRAGMENT_PROGRAM_ARB: + if (params) + *params = 0; + return; + } + ((PFNGLGETPROGRAMIVARBPROC)wrap_addr[GLGETPROGRAMIVARB].orig_func)(target, pname, params); +} + +void GLAPIENTRY glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void * pixels) { + ((PFNGLGETTEXTUREIMAGEEXTPROC)wrap_addr[GLGETTEXTUREIMAGEEXT].orig_func)(texture, target, level, format, type, pixels); +} + +GLboolean GLAPIENTRY glIsBufferARB(GLuint buffer) { + return ((PFNGLISBUFFERARBPROC)wrap_addr[GLISBUFFERARB].orig_func)(buffer); +} + +void GLAPIENTRY glLoadTransposeMatrixf(GLfloat const * m) { + ((PFNGLLOADTRANSPOSEMATRIXFPROC)wrap_addr[GLLOADTRANSPOSEMATRIXF].orig_func)(m); +} + +void * GLAPIENTRY glMapNamedBufferEXT(GLuint buffer, GLenum access) { + return ((PFNGLMAPNAMEDBUFFEREXTPROC)wrap_addr[GLMAPNAMEDBUFFEREXT].orig_func)(buffer, access); +} + +void GLAPIENTRY glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) { + ((PFNGLMULTITEXCOORD2FPROC)wrap_addr[GLMULTITEXCOORD2F].orig_func)(target, s, t); +} + +void GLAPIENTRY glMultiTexCoord2fv(GLenum target, GLfloat const * v) { + ((PFNGLMULTITEXCOORD2FVPROC)wrap_addr[GLMULTITEXCOORD2FV].orig_func)(target, v); +} + +void GLAPIENTRY glMultTransposeMatrixf(GLfloat const * m) { + ((PFNGLMULTTRANSPOSEMATRIXFPROC)wrap_addr[GLMULTTRANSPOSEMATRIXF].orig_func)(m); +} + +void GLAPIENTRY glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage) { + ((PFNGLNAMEDBUFFERDATAEXTPROC)wrap_addr[GLNAMEDBUFFERDATAEXT].orig_func)(buffer, size, data, usage); +} + +void GLAPIENTRY glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data) { + ((PFNGLNAMEDBUFFERSUBDATAEXTPROC)wrap_addr[GLNAMEDBUFFERSUBDATAEXT].orig_func)(buffer, offset, size, data); +} + +void GLAPIENTRY glPointParameterf(GLenum pname, GLfloat param) { + ((PFNGLPOINTPARAMETERFPROC)wrap_addr[GLPOINTPARAMETERF].orig_func)(pname, param); +} + +void GLAPIENTRY glPointParameterfv(GLenum pname, GLfloat const * params) { + ((PFNGLPOINTPARAMETERFVPROC)wrap_addr[GLPOINTPARAMETERFV].orig_func)(pname, params); +} + +void GLAPIENTRY glPointParameteri(GLenum pname, GLint param) { + ((PFNGLPOINTPARAMETERIPROC)wrap_addr[GLPOINTPARAMETERI].orig_func)(pname, param); +} + +void GLAPIENTRY glPrimitiveRestartIndexNV(GLuint index) { + glPrimitiveRestartIndex(index); + //((PFNGLPRIMITIVERESTARTINDEXNVPROC)wrap_addr[GLPRIMITIVERESTARTINDEXNV].orig_func)(index); +} + +void GLAPIENTRY glProgramBufferParametersfvNV(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, GLfloat const * params) { + ((PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC)wrap_addr[GLPROGRAMBUFFERPARAMETERSFVNV].orig_func)(target, bindingIndex, wordIndex, count, params); +} + +void GLAPIENTRY glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + ((PFNGLPROGRAMENVPARAMETER4FARBPROC)wrap_addr[GLPROGRAMENVPARAMETER4FARB].orig_func)(target, index, x, y, z, w); +} + +void GLAPIENTRY glProgramEnvParameter4fvARB(GLenum target, GLuint index, GLfloat const * params) { + ((PFNGLPROGRAMENVPARAMETER4FVARBPROC)wrap_addr[GLPROGRAMENVPARAMETER4FVARB].orig_func)(target, index, params); +} + +void GLAPIENTRY glProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLfloat const * params) { + ((PFNGLPROGRAMENVPARAMETERS4FVEXTPROC)wrap_addr[GLPROGRAMENVPARAMETERS4FVEXT].orig_func)(target, index, count, params); +} + +void GLAPIENTRY glProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + ((PFNGLPROGRAMLOCALPARAMETER4FARBPROC)wrap_addr[GLPROGRAMLOCALPARAMETER4FARB].orig_func)(target, index, x, y, z, w); +} + +void GLAPIENTRY glProgramLocalParameter4fvARB(GLenum target, GLuint index, GLfloat const * params) { + ((PFNGLPROGRAMLOCALPARAMETER4FVARBPROC)wrap_addr[GLPROGRAMLOCALPARAMETER4FVARB].orig_func)(target, index, params); +} + +void GLAPIENTRY glProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLfloat const * params) { + ((PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC)wrap_addr[GLPROGRAMLOCALPARAMETERS4FVEXT].orig_func)(target, index, count, params); +} + +void GLAPIENTRY glRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + ((PFNGLRENDERBUFFERSTORAGEEXTPROC)wrap_addr[GLRENDERBUFFERSTORAGEEXT].orig_func)(target, internalformat, width, height); +} + +void GLAPIENTRY glRenderbufferStorageMultisampleCoverageNV(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height) { + ((PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)wrap_addr[GLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENV].orig_func)(target, coverageSamples, colorSamples, internalformat, width, height); +} + +GLboolean GLAPIENTRY glUnmapNamedBufferEXT(GLuint buffer) { + return ((PFNGLUNMAPNAMEDBUFFEREXTPROC)wrap_addr[GLUNMAPNAMEDBUFFEREXT].orig_func)(buffer); +} + +void GLAPIENTRY glUseProgram(GLuint program) { + current_program = program; + ((PFNGLUSEPROGRAMPROC)wrap_addr[GLUSEPROGRAM].orig_func)(program); +} + +void GLAPIENTRY glVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer) { + ((PFNGLVERTEXATTRIBPOINTERARBPROC)wrap_addr[GLVERTEXATTRIBPOINTERARB].orig_func)(index, size, type, normalized, stride, pointer); +} + +void GLAPIENTRY glBeginGLUT(GLenum mode) { + ((PFNGLBEGINGLUTPROC)wrap_addr_glut[GLBEGINGLUT].orig_func)(mode); +} + +void GLAPIENTRY glBitmapGLUT(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const * bitmap) { + ((PFNGLBITMAPGLUTPROC)wrap_addr_glut[GLBITMAPGLUT].orig_func)(width, height, xorig, yorig, xmove, ymove, bitmap); +} + +void GLAPIENTRY glDrawBufferGLUT(GLenum buf) { + ((PFNGLDRAWBUFFERGLUTPROC)wrap_addr_glut[GLDRAWBUFFERGLUT].orig_func)(buf); +} + +void GLAPIENTRY glEnableGLUT(GLenum cap) { + ((PFNGLENABLEGLUTPROC)wrap_addr_glut[GLENABLEGLUT].orig_func)(cap); +} + +void GLAPIENTRY glEndGLUT() { + ((PFNGLENDGLUTPROC)wrap_addr_glut[GLENDGLUT].orig_func)(); +} + +void GLAPIENTRY glEvalMesh2GLUT(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { + ((PFNGLEVALMESH2GLUTPROC)wrap_addr_glut[GLEVALMESH2GLUT].orig_func)(mode, i1, i2, j1, j2); +} + +GLenum GLAPIENTRY glGetErrorGLUT() { + return ((PFNGLGETERRORGLUTPROC)wrap_addr_glut[GLGETERRORGLUT].orig_func)(); +} + +void GLAPIENTRY glGetIntegervGLUT(GLenum pname, GLint * data) { + ((PFNGLGETINTEGERVGLUTPROC)wrap_addr_glut[GLGETINTEGERVGLUT].orig_func)(pname, data); +} + +GLubyte const * GLAPIENTRY glGetStringGLUT(GLenum name) { + return ((PFNGLGETSTRINGGLUTPROC)wrap_addr_glut[GLGETSTRINGGLUT].orig_func)(name); +} + +void GLAPIENTRY glMap2fGLUT(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat const * points) { + ((PFNGLMAP2FGLUTPROC)wrap_addr_glut[GLMAP2FGLUT].orig_func)(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); +} + +void GLAPIENTRY glMapGrid2fGLUT(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) { + ((PFNGLMAPGRID2FGLUTPROC)wrap_addr_glut[GLMAPGRID2FGLUT].orig_func)(un, u1, u2, vn, v1, v2); +} + +void GLAPIENTRY glNormal3fGLUT(GLfloat nx, GLfloat ny, GLfloat nz) { + ((PFNGLNORMAL3FGLUTPROC)wrap_addr_glut[GLNORMAL3FGLUT].orig_func)(nx, ny, nz); +} + +void GLAPIENTRY glNormal3fvGLUT(GLfloat const * v) { + ((PFNGLNORMAL3FVGLUTPROC)wrap_addr_glut[GLNORMAL3FVGLUT].orig_func)(v); +} + +void GLAPIENTRY glPixelStoreiGLUT(GLenum pname, GLint param) { + ((PFNGLPIXELSTOREIGLUTPROC)wrap_addr_glut[GLPIXELSTOREIGLUT].orig_func)(pname, param); +} + +void GLAPIENTRY glPolygonModeGLUT(GLenum face, GLenum mode) { + ((PFNGLPOLYGONMODEGLUTPROC)wrap_addr_glut[GLPOLYGONMODEGLUT].orig_func)(face, mode); +} + +void GLAPIENTRY glPopAttribGLUT() { + ((PFNGLPOPATTRIBGLUTPROC)wrap_addr_glut[GLPOPATTRIBGLUT].orig_func)(); +} + +void GLAPIENTRY glPopMatrixGLUT() { + ((PFNGLPOPMATRIXGLUTPROC)wrap_addr_glut[GLPOPMATRIXGLUT].orig_func)(); +} + +void GLAPIENTRY glPushAttribGLUT(GLbitfield mask) { + ((PFNGLPUSHATTRIBGLUTPROC)wrap_addr_glut[GLPUSHATTRIBGLUT].orig_func)(mask); +} + +void GLAPIENTRY glPushMatrixGLUT() { + ((PFNGLPUSHMATRIXGLUTPROC)wrap_addr_glut[GLPUSHMATRIXGLUT].orig_func)(); +} + +void GLAPIENTRY glReadBufferGLUT(GLenum src) { + ((PFNGLREADBUFFERGLUTPROC)wrap_addr_glut[GLREADBUFFERGLUT].orig_func)(src); +} + +void GLAPIENTRY glRotatefGLUT(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + float_t c = cosf(angle * DEG_TO_RAD_FLOAT); + float_t s = sinf(angle * DEG_TO_RAD_FLOAT); + float_t t = 1.0f - c; + + mat4 mat; + mat.row0 = { t * x * x + c, t * x * y + z * s, t * x * z - y * s, 0.0f }; + mat.row1 = { t * y * x - z * s, t * y * y + c, t * y * z + x * s, 0.0f }; + mat.row2 = { t * z * x + y * s, t * z * y - x * s, t * z * z + c, 0.0f }; + mat.row3 = { 0.0f, 0.0f, 0.0f, 1.0f }; + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLROTATEFGLUTPROC)wrap_addr_glut[GLROTATEFGLUT].orig_func)(angle, x, y, z); +} + +void GLAPIENTRY glScalefGLUT(GLfloat x, GLfloat y, GLfloat z) { + mat4 mat; + mat4_scale(x, y, z, &mat); + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLSCALEFGLUTPROC)wrap_addr_glut[GLSCALEFGLUT].orig_func)(x, y, z); +} + +void GLAPIENTRY glTranslatefGLUT(GLfloat x, GLfloat y, GLfloat z) { + mat4 mat; + mat4_translate(x, y, z, &mat); + mat4_transpose(&mat, &mat); + glMultTransposeMatrixf((const GLfloat*)&mat); + //((PFNGLTRANSLATEFGLUTPROC)wrap_addr_glut[GLTRANSLATEFGLUT].orig_func)(x, y, z); +} + +void GLAPIENTRY glVertex2fGLUT(GLfloat x, GLfloat y) { + ((PFNGLVERTEX2FGLUTPROC)wrap_addr_glut[GLVERTEX2FGLUT].orig_func)(x, y); +} + +void GLAPIENTRY glVertex3fGLUT(GLfloat x, GLfloat y, GLfloat z) { + ((PFNGLVERTEX3FGLUTPROC)wrap_addr_glut[GLVERTEX3FGLUT].orig_func)(x, y, z); +} + +void GLAPIENTRY glVertex3fvGLUT(GLfloat const * v) { + ((PFNGLVERTEX3FVGLUTPROC)wrap_addr_glut[GLVERTEX3FVGLUT].orig_func)(v); +} + +HGLRC GLAPIENTRY wglCreateContextGLUT(HDC hDc) { + return ((PFNWGLCREATECONTEXTGLUTPROC)wrap_addr_glut[WGLCREATECONTEXTGLUT].orig_func)(hDc); +} + +typedef void (GLAPIENTRY* PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint* params); +typedef void (GLAPIENTRY* PFNGLSTENCILMASKPROC)(GLuint mask); +typedef void (GLAPIENTRY* PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); +typedef void (GLAPIENTRY* PFNGLCLEARDEPTHFPROC)(GLfloat d); +typedef void (GLAPIENTRY* PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary); +typedef void (GLAPIENTRY* PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void* binary, GLsizei length); +typedef void (GLAPIENTRY* PFNGLBUFFERSTORAGEPROC)(GLenum target, GLsizeiptr size, const void* data, GLbitfield flags); +typedef void (GLAPIENTRY* PFNGLCREATEBUFFERSPROC)(GLsizei n, GLuint* buffers); +typedef void (GLAPIENTRY* PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint buffer, GLsizeiptr size, const void* data, GLbitfield flags); +typedef void (GLAPIENTRY* PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data); +typedef void* (GLAPIENTRY* PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access); +typedef GLboolean (GLAPIENTRY* PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer); +typedef void (GLAPIENTRY* PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); + +#if DEBUG +typedef void(GLAPIENTRY* PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar* message); +typedef void(GLAPIENTRY* PFNGLPOPDEBUGGROUPPROC)(); +#endif + +static PFNGLTEXPARAMETERIVPROC _glTexParameteriv = 0; +static PFNGLSTENCILMASKPROC _glStencilMask = 0; +static PFNGLPRIMITIVERESTARTINDEXPROC _glPrimitiveRestartIndex = 0; +static PFNGLCLEARDEPTHFPROC _glClearDepthf = 0; +static PFNGLGETPROGRAMBINARYPROC _glGetProgramBinary = 0; +static PFNGLPROGRAMBINARYPROC _glProgramBinary = 0; +static PFNGLBUFFERSTORAGEPROC _glBufferStorage = 0; +static PFNGLCREATEBUFFERSPROC _glCreateBuffers = 0; +static PFNGLNAMEDBUFFERSTORAGEPROC _glNamedBufferStorage = 0; +static PFNGLNAMEDBUFFERSUBDATAPROC _glNamedBufferSubData = 0; +static PFNGLMAPNAMEDBUFFERPROC _glMapNamedBuffer = 0; +static PFNGLUNMAPNAMEDBUFFERPROC _glUnmapNamedBuffer = 0; +static PFNGLTEXTURESUBIMAGE2DPROC _glTextureSubImage2D = 0; + +#if DEBUG +static PFNGLPUSHDEBUGGROUPPROC _glPushDebugGroup = 0; +static PFNGLPOPDEBUGGROUPPROC _glPopDebugGroup = 0; +#endif + +void GLAPIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params) { + if (!_glTexParameteriv) + _glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)GetProcAddress((HMODULE)opengl32_handle, "glTexParameteriv"); + _glTexParameteriv(target, pname, params); +} + +void GLAPIENTRY glStencilMask(GLuint mask) { + if (!_glStencilMask) + _glStencilMask = (PFNGLSTENCILMASKPROC)wglGetProcAddressDLL("glStencilMask"); + _glStencilMask(mask); +} + +void GLAPIENTRY glPrimitiveRestartIndex(GLuint index) { + if (!_glPrimitiveRestartIndex) + _glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)wglGetProcAddressDLL("glPrimitiveRestartIndex"); + _glPrimitiveRestartIndex(index); +} + +void GLAPIENTRY glClearDepthf(GLfloat d) { + if (!_glClearDepthf) + _glClearDepthf = (PFNGLCLEARDEPTHFPROC)wglGetProcAddressDLL("glClearDepthf"); + _glClearDepthf(d); +} + +void GLAPIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) { + if (!_glGetProgramBinary) + _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)wglGetProcAddressDLL("glGetProgramBinary"); + _glGetProgramBinary(program, bufSize, length, binaryFormat, binary); +} + +void GLAPIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const void* binary, GLsizei length) { + if (!_glProgramBinary) + _glProgramBinary = (PFNGLPROGRAMBINARYPROC)wglGetProcAddressDLL("glProgramBinary"); + _glProgramBinary(program, binaryFormat, binary, length); +} + +void GLAPIENTRY glBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLbitfield flags) { + if (!_glBufferStorage) + _glBufferStorage = (PFNGLBUFFERSTORAGEPROC)wglGetProcAddressDLL("glBufferStorage"); + _glBufferStorage(target, size, data, flags); +} + +void GLAPIENTRY glCreateBuffers(GLsizei n, GLuint* buffers) { + if (!_glCreateBuffers) + _glCreateBuffers = (PFNGLCREATEBUFFERSPROC)wglGetProcAddressDLL("glCreateBuffers"); + _glCreateBuffers(n, buffers); +} + +void GLAPIENTRY glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void* data, GLbitfield flags) { + if (!_glNamedBufferStorage) + _glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)wglGetProcAddressDLL("glNamedBufferStorage"); + _glNamedBufferStorage(buffer, size, data, flags); +} + +void GLAPIENTRY glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data) { + if (!_glNamedBufferSubData) + _glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)wglGetProcAddressDLL("glNamedBufferSubData"); + _glNamedBufferSubData(buffer, offset, size, data); +} + +void* GLAPIENTRY glMapNamedBuffer(GLuint buffer, GLenum access) { + if (!_glMapNamedBuffer) + _glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC)wglGetProcAddressDLL("glMapNamedBuffer"); + return _glMapNamedBuffer(buffer, access); +} + +GLboolean GLAPIENTRY glUnmapNamedBuffer(GLuint buffer) { + if (!_glUnmapNamedBuffer) + _glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)wglGetProcAddressDLL("glUnmapNamedBuffer"); + return _glUnmapNamedBuffer(buffer); +} + +void GLAPIENTRY glTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { + if (!_glTextureSubImage2D) + _glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)wglGetProcAddressDLL("glTextureSubImage2D"); + _glTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, type, pixels); +} + +#if DEBUG +void constexpr GLAPIENTRY glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) { + if (!_glPushDebugGroup) + _glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)wglGetProcAddressDLL("glPushDebugGroup"); + return _glPushDebugGroup(source, id, length, message); +} + +void constexpr GLAPIENTRY glPopDebugGroup() { + if (!_glPopDebugGroup) + _glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)wglGetProcAddressDLL("glPopDebugGroup"); + return _glPopDebugGroup(); +} +#endif diff --git a/src/DivaGL/wrap.hpp b/src/DivaGL/wrap.hpp new file mode 100644 index 0000000..f7d00b4 --- /dev/null +++ b/src/DivaGL/wrap.hpp @@ -0,0 +1,3432 @@ +/* + by korenkonder + GitHub/GitLab: korenkonder +*/ + +#pragma once + +#include "gl.hpp" +#include + +struct gl_func_struct { + size_t address; + size_t func; +}; + +typedef void (GLAPIENTRY * PFNGLBLENDFUNCDLLPROC) (GLenum sfactor, GLenum dfactor); +typedef void (GLAPIENTRY * PFNGLCOLORMASKDLLPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESDLLPROC) (GLsizei n, GLuint const * textures); +typedef void (GLAPIENTRY * PFNGLDEPTHMASKDLLPROC) (GLboolean flag); +typedef void (GLAPIENTRY * PFNGLFINISHDLLPROC) (); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESDLLPROC) (GLsizei n, GLuint * textures); +typedef void (GLAPIENTRY * PFNGLSCISSORDLLPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLVIEWPORTDLLPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef PROC (GLAPIENTRY * PFNWGLGETPROCADDRESSDLLPROC) (LPCSTR lpszProc); + +typedef void (GLAPIENTRY * PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); +typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLACTIVEVARYINGNVPROC) (GLuint program, GLchar const * name); +typedef GLboolean (GLAPIENTRY * PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, GLuint const * programs, GLboolean * residences); +typedef GLboolean (GLAPIENTRY * PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, GLuint const * textures, GLboolean * residences); +typedef void (GLAPIENTRY * PFNGLARRAYELEMENTEXTPROC) (GLint i); +typedef void (GLAPIENTRY * PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GLAPIENTRY * PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); +typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, GLchar const * name); +typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, GLcharARB const * name); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, GLchar const * name); +typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, GLchar const * name); +typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); +typedef void (GLAPIENTRY * PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); +typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GLAPIENTRY * PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); +typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAPIENTRY * PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void * data, GLenum usage); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void * data); +typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const void * data); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); +typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, GLint const * value); +typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (GLAPIENTRY * PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (GLAPIENTRY * PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); +typedef void (GLAPIENTRY * PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (GLAPIENTRY * PFNGLCOLOR3HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); +typedef void (GLAPIENTRY * PFNGLCOLOR4HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (GLAPIENTRY * PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void * data); +typedef void (GLAPIENTRY * PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void * data); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void * table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void * table); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * bits); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const void * image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * image); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); +typedef void (GLAPIENTRY * PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATEPROGRAMOBJECTARBPROC) (); +typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); +typedef GLhandleARB (GLAPIENTRY * PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); +typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, GLuint const * buffers); +typedef void (GLAPIENTRY * PFNGLDELETEFENCESNVPROC) (GLsizei n, GLuint const * fences); +typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, GLuint const * framebuffers); +typedef void (GLAPIENTRY * PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); +typedef void (GLAPIENTRY * PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint const * ids); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, GLuint const * programs); +typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, GLuint const * programs); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, GLuint const * ids); +typedef void (GLAPIENTRY * PFNGLDELETEQUERIESARBPROC) (GLsizei n, GLuint const * ids); +typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, GLuint const * renderbuffers); +typedef void (GLAPIENTRY * PFNGLDELETESAMPLERSPROC) (GLsizei count, GLuint const * samplers); +typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GLAPIENTRY * PFNGLDELETETEXTURESEXTPROC) (GLsizei n, GLuint const * textures); +typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, GLuint const * arrays); +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +typedef void (GLAPIENTRY * PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); +typedef void (GLAPIENTRY * PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (GLAPIENTRY * PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); +typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GLAPIENTRY * PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, GLenum const * bufs); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSARBPROC) (GLsizei n, GLenum const * bufs); +typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSATIPROC) (GLsizei n, GLenum const * bufs); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +typedef void (GLAPIENTRY * PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, GLboolean const * pointer); +typedef void (GLAPIENTRY * PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (); +typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERNVPROC) (); +typedef void (GLAPIENTRY * PFNGLENDOCCLUSIONQUERYNVPROC) (); +typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLENDQUERYARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (); +typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKNVPROC) (); +typedef void (GLAPIENTRY * PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); +typedef void (GLAPIENTRY * PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +typedef void (GLAPIENTRY * PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGENVPROC) (); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (GLdouble const * coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDDVEXTPROC) (GLdouble const * coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (GLfloat const * coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDFVEXTPROC) (GLfloat const * coord); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDHVNVPROC) (GLhalfNV const * fog); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, GLenum const * bufs); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint * buffers); +typedef void (GLAPIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint * buffers); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); +typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); +typedef void (GLAPIENTRY * PFNGLGENFENCESNVPROC) (GLsizei n, GLuint * fences); +typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint * framebuffers); +typedef void (GLAPIENTRY * PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint * ids); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint * programs); +typedef void (GLAPIENTRY * PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint * programs); +typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint * ids); +typedef void (GLAPIENTRY * PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint * ids); +typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint * renderbuffers); +typedef void (GLAPIENTRY * PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint * samplers); +typedef void (GLAPIENTRY * PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint * textures); +typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint * arrays); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length, GLint * size, GLenum * type, GLcharARB * name); +typedef void (GLAPIENTRY * PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count, GLhandleARB * obj); +typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, GLchar const * name); +typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLcharARB const * name); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean * data); +typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean * data); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void ** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, void ** params); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, void * table); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, void * data); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, void * img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, void * img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, void * img); +typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, void * img); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, void * image); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble * data); +typedef void (GLAPIENTRY * PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat * data); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, GLchar const * name); +typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, GLchar const * name); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint * params); +typedef GLhandleARB (GLAPIENTRY * PFNGLGETHANDLEARBPROC) (GLenum pname); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void * values); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog); +typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint * data); +typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint * data); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, void * values); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat * val); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, void ** params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void * data); +typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, void * string); +typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, void ** data); +typedef void (GLAPIENTRY * PFNGLGETPOINTERVEXTPROC) (GLenum pname, void ** params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, GLubyte const * name, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, GLubyte const * name, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, void * string); +typedef void (GLAPIENTRY * PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte * program); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, void * row, void * column, void * span); +typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); +typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source); +typedef GLubyte const * (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); +typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint * location); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint * params); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, GLchar const * name); +typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, GLcharARB const * name); +typedef GLintptr (GLAPIENTRY * PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint * params); +typedef GLint (GLAPIENTRY * PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, GLchar const * name); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void ** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, void ** pointer); +typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, void ** pointer); +typedef void (GLAPIENTRY * PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT * params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint * params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT * params); +typedef void (GLAPIENTRY * PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint * params); +typedef void (GLAPIENTRY * PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum target, GLuint index); +typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (GLAPIENTRY * PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program); +typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMNVPROC) (GLuint id); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); +typedef GLboolean (GLAPIENTRY * PFNGLISQUERYARBPROC) (GLuint id); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); +typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); +typedef GLboolean (GLAPIENTRY * PFNGLISTEXTUREEXTPROC) (GLuint texture); +typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, GLubyte const * program); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDARBPROC) (GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFARBPROC) (GLfloat const * m); +typedef void (GLAPIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void * (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); +typedef void * (GLAPIENTRY * PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); +typedef void * (GLAPIENTRY * PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GLAPIENTRY * PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADDEXTPROC) (GLenum mode, GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADFEXTPROC) (GLenum mode, GLfloat const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, GLfloat const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTDEXTPROC) (GLenum mode, GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTFEXTPROC) (GLenum mode, GLfloat const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, GLfloat const * m); +typedef void (GLAPIENTRY * PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GLAPIENTRY * PFNGLMATRIXPOPEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLMATRIXPUSHEXTPROC) (GLenum mode); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint const * first, GLsizei const * count, GLsizei drawcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint const * first, GLsizei const * count, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, GLsizei const * count, GLenum type, const void *const* indices, GLsizei drawcount); +typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, GLsizei const * count, GLenum type, const void *const* indices, GLsizei primcount); +typedef void (GLAPIENTRY * PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, GLint const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDARBPROC) (GLdouble const * m); +typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFARBPROC) (GLfloat const * m); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); +typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble const * params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint const * params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, GLint const * params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const void * string); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); +typedef void (GLAPIENTRY * PFNGLNORMAL3HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAPIENTRY * PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const void * pointer); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); +typedef void (GLAPIENTRY * PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); +typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTNVPROC) (); +typedef void (GLAPIENTRY * PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, GLuint const * textures, GLclampf const * priorities); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, GLint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, GLdouble const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, GLint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, GLint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, GLdouble const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, GLint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, GLint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, GLubyte const * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, GLubyte const * name, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, GLubyte const * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, GLubyte const * name, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const void * string); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +typedef void (GLAPIENTRY * PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, GLuint const * programs); +typedef void (GLAPIENTRY * PFNGLRESETHISTOGRAMPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLRESETMINMAXPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert); +typedef void (GLAPIENTRY * PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat const * param); +typedef void (GLAPIENTRY * PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVEXTPROC) (GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVEXTPROC) (GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVEXTPROC) (GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (GLint const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVEXTPROC) (GLint const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (GLshort const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVEXTPROC) (GLshort const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVEXTPROC) (GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (GLuint const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVEXTPROC) (GLuint const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (GLushort const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVEXTPROC) (GLushort const * v); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * row, const void * column); +typedef void (GLAPIENTRY * PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, GLchar const *const* string, GLint const * length); +typedef void (GLAPIENTRY * PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, GLcharARB const ** string, GLint const * length); +typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GLAPIENTRY * PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); +typedef void (GLAPIENTRY * PFNGLTEXCOORD1HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); +typedef void (GLAPIENTRY * PFNGLTEXCOORD2HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); +typedef void (GLAPIENTRY * PFNGLTEXCOORD3HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); +typedef void (GLAPIENTRY * PFNGLTEXCOORD4HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREBARRIERNVPROC) (); +typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat const * params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint const * params); +typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint const * params); +typedef void (GLAPIENTRY * PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); +typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +typedef void (GLAPIENTRY * PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLsizei count, GLint const * attribs, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, GLchar const *const* varyings, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, GLint const * locations, GLenum bufferMode); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, GLint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, GLuint const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat const * value); +typedef void (GLAPIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); +typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERARBPROC) (GLenum target); +typedef void (GLAPIENTRY * PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); +typedef void (GLAPIENTRY * PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); +typedef void (GLAPIENTRY * PFNGLVERTEX2HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (GLAPIENTRY * PFNGLVERTEX3HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (GLAPIENTRY * PFNGLVERTEX4HVNVPROC) (GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const void * pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, GLushort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, GLushort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, GLushort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, GLushort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, GLbyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, GLint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, GLuint const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, GLushort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, GLushort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const void * pointer); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, GLhalfNV const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, GLshort const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, GLubyte const * v); +typedef void (GLAPIENTRY * PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const void * pointer); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVARBPROC) (GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVARBPROC) (GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (GLint const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVARBPROC) (GLint const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (GLshort const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVARBPROC) (GLshort const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVARBPROC) (GLdouble const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVARBPROC) (GLfloat const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (GLint const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVARBPROC) (GLint const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (GLshort const * v); +typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVARBPROC) (GLshort const * v); +typedef void * (GLAPIENTRY * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef BOOL (GLAPIENTRY * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (GLAPIENTRY * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (GLAPIENTRY * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (GLAPIENTRY * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int * piAttribIList, FLOAT const * pfAttribFList, UINT nMaxFormats, int * piFormats, UINT * nNumFormats); +typedef HANDLE (GLAPIENTRY * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef HGLRC (GLAPIENTRY * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int * attribList); +typedef HPBUFFERARB (GLAPIENTRY * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int * piAttribList); +typedef VOID (GLAPIENTRY * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (GLAPIENTRY * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (GLAPIENTRY * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); +typedef BOOL (GLAPIENTRY * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE * hObjects); +typedef HANDLE (GLAPIENTRY * PFNWGLDXOPENDEVICENVPROC) (void * dxDevice); +typedef HANDLE (GLAPIENTRY * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void * dxObject, GLuint name, GLenum type, GLenum access); +typedef BOOL (GLAPIENTRY * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void * dxObject, HANDLE shareHandle); +typedef BOOL (GLAPIENTRY * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE * hObjects); +typedef BOOL (GLAPIENTRY * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); +typedef void (GLAPIENTRY * PFNWGLFREEMEMORYNVPROC) (void * pointer); +typedef HGLRC (GLAPIENTRY * PFNWGLGETCURRENTCONTEXTPROC) (); +typedef HDC (GLAPIENTRY * PFNWGLGETCURRENTREADDCARBPROC) (); +typedef const char * (GLAPIENTRY * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +typedef const char * (GLAPIENTRY * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (); +typedef HDC (GLAPIENTRY * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (GLAPIENTRY * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, FLOAT * pfValues); +typedef BOOL (GLAPIENTRY * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int * piAttributes, int * piValues); +typedef PROC (GLAPIENTRY * PFNWGLGETPROCADDRESSPROC) (LPCSTR lpszProc); +typedef int (GLAPIENTRY * PFNWGLGETSWAPINTERVALEXTPROC) (); +typedef BOOL (GLAPIENTRY * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV * hVideoDevice); +typedef BOOL (GLAPIENTRY * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long * pulCounterOutputPbuffer, unsigned long * pulCounterOutputVideo); +typedef BOOL (GLAPIENTRY * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (GLAPIENTRY * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef BOOL (GLAPIENTRY * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint * count); +typedef BOOL (GLAPIENTRY * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint * maxGroups, GLuint * maxBarriers); +typedef BOOL (GLAPIENTRY * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int * piValue); +typedef BOOL (GLAPIENTRY * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint * group, GLuint * barrier); +typedef int (GLAPIENTRY * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (GLAPIENTRY * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (GLAPIENTRY * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (GLAPIENTRY * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (GLAPIENTRY * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); +typedef BOOL (GLAPIENTRY * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +typedef BOOL (GLAPIENTRY * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (GLAPIENTRY * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long * pulCounterPbuffer, BOOL bBlock); +typedef BOOL (GLAPIENTRY * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int * piAttribList); +typedef BOOL (GLAPIENTRY * PFNWGLSWAPINTERVALEXTPROC) (int interval); + +typedef void (GLAPIENTRY * PFNGLFINISHGLUTPROC) (); +typedef void (GLAPIENTRY * PFNGLVIEWPORTGLUTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef BOOL (GLAPIENTRY * PFNWGLDELETECONTEXTGLUTPROC) (HGLRC oldContext); +typedef HGLRC (GLAPIENTRY * PFNWGLGETCURRENTCONTEXTGLUTPROC) (); +typedef HDC (GLAPIENTRY * PFNWGLGETCURRENTDCGLUTPROC) (); +typedef PROC (GLAPIENTRY * PFNWGLGETPROCADDRESSGLUTPROC) (LPCSTR lpszProc); +typedef BOOL (GLAPIENTRY * PFNWGLMAKECURRENTGLUTPROC) (HDC hDc, HGLRC newContext); + +#define GLBLENDFUNCDLL 0 +#define GLCOLORMASKDLL 1 +#define GLDELETETEXTURESDLL 2 +#define GLDEPTHMASKDLL 3 +#define GLFINISHDLL 4 +#define GLGENTEXTURESDLL 5 +#define GLSCISSORDLL 6 +#define GLVIEWPORTDLL 7 +#define WGLGETPROCADDRESSDLL 8 + +#define GLACTIVESTENCILFACEEXT 0 +#define GLACTIVETEXTUREARB 1 +#define GLACTIVEVARYINGNV 2 +#define GLAREPROGRAMSRESIDENTNV 3 +#define GLARETEXTURESRESIDENTEXT 4 +#define GLARRAYELEMENTEXT 5 +#define GLATTACHOBJECTARB 6 +#define GLATTACHSHADER 7 +#define GLBEGINCONDITIONALRENDER 8 +#define GLBEGINCONDITIONALRENDERNV 9 +#define GLBEGINOCCLUSIONQUERYNV 10 +#define GLBEGINQUERY 11 +#define GLBEGINQUERYARB 12 +#define GLBEGINTRANSFORMFEEDBACK 13 +#define GLBEGINTRANSFORMFEEDBACKNV 14 +#define GLBINDATTRIBLOCATION 15 +#define GLBINDATTRIBLOCATIONARB 16 +#define GLBINDBUFFER 17 +#define GLBINDBUFFERBASE 18 +#define GLBINDBUFFEROFFSETNV 19 +#define GLBINDBUFFERRANGE 20 +#define GLBINDBUFFERRANGENV 21 +#define GLBINDFRAGDATALOCATION 22 +#define GLBINDFRAGDATALOCATIONEXT 23 +#define GLBINDFRAMEBUFFER 24 +#define GLBINDPROGRAMARB 25 +#define GLBINDPROGRAMNV 26 +#define GLBINDRENDERBUFFER 27 +#define GLBINDSAMPLER 28 +#define GLBINDTEXTUREEXT 29 +#define GLBINDVERTEXARRAY 30 +#define GLBLENDCOLOR 31 +#define GLBLENDCOLOREXT 32 +#define GLBLENDEQUATION 33 +#define GLBLENDEQUATIONEXT 34 +#define GLBLENDEQUATIONSEPARATE 35 +#define GLBLENDEQUATIONSEPARATEEXT 36 +#define GLBLENDFUNCSEPARATE 37 +#define GLBLENDFUNCSEPARATEEXT 38 +#define GLBLITFRAMEBUFFER 39 +#define GLBLITFRAMEBUFFEREXT 40 +#define GLBUFFERDATA 41 +#define GLBUFFERSUBDATA 42 +#define GLBUFFERSUBDATAARB 43 +#define GLCHECKFRAMEBUFFERSTATUS 44 +#define GLCHECKFRAMEBUFFERSTATUSEXT 45 +#define GLCHECKNAMEDFRAMEBUFFERSTATUSEXT 46 +#define GLCLEARBUFFERFI 47 +#define GLCLEARBUFFERFV 48 +#define GLCLEARBUFFERIV 49 +#define GLCLEARBUFFERUIV 50 +#define GLCLEARCOLORIIEXT 51 +#define GLCLEARCOLORIUIEXT 52 +#define GLCLEARDEPTHDNV 53 +#define GLCLIENTACTIVETEXTUREARB 54 +#define GLCLIENTATTRIBDEFAULTEXT 55 +#define GLCOLOR3HNV 56 +#define GLCOLOR3HVNV 57 +#define GLCOLOR4HNV 58 +#define GLCOLOR4HVNV 59 +#define GLCOLORMASKI 60 +#define GLCOLORMASKINDEXEDEXT 61 +#define GLCOLORPOINTEREXT 62 +#define GLCOLORSUBTABLE 63 +#define GLCOLORSUBTABLEEXT 64 +#define GLCOLORTABLE 65 +#define GLCOLORTABLEEXT 66 +#define GLCOLORTABLEPARAMETERFV 67 +#define GLCOLORTABLEPARAMETERIV 68 +#define GLCOMBINERINPUTNV 69 +#define GLCOMBINEROUTPUTNV 70 +#define GLCOMBINERPARAMETERFNV 71 +#define GLCOMBINERPARAMETERFVNV 72 +#define GLCOMBINERPARAMETERINV 73 +#define GLCOMBINERPARAMETERIVNV 74 +#define GLCOMBINERSTAGEPARAMETERFVNV 75 +#define GLCOMPILESHADER 76 +#define GLCOMPILESHADERARB 77 +#define GLCOMPRESSEDMULTITEXIMAGE1DEXT 78 +#define GLCOMPRESSEDMULTITEXIMAGE2DEXT 79 +#define GLCOMPRESSEDMULTITEXIMAGE3DEXT 80 +#define GLCOMPRESSEDMULTITEXSUBIMAGE1DEXT 81 +#define GLCOMPRESSEDMULTITEXSUBIMAGE2DEXT 82 +#define GLCOMPRESSEDMULTITEXSUBIMAGE3DEXT 83 +#define GLCOMPRESSEDTEXIMAGE1D 84 +#define GLCOMPRESSEDTEXIMAGE1DARB 85 +#define GLCOMPRESSEDTEXIMAGE2D 86 +#define GLCOMPRESSEDTEXIMAGE2DARB 87 +#define GLCOMPRESSEDTEXIMAGE3D 88 +#define GLCOMPRESSEDTEXIMAGE3DARB 89 +#define GLCOMPRESSEDTEXSUBIMAGE1D 90 +#define GLCOMPRESSEDTEXSUBIMAGE1DARB 91 +#define GLCOMPRESSEDTEXSUBIMAGE2D 92 +#define GLCOMPRESSEDTEXSUBIMAGE2DARB 93 +#define GLCOMPRESSEDTEXSUBIMAGE3D 94 +#define GLCOMPRESSEDTEXSUBIMAGE3DARB 95 +#define GLCOMPRESSEDTEXTUREIMAGE1DEXT 96 +#define GLCOMPRESSEDTEXTUREIMAGE2DEXT 97 +#define GLCOMPRESSEDTEXTUREIMAGE3DEXT 98 +#define GLCOMPRESSEDTEXTURESUBIMAGE1DEXT 99 +#define GLCOMPRESSEDTEXTURESUBIMAGE2DEXT 100 +#define GLCOMPRESSEDTEXTURESUBIMAGE3DEXT 101 +#define GLCONVOLUTIONFILTER1D 102 +#define GLCONVOLUTIONFILTER2D 103 +#define GLCONVOLUTIONPARAMETERF 104 +#define GLCONVOLUTIONPARAMETERFV 105 +#define GLCONVOLUTIONPARAMETERI 106 +#define GLCONVOLUTIONPARAMETERIV 107 +#define GLCOPYCOLORSUBTABLE 108 +#define GLCOPYCOLORTABLE 109 +#define GLCOPYCONVOLUTIONFILTER1D 110 +#define GLCOPYCONVOLUTIONFILTER2D 111 +#define GLCOPYIMAGESUBDATA 112 +#define GLCOPYMULTITEXIMAGE1DEXT 113 +#define GLCOPYMULTITEXIMAGE2DEXT 114 +#define GLCOPYMULTITEXSUBIMAGE1DEXT 115 +#define GLCOPYMULTITEXSUBIMAGE3DEXT 116 +#define GLCOPYTEXSUBIMAGE3D 117 +#define GLCOPYTEXSUBIMAGE3DEXT 118 +#define GLCOPYTEXTUREIMAGE1DEXT 119 +#define GLCOPYTEXTUREIMAGE2DEXT 120 +#define GLCOPYTEXTURESUBIMAGE1DEXT 121 +#define GLCOPYTEXTURESUBIMAGE2DEXT 122 +#define GLCOPYTEXTURESUBIMAGE3DEXT 123 +#define GLCREATEPROGRAM 124 +#define GLCREATEPROGRAMOBJECTARB 125 +#define GLCREATESHADER 126 +#define GLCREATESHADEROBJECTARB 127 +#define GLDELETEBUFFERS 128 +#define GLDELETEFENCESNV 129 +#define GLDELETEFRAMEBUFFERS 130 +#define GLDELETEOBJECTARB 131 +#define GLDELETEOCCLUSIONQUERIESNV 132 +#define GLDELETEPROGRAM 133 +#define GLDELETEPROGRAMSARB 134 +#define GLDELETEPROGRAMSNV 135 +#define GLDELETEQUERIES 136 +#define GLDELETEQUERIESARB 137 +#define GLDELETERENDERBUFFERS 138 +#define GLDELETESAMPLERS 139 +#define GLDELETESHADER 140 +#define GLDELETETEXTURESEXT 141 +#define GLDELETEVERTEXARRAYS 142 +#define GLDEPTHBOUNDSDNV 143 +#define GLDEPTHBOUNDSEXT 144 +#define GLDEPTHRANGEDNV 145 +#define GLDETACHOBJECTARB 146 +#define GLDETACHSHADER 147 +#define GLDISABLECLIENTSTATEINDEXEDEXT 148 +#define GLDISABLEI 149 +#define GLDISABLEINDEXEDEXT 150 +#define GLDISABLEVERTEXATTRIBARRAY 151 +#define GLDRAWARRAYSEXT 152 +#define GLDRAWARRAYSINSTANCEDARB 153 +#define GLDRAWARRAYSINSTANCEDEXT 154 +#define GLDRAWBUFFERS 155 +#define GLDRAWBUFFERSARB 156 +#define GLDRAWBUFFERSATI 157 +#define GLDRAWELEMENTSINSTANCEDARB 158 +#define GLDRAWELEMENTSINSTANCEDEXT 159 +#define GLDRAWRANGEELEMENTSEXT 160 +#define GLEDGEFLAGPOINTEREXT 161 +#define GLENABLECLIENTSTATEINDEXEDEXT 162 +#define GLENABLEI 163 +#define GLENABLEINDEXEDEXT 164 +#define GLENDCONDITIONALRENDER 165 +#define GLENDCONDITIONALRENDERNV 166 +#define GLENDOCCLUSIONQUERYNV 167 +#define GLENDQUERY 168 +#define GLENDQUERYARB 169 +#define GLENDTRANSFORMFEEDBACK 170 +#define GLENDTRANSFORMFEEDBACKNV 171 +#define GLEXECUTEPROGRAMNV 172 +#define GLFINALCOMBINERINPUTNV 173 +#define GLFINISHFENCENV 174 +#define GLFLUSHMAPPEDBUFFERRANGE 175 +#define GLFLUSHPIXELDATARANGENV 176 +#define GLFLUSHVERTEXARRAYRANGENV 177 +#define GLFOGCOORDD 178 +#define GLFOGCOORDDEXT 179 +#define GLFOGCOORDDV 180 +#define GLFOGCOORDDVEXT 181 +#define GLFOGCOORDF 182 +#define GLFOGCOORDFEXT 183 +#define GLFOGCOORDFV 184 +#define GLFOGCOORDFVEXT 185 +#define GLFOGCOORDHNV 186 +#define GLFOGCOORDHVNV 187 +#define GLFOGCOORDPOINTER 188 +#define GLFOGCOORDPOINTEREXT 189 +#define GLFRAMEBUFFERDRAWBUFFEREXT 190 +#define GLFRAMEBUFFERDRAWBUFFERSEXT 191 +#define GLFRAMEBUFFERREADBUFFEREXT 192 +#define GLFRAMEBUFFERRENDERBUFFER 193 +#define GLFRAMEBUFFERTEXTURE 194 +#define GLFRAMEBUFFERTEXTURE1D 195 +#define GLFRAMEBUFFERTEXTURE1DEXT 196 +#define GLFRAMEBUFFERTEXTURE2D 197 +#define GLFRAMEBUFFERTEXTURE3D 198 +#define GLFRAMEBUFFERTEXTURE3DEXT 199 +#define GLFRAMEBUFFERTEXTUREARB 200 +#define GLFRAMEBUFFERTEXTUREEXT 201 +#define GLFRAMEBUFFERTEXTUREFACEARB 202 +#define GLFRAMEBUFFERTEXTUREFACEEXT 203 +#define GLFRAMEBUFFERTEXTURELAYER 204 +#define GLFRAMEBUFFERTEXTURELAYERARB 205 +#define GLFRAMEBUFFERTEXTURELAYEREXT 206 +#define GLGENBUFFERS 207 +#define GLGENBUFFERSARB 208 +#define GLGENERATEMIPMAP 209 +#define GLGENERATEMIPMAPEXT 210 +#define GLGENERATEMULTITEXMIPMAPEXT 211 +#define GLGENERATETEXTUREMIPMAPEXT 212 +#define GLGENFENCESNV 213 +#define GLGENFRAMEBUFFERS 214 +#define GLGENOCCLUSIONQUERIESNV 215 +#define GLGENPROGRAMSARB 216 +#define GLGENPROGRAMSNV 217 +#define GLGENQUERIES 218 +#define GLGENQUERIESARB 219 +#define GLGENRENDERBUFFERS 220 +#define GLGENSAMPLERS 221 +#define GLGENTEXTURESEXT 222 +#define GLGENVERTEXARRAYS 223 +#define GLGETACTIVEATTRIB 224 +#define GLGETACTIVEATTRIBARB 225 +#define GLGETACTIVEUNIFORM 226 +#define GLGETACTIVEUNIFORMARB 227 +#define GLGETACTIVEVARYINGNV 228 +#define GLGETATTACHEDOBJECTSARB 229 +#define GLGETATTACHEDSHADERS 230 +#define GLGETATTRIBLOCATION 231 +#define GLGETATTRIBLOCATIONARB 232 +#define GLGETBOOLEANI_V 233 +#define GLGETBOOLEANINDEXEDVEXT 234 +#define GLGETBUFFERPARAMETERIV 235 +#define GLGETBUFFERPARAMETERIVARB 236 +#define GLGETBUFFERPOINTERV 237 +#define GLGETBUFFERPOINTERVARB 238 +#define GLGETBUFFERSUBDATA 239 +#define GLGETBUFFERSUBDATAARB 240 +#define GLGETCOLORTABLE 241 +#define GLGETCOLORTABLEEXT 242 +#define GLGETCOLORTABLEPARAMETERFV 243 +#define GLGETCOLORTABLEPARAMETERFVEXT 244 +#define GLGETCOLORTABLEPARAMETERIV 245 +#define GLGETCOLORTABLEPARAMETERIVEXT 246 +#define GLGETCOMBINERINPUTPARAMETERFVNV 247 +#define GLGETCOMBINERINPUTPARAMETERIVNV 248 +#define GLGETCOMBINEROUTPUTPARAMETERFVNV 249 +#define GLGETCOMBINEROUTPUTPARAMETERIVNV 250 +#define GLGETCOMBINERSTAGEPARAMETERFVNV 251 +#define GLGETCOMPRESSEDMULTITEXIMAGEEXT 252 +#define GLGETCOMPRESSEDTEXIMAGE 253 +#define GLGETCOMPRESSEDTEXIMAGEARB 254 +#define GLGETCOMPRESSEDTEXTUREIMAGEEXT 255 +#define GLGETCONVOLUTIONFILTER 256 +#define GLGETCONVOLUTIONPARAMETERFV 257 +#define GLGETCONVOLUTIONPARAMETERIV 258 +#define GLGETDOUBLEINDEXEDVEXT 259 +#define GLGETFENCEIVNV 260 +#define GLGETFINALCOMBINERINPUTPARAMETERFVNV 261 +#define GLGETFINALCOMBINERINPUTPARAMETERIVNV 262 +#define GLGETFLOATINDEXEDVEXT 263 +#define GLGETFRAGDATALOCATION 264 +#define GLGETFRAGDATALOCATIONEXT 265 +#define GLGETFRAMEBUFFERATTACHMENTPARAMETERIV 266 +#define GLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXT 267 +#define GLGETFRAMEBUFFERPARAMETERIVEXT 268 +#define GLGETHANDLEARB 269 +#define GLGETHISTOGRAM 270 +#define GLGETHISTOGRAMPARAMETERFV 271 +#define GLGETHISTOGRAMPARAMETERIV 272 +#define GLGETINFOLOGARB 273 +#define GLGETINTEGERI_V 274 +#define GLGETINTEGERINDEXEDVEXT 275 +#define GLGETMINMAX 276 +#define GLGETMINMAXPARAMETERFV 277 +#define GLGETMINMAXPARAMETERIV 278 +#define GLGETMULTISAMPLEFVNV 279 +#define GLGETMULTITEXENVFVEXT 280 +#define GLGETMULTITEXENVIVEXT 281 +#define GLGETMULTITEXGENDVEXT 282 +#define GLGETMULTITEXGENFVEXT 283 +#define GLGETMULTITEXGENIVEXT 284 +#define GLGETMULTITEXIMAGEEXT 285 +#define GLGETMULTITEXLEVELPARAMETERFVEXT 286 +#define GLGETMULTITEXLEVELPARAMETERIVEXT 287 +#define GLGETMULTITEXPARAMETERFVEXT 288 +#define GLGETMULTITEXPARAMETERIIVEXT 289 +#define GLGETMULTITEXPARAMETERIUIVEXT 290 +#define GLGETMULTITEXPARAMETERIVEXT 291 +#define GLGETNAMEDBUFFERPARAMETERIVEXT 292 +#define GLGETNAMEDBUFFERPOINTERVEXT 293 +#define GLGETNAMEDBUFFERSUBDATAEXT 294 +#define GLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXT 295 +#define GLGETNAMEDPROGRAMIVEXT 296 +#define GLGETNAMEDPROGRAMLOCALPARAMETERDVEXT 297 +#define GLGETNAMEDPROGRAMLOCALPARAMETERFVEXT 298 +#define GLGETNAMEDPROGRAMLOCALPARAMETERIIVEXT 299 +#define GLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXT 300 +#define GLGETNAMEDPROGRAMSTRINGEXT 301 +#define GLGETNAMEDRENDERBUFFERPARAMETERIVEXT 302 +#define GLGETOBJECTPARAMETERFVARB 303 +#define GLGETOBJECTPARAMETERIVARB 304 +#define GLGETOCCLUSIONQUERYIVNV 305 +#define GLGETOCCLUSIONQUERYUIVNV 306 +#define GLGETPOINTERINDEXEDVEXT 307 +#define GLGETPOINTERVEXT 308 +#define GLGETPROGRAMENVPARAMETERDVARB 309 +#define GLGETPROGRAMENVPARAMETERIIVNV 310 +#define GLGETPROGRAMENVPARAMETERIUIVNV 311 +#define GLGETPROGRAMINFOLOG 312 +#define GLGETPROGRAMIV 313 +#define GLGETPROGRAMIVNV 314 +#define GLGETPROGRAMLOCALPARAMETERDVARB 315 +#define GLGETPROGRAMLOCALPARAMETERFVARB 316 +#define GLGETPROGRAMLOCALPARAMETERIIVNV 317 +#define GLGETPROGRAMLOCALPARAMETERIUIVNV 318 +#define GLGETPROGRAMNAMEDPARAMETERDVNV 319 +#define GLGETPROGRAMNAMEDPARAMETERFVNV 320 +#define GLGETPROGRAMPARAMETERDVNV 321 +#define GLGETPROGRAMPARAMETERFVNV 322 +#define GLGETPROGRAMSTRINGARB 323 +#define GLGETPROGRAMSTRINGNV 324 +#define GLGETQUERYIV 325 +#define GLGETQUERYIVARB 326 +#define GLGETQUERYOBJECTI64VEXT 327 +#define GLGETQUERYOBJECTIV 328 +#define GLGETQUERYOBJECTIVARB 329 +#define GLGETQUERYOBJECTUI64V 330 +#define GLGETQUERYOBJECTUI64VEXT 331 +#define GLGETQUERYOBJECTUIV 332 +#define GLGETQUERYOBJECTUIVARB 333 +#define GLGETRENDERBUFFERPARAMETERIV 334 +#define GLGETRENDERBUFFERPARAMETERIVEXT 335 +#define GLGETSEPARABLEFILTER 336 +#define GLGETSHADERINFOLOG 337 +#define GLGETSHADERIV 338 +#define GLGETSHADERSOURCE 339 +#define GLGETSHADERSOURCEARB 340 +#define GLGETSTRINGI 341 +#define GLGETTEXPARAMETERIIV 342 +#define GLGETTEXPARAMETERIIVEXT 343 +#define GLGETTEXPARAMETERIUIV 344 +#define GLGETTEXPARAMETERIUIVEXT 345 +#define GLGETTEXTURELEVELPARAMETERFVEXT 346 +#define GLGETTEXTURELEVELPARAMETERIVEXT 347 +#define GLGETTEXTUREPARAMETERFVEXT 348 +#define GLGETTEXTUREPARAMETERIIVEXT 349 +#define GLGETTEXTUREPARAMETERIUIVEXT 350 +#define GLGETTEXTUREPARAMETERIVEXT 351 +#define GLGETTRACKMATRIXIVNV 352 +#define GLGETTRANSFORMFEEDBACKVARYING 353 +#define GLGETTRANSFORMFEEDBACKVARYINGNV 354 +#define GLGETUNIFORMBUFFERSIZEEXT 355 +#define GLGETUNIFORMFV 356 +#define GLGETUNIFORMFVARB 357 +#define GLGETUNIFORMIV 358 +#define GLGETUNIFORMIVARB 359 +#define GLGETUNIFORMLOCATION 360 +#define GLGETUNIFORMLOCATIONARB 361 +#define GLGETUNIFORMOFFSETEXT 362 +#define GLGETUNIFORMUIV 363 +#define GLGETUNIFORMUIVEXT 364 +#define GLGETVARYINGLOCATIONNV 365 +#define GLGETVERTEXATTRIBDV 366 +#define GLGETVERTEXATTRIBDVARB 367 +#define GLGETVERTEXATTRIBDVNV 368 +#define GLGETVERTEXATTRIBFV 369 +#define GLGETVERTEXATTRIBFVARB 370 +#define GLGETVERTEXATTRIBFVNV 371 +#define GLGETVERTEXATTRIBIIV 372 +#define GLGETVERTEXATTRIBIIVEXT 373 +#define GLGETVERTEXATTRIBIUIV 374 +#define GLGETVERTEXATTRIBIUIVEXT 375 +#define GLGETVERTEXATTRIBIV 376 +#define GLGETVERTEXATTRIBIVARB 377 +#define GLGETVERTEXATTRIBIVNV 378 +#define GLGETVERTEXATTRIBPOINTERV 379 +#define GLGETVERTEXATTRIBPOINTERVARB 380 +#define GLGETVERTEXATTRIBPOINTERVNV 381 +#define GLGETVIDEOI64VNV 382 +#define GLGETVIDEOIVNV 383 +#define GLGETVIDEOUI64VNV 384 +#define GLGETVIDEOUIVNV 385 +#define GLHISTOGRAM 386 +#define GLINDEXPOINTEREXT 387 +#define GLISBUFFER 388 +#define GLISENABLEDI 389 +#define GLISENABLEDINDEXEDEXT 390 +#define GLISFENCENV 391 +#define GLISFRAMEBUFFER 392 +#define GLISFRAMEBUFFEREXT 393 +#define GLISOCCLUSIONQUERYNV 394 +#define GLISPROGRAM 395 +#define GLISPROGRAMARB 396 +#define GLISPROGRAMNV 397 +#define GLISQUERY 398 +#define GLISQUERYARB 399 +#define GLISRENDERBUFFER 400 +#define GLISRENDERBUFFEREXT 401 +#define GLISSHADER 402 +#define GLISTEXTUREEXT 403 +#define GLISVERTEXARRAY 404 +#define GLLINKPROGRAM 405 +#define GLLINKPROGRAMARB 406 +#define GLLOADPROGRAMNV 407 +#define GLLOADTRANSPOSEMATRIXD 408 +#define GLLOADTRANSPOSEMATRIXDARB 409 +#define GLLOADTRANSPOSEMATRIXFARB 410 +#define GLLOCKARRAYSEXT 411 +#define GLMAPBUFFER 412 +#define GLMAPBUFFERARB 413 +#define GLMAPBUFFERRANGE 414 +#define GLMATRIXFRUSTUMEXT 415 +#define GLMATRIXLOADDEXT 416 +#define GLMATRIXLOADFEXT 417 +#define GLMATRIXLOADIDENTITYEXT 418 +#define GLMATRIXLOADTRANSPOSEDEXT 419 +#define GLMATRIXLOADTRANSPOSEFEXT 420 +#define GLMATRIXMULTDEXT 421 +#define GLMATRIXMULTFEXT 422 +#define GLMATRIXMULTTRANSPOSEDEXT 423 +#define GLMATRIXMULTTRANSPOSEFEXT 424 +#define GLMATRIXORTHOEXT 425 +#define GLMATRIXPOPEXT 426 +#define GLMATRIXPUSHEXT 427 +#define GLMATRIXROTATEDEXT 428 +#define GLMATRIXROTATEFEXT 429 +#define GLMATRIXSCALEDEXT 430 +#define GLMATRIXSCALEFEXT 431 +#define GLMATRIXTRANSLATEDEXT 432 +#define GLMATRIXTRANSLATEFEXT 433 +#define GLMINMAX 434 +#define GLMULTIDRAWARRAYS 435 +#define GLMULTIDRAWARRAYSEXT 436 +#define GLMULTIDRAWELEMENTS 437 +#define GLMULTIDRAWELEMENTSEXT 438 +#define GLMULTITEXBUFFEREXT 439 +#define GLMULTITEXCOORD1D 440 +#define GLMULTITEXCOORD1DARB 441 +#define GLMULTITEXCOORD1DV 442 +#define GLMULTITEXCOORD1DVARB 443 +#define GLMULTITEXCOORD1F 444 +#define GLMULTITEXCOORD1FARB 445 +#define GLMULTITEXCOORD1FV 446 +#define GLMULTITEXCOORD1FVARB 447 +#define GLMULTITEXCOORD1HNV 448 +#define GLMULTITEXCOORD1HVNV 449 +#define GLMULTITEXCOORD1I 450 +#define GLMULTITEXCOORD1IARB 451 +#define GLMULTITEXCOORD1IV 452 +#define GLMULTITEXCOORD1IVARB 453 +#define GLMULTITEXCOORD1S 454 +#define GLMULTITEXCOORD1SARB 455 +#define GLMULTITEXCOORD1SV 456 +#define GLMULTITEXCOORD1SVARB 457 +#define GLMULTITEXCOORD2D 458 +#define GLMULTITEXCOORD2DARB 459 +#define GLMULTITEXCOORD2DV 460 +#define GLMULTITEXCOORD2DVARB 461 +#define GLMULTITEXCOORD2FARB 462 +#define GLMULTITEXCOORD2FVARB 463 +#define GLMULTITEXCOORD2HNV 464 +#define GLMULTITEXCOORD2HVNV 465 +#define GLMULTITEXCOORD2I 466 +#define GLMULTITEXCOORD2IARB 467 +#define GLMULTITEXCOORD2IV 468 +#define GLMULTITEXCOORD2IVARB 469 +#define GLMULTITEXCOORD2S 470 +#define GLMULTITEXCOORD2SARB 471 +#define GLMULTITEXCOORD2SV 472 +#define GLMULTITEXCOORD2SVARB 473 +#define GLMULTITEXCOORD3D 474 +#define GLMULTITEXCOORD3DARB 475 +#define GLMULTITEXCOORD3DV 476 +#define GLMULTITEXCOORD3DVARB 477 +#define GLMULTITEXCOORD3F 478 +#define GLMULTITEXCOORD3FARB 479 +#define GLMULTITEXCOORD3FV 480 +#define GLMULTITEXCOORD3FVARB 481 +#define GLMULTITEXCOORD3HNV 482 +#define GLMULTITEXCOORD3HVNV 483 +#define GLMULTITEXCOORD3I 484 +#define GLMULTITEXCOORD3IARB 485 +#define GLMULTITEXCOORD3IV 486 +#define GLMULTITEXCOORD3IVARB 487 +#define GLMULTITEXCOORD3S 488 +#define GLMULTITEXCOORD3SARB 489 +#define GLMULTITEXCOORD3SV 490 +#define GLMULTITEXCOORD3SVARB 491 +#define GLMULTITEXCOORD4D 492 +#define GLMULTITEXCOORD4DARB 493 +#define GLMULTITEXCOORD4DV 494 +#define GLMULTITEXCOORD4DVARB 495 +#define GLMULTITEXCOORD4F 496 +#define GLMULTITEXCOORD4FARB 497 +#define GLMULTITEXCOORD4FV 498 +#define GLMULTITEXCOORD4FVARB 499 +#define GLMULTITEXCOORD4HNV 500 +#define GLMULTITEXCOORD4HVNV 501 +#define GLMULTITEXCOORD4I 502 +#define GLMULTITEXCOORD4IARB 503 +#define GLMULTITEXCOORD4IV 504 +#define GLMULTITEXCOORD4IVARB 505 +#define GLMULTITEXCOORD4S 506 +#define GLMULTITEXCOORD4SARB 507 +#define GLMULTITEXCOORD4SV 508 +#define GLMULTITEXCOORD4SVARB 509 +#define GLMULTITEXCOORDPOINTEREXT 510 +#define GLMULTITEXENVFEXT 511 +#define GLMULTITEXENVFVEXT 512 +#define GLMULTITEXENVIEXT 513 +#define GLMULTITEXENVIVEXT 514 +#define GLMULTITEXGENDEXT 515 +#define GLMULTITEXGENDVEXT 516 +#define GLMULTITEXGENFEXT 517 +#define GLMULTITEXGENFVEXT 518 +#define GLMULTITEXGENIEXT 519 +#define GLMULTITEXGENIVEXT 520 +#define GLMULTITEXIMAGE1DEXT 521 +#define GLMULTITEXIMAGE2DEXT 522 +#define GLMULTITEXIMAGE3DEXT 523 +#define GLMULTITEXPARAMETERFEXT 524 +#define GLMULTITEXPARAMETERFVEXT 525 +#define GLMULTITEXPARAMETERIEXT 526 +#define GLMULTITEXPARAMETERIIVEXT 527 +#define GLMULTITEXPARAMETERIUIVEXT 528 +#define GLMULTITEXPARAMETERIVEXT 529 +#define GLMULTITEXRENDERBUFFEREXT 530 +#define GLMULTITEXSUBIMAGE1DEXT 531 +#define GLMULTITEXSUBIMAGE2DEXT 532 +#define GLMULTITEXSUBIMAGE3DEXT 533 +#define GLMULTTRANSPOSEMATRIXD 534 +#define GLMULTTRANSPOSEMATRIXDARB 535 +#define GLMULTTRANSPOSEMATRIXFARB 536 +#define GLNAMEDFRAMEBUFFERRENDERBUFFEREXT 537 +#define GLNAMEDFRAMEBUFFERTEXTURE1DEXT 538 +#define GLNAMEDFRAMEBUFFERTEXTURE2DEXT 539 +#define GLNAMEDFRAMEBUFFERTEXTURE3DEXT 540 +#define GLNAMEDFRAMEBUFFERTEXTUREEXT 541 +#define GLNAMEDFRAMEBUFFERTEXTUREFACEEXT 542 +#define GLNAMEDFRAMEBUFFERTEXTURELAYEREXT 543 +#define GLNAMEDPROGRAMLOCALPARAMETER4DEXT 544 +#define GLNAMEDPROGRAMLOCALPARAMETER4DVEXT 545 +#define GLNAMEDPROGRAMLOCALPARAMETER4FEXT 546 +#define GLNAMEDPROGRAMLOCALPARAMETER4FVEXT 547 +#define GLNAMEDPROGRAMLOCALPARAMETERI4IEXT 548 +#define GLNAMEDPROGRAMLOCALPARAMETERI4IVEXT 549 +#define GLNAMEDPROGRAMLOCALPARAMETERI4UIEXT 550 +#define GLNAMEDPROGRAMLOCALPARAMETERI4UIVEXT 551 +#define GLNAMEDPROGRAMLOCALPARAMETERS4FVEXT 552 +#define GLNAMEDPROGRAMLOCALPARAMETERSI4IVEXT 553 +#define GLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXT 554 +#define GLNAMEDPROGRAMSTRINGEXT 555 +#define GLNAMEDRENDERBUFFERSTORAGEEXT 556 +#define GLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXT 557 +#define GLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXT 558 +#define GLNORMAL3HNV 559 +#define GLNORMAL3HVNV 560 +#define GLNORMALPOINTEREXT 561 +#define GLPIXELDATARANGENV 562 +#define GLPOINTPARAMETERFARB 563 +#define GLPOINTPARAMETERFEXT 564 +#define GLPOINTPARAMETERFVARB 565 +#define GLPOINTPARAMETERFVEXT 566 +#define GLPOINTPARAMETERINV 567 +#define GLPOINTPARAMETERIV 568 +#define GLPOINTPARAMETERIVNV 569 +#define GLPRESENTFRAMEDUALFILLNV 570 +#define GLPRESENTFRAMEKEYEDNV 571 +#define GLPRIMITIVERESTARTNV 572 +#define GLPRIORITIZETEXTURESEXT 573 +#define GLPROGRAMBUFFERPARAMETERSIIVNV 574 +#define GLPROGRAMBUFFERPARAMETERSIUIVNV 575 +#define GLPROGRAMENVPARAMETER4DARB 576 +#define GLPROGRAMENVPARAMETER4DVARB 577 +#define GLPROGRAMENVPARAMETERI4INV 578 +#define GLPROGRAMENVPARAMETERI4IVNV 579 +#define GLPROGRAMENVPARAMETERI4UINV 580 +#define GLPROGRAMENVPARAMETERI4UIVNV 581 +#define GLPROGRAMENVPARAMETERSI4IVNV 582 +#define GLPROGRAMENVPARAMETERSI4UIVNV 583 +#define GLPROGRAMLOCALPARAMETER4DARB 584 +#define GLPROGRAMLOCALPARAMETER4DVARB 585 +#define GLPROGRAMLOCALPARAMETERI4INV 586 +#define GLPROGRAMLOCALPARAMETERI4IVNV 587 +#define GLPROGRAMLOCALPARAMETERI4UINV 588 +#define GLPROGRAMLOCALPARAMETERI4UIVNV 589 +#define GLPROGRAMLOCALPARAMETERSI4IVNV 590 +#define GLPROGRAMLOCALPARAMETERSI4UIVNV 591 +#define GLPROGRAMNAMEDPARAMETER4DNV 592 +#define GLPROGRAMNAMEDPARAMETER4DVNV 593 +#define GLPROGRAMNAMEDPARAMETER4FNV 594 +#define GLPROGRAMNAMEDPARAMETER4FVNV 595 +#define GLPROGRAMPARAMETER4DNV 596 +#define GLPROGRAMPARAMETER4DVNV 597 +#define GLPROGRAMPARAMETER4FNV 598 +#define GLPROGRAMPARAMETER4FVNV 599 +#define GLPROGRAMPARAMETERIARB 600 +#define GLPROGRAMPARAMETERIEXT 601 +#define GLPROGRAMPARAMETERS4DVNV 602 +#define GLPROGRAMPARAMETERS4FVNV 603 +#define GLPROGRAMSTRINGARB 604 +#define GLPROGRAMUNIFORM1FEXT 605 +#define GLPROGRAMUNIFORM1FVEXT 606 +#define GLPROGRAMUNIFORM1IEXT 607 +#define GLPROGRAMUNIFORM1IVEXT 608 +#define GLPROGRAMUNIFORM1UIEXT 609 +#define GLPROGRAMUNIFORM1UIVEXT 610 +#define GLPROGRAMUNIFORM2FEXT 611 +#define GLPROGRAMUNIFORM2FVEXT 612 +#define GLPROGRAMUNIFORM2IEXT 613 +#define GLPROGRAMUNIFORM2IVEXT 614 +#define GLPROGRAMUNIFORM2UIEXT 615 +#define GLPROGRAMUNIFORM2UIVEXT 616 +#define GLPROGRAMUNIFORM3FEXT 617 +#define GLPROGRAMUNIFORM3FVEXT 618 +#define GLPROGRAMUNIFORM3IEXT 619 +#define GLPROGRAMUNIFORM3IVEXT 620 +#define GLPROGRAMUNIFORM3UIEXT 621 +#define GLPROGRAMUNIFORM3UIVEXT 622 +#define GLPROGRAMUNIFORM4FEXT 623 +#define GLPROGRAMUNIFORM4FVEXT 624 +#define GLPROGRAMUNIFORM4IEXT 625 +#define GLPROGRAMUNIFORM4IVEXT 626 +#define GLPROGRAMUNIFORM4UIEXT 627 +#define GLPROGRAMUNIFORM4UIVEXT 628 +#define GLPROGRAMUNIFORMMATRIX2FVEXT 629 +#define GLPROGRAMUNIFORMMATRIX2X3FVEXT 630 +#define GLPROGRAMUNIFORMMATRIX2X4FVEXT 631 +#define GLPROGRAMUNIFORMMATRIX3FVEXT 632 +#define GLPROGRAMUNIFORMMATRIX3X2FVEXT 633 +#define GLPROGRAMUNIFORMMATRIX3X4FVEXT 634 +#define GLPROGRAMUNIFORMMATRIX4FVEXT 635 +#define GLPROGRAMUNIFORMMATRIX4X2FVEXT 636 +#define GLPROGRAMUNIFORMMATRIX4X3FVEXT 637 +#define GLPROGRAMVERTEXLIMITNV 638 +#define GLPUSHCLIENTATTRIBDEFAULTEXT 639 +#define GLQUERYCOUNTER 640 +#define GLRENDERBUFFERSTORAGE 641 +#define GLRENDERBUFFERSTORAGEMULTISAMPLE 642 +#define GLRENDERBUFFERSTORAGEMULTISAMPLEEXT 643 +#define GLREQUESTRESIDENTPROGRAMSNV 644 +#define GLRESETHISTOGRAM 645 +#define GLRESETMINMAX 646 +#define GLSAMPLECOVERAGE 647 +#define GLSAMPLECOVERAGEARB 648 +#define GLSAMPLEMASKINDEXEDNV 649 +#define GLSAMPLERPARAMETERF 650 +#define GLSAMPLERPARAMETERFV 651 +#define GLSAMPLERPARAMETERI 652 +#define GLSECONDARYCOLOR3B 653 +#define GLSECONDARYCOLOR3BEXT 654 +#define GLSECONDARYCOLOR3BV 655 +#define GLSECONDARYCOLOR3BVEXT 656 +#define GLSECONDARYCOLOR3D 657 +#define GLSECONDARYCOLOR3DEXT 658 +#define GLSECONDARYCOLOR3DV 659 +#define GLSECONDARYCOLOR3DVEXT 660 +#define GLSECONDARYCOLOR3F 661 +#define GLSECONDARYCOLOR3FEXT 662 +#define GLSECONDARYCOLOR3FV 663 +#define GLSECONDARYCOLOR3FVEXT 664 +#define GLSECONDARYCOLOR3HNV 665 +#define GLSECONDARYCOLOR3HVNV 666 +#define GLSECONDARYCOLOR3I 667 +#define GLSECONDARYCOLOR3IEXT 668 +#define GLSECONDARYCOLOR3IV 669 +#define GLSECONDARYCOLOR3IVEXT 670 +#define GLSECONDARYCOLOR3S 671 +#define GLSECONDARYCOLOR3SEXT 672 +#define GLSECONDARYCOLOR3SV 673 +#define GLSECONDARYCOLOR3SVEXT 674 +#define GLSECONDARYCOLOR3UB 675 +#define GLSECONDARYCOLOR3UBEXT 676 +#define GLSECONDARYCOLOR3UBV 677 +#define GLSECONDARYCOLOR3UBVEXT 678 +#define GLSECONDARYCOLOR3UI 679 +#define GLSECONDARYCOLOR3UIEXT 680 +#define GLSECONDARYCOLOR3UIV 681 +#define GLSECONDARYCOLOR3UIVEXT 682 +#define GLSECONDARYCOLOR3US 683 +#define GLSECONDARYCOLOR3USEXT 684 +#define GLSECONDARYCOLOR3USV 685 +#define GLSECONDARYCOLOR3USVEXT 686 +#define GLSECONDARYCOLORPOINTER 687 +#define GLSECONDARYCOLORPOINTEREXT 688 +#define GLSEPARABLEFILTER2D 689 +#define GLSETFENCENV 690 +#define GLSHADERSOURCE 691 +#define GLSHADERSOURCEARB 692 +#define GLSTENCILFUNCSEPARATE 693 +#define GLSTENCILMASKSEPARATE 694 +#define GLSTENCILOPSEPARATE 695 +#define GLTESTFENCENV 696 +#define GLTEXBUFFERARB 697 +#define GLTEXBUFFEREXT 698 +#define GLTEXCOORD1HNV 699 +#define GLTEXCOORD1HVNV 700 +#define GLTEXCOORD2HNV 701 +#define GLTEXCOORD2HVNV 702 +#define GLTEXCOORD3HNV 703 +#define GLTEXCOORD3HVNV 704 +#define GLTEXCOORD4HNV 705 +#define GLTEXCOORD4HVNV 706 +#define GLTEXCOORDPOINTEREXT 707 +#define GLTEXIMAGE3D 708 +#define GLTEXIMAGE3DEXT 709 +#define GLTEXPARAMETERIIV 710 +#define GLTEXPARAMETERIIVEXT 711 +#define GLTEXPARAMETERIUIV 712 +#define GLTEXPARAMETERIUIVEXT 713 +#define GLTEXRENDERBUFFERNV 714 +#define GLTEXSTORAGE2D 715 +#define GLTEXSUBIMAGE3D 716 +#define GLTEXSUBIMAGE3DEXT 717 +#define GLTEXTUREBARRIERNV 718 +#define GLTEXTUREBUFFEREXT 719 +#define GLTEXTUREIMAGE1DEXT 720 +#define GLTEXTUREIMAGE2DEXT 721 +#define GLTEXTUREIMAGE3DEXT 722 +#define GLTEXTUREPARAMETERFEXT 723 +#define GLTEXTUREPARAMETERFVEXT 724 +#define GLTEXTUREPARAMETERIEXT 725 +#define GLTEXTUREPARAMETERIIVEXT 726 +#define GLTEXTUREPARAMETERIUIVEXT 727 +#define GLTEXTUREPARAMETERIVEXT 728 +#define GLTEXTURERENDERBUFFEREXT 729 +#define GLTEXTURESTORAGE2DEXT 730 +#define GLTEXTURESUBIMAGE1DEXT 731 +#define GLTEXTURESUBIMAGE2DEXT 732 +#define GLTEXTURESUBIMAGE3DEXT 733 +#define GLTRACKMATRIXNV 734 +#define GLTRANSFORMFEEDBACKATTRIBSNV 735 +#define GLTRANSFORMFEEDBACKVARYINGS 736 +#define GLTRANSFORMFEEDBACKVARYINGSNV 737 +#define GLUNIFORM1F 738 +#define GLUNIFORM1FARB 739 +#define GLUNIFORM1FV 740 +#define GLUNIFORM1FVARB 741 +#define GLUNIFORM1I 742 +#define GLUNIFORM1IARB 743 +#define GLUNIFORM1IV 744 +#define GLUNIFORM1IVARB 745 +#define GLUNIFORM1UI 746 +#define GLUNIFORM1UIEXT 747 +#define GLUNIFORM1UIV 748 +#define GLUNIFORM1UIVEXT 749 +#define GLUNIFORM2F 750 +#define GLUNIFORM2FARB 751 +#define GLUNIFORM2FV 752 +#define GLUNIFORM2FVARB 753 +#define GLUNIFORM2I 754 +#define GLUNIFORM2IARB 755 +#define GLUNIFORM2IV 756 +#define GLUNIFORM2IVARB 757 +#define GLUNIFORM2UI 758 +#define GLUNIFORM2UIEXT 759 +#define GLUNIFORM2UIV 760 +#define GLUNIFORM2UIVEXT 761 +#define GLUNIFORM3F 762 +#define GLUNIFORM3FARB 763 +#define GLUNIFORM3FV 764 +#define GLUNIFORM3FVARB 765 +#define GLUNIFORM3I 766 +#define GLUNIFORM3IARB 767 +#define GLUNIFORM3IV 768 +#define GLUNIFORM3IVARB 769 +#define GLUNIFORM3UI 770 +#define GLUNIFORM3UIEXT 771 +#define GLUNIFORM3UIV 772 +#define GLUNIFORM3UIVEXT 773 +#define GLUNIFORM4F 774 +#define GLUNIFORM4FARB 775 +#define GLUNIFORM4FV 776 +#define GLUNIFORM4FVARB 777 +#define GLUNIFORM4I 778 +#define GLUNIFORM4IARB 779 +#define GLUNIFORM4IV 780 +#define GLUNIFORM4IVARB 781 +#define GLUNIFORM4UI 782 +#define GLUNIFORM4UIEXT 783 +#define GLUNIFORM4UIV 784 +#define GLUNIFORM4UIVEXT 785 +#define GLUNIFORMBUFFEREXT 786 +#define GLUNIFORMMATRIX2FV 787 +#define GLUNIFORMMATRIX2FVARB 788 +#define GLUNIFORMMATRIX2X3FV 789 +#define GLUNIFORMMATRIX2X4FV 790 +#define GLUNIFORMMATRIX3FV 791 +#define GLUNIFORMMATRIX3FVARB 792 +#define GLUNIFORMMATRIX3X2FV 793 +#define GLUNIFORMMATRIX3X4FV 794 +#define GLUNIFORMMATRIX4FV 795 +#define GLUNIFORMMATRIX4FVARB 796 +#define GLUNIFORMMATRIX4X2FV 797 +#define GLUNIFORMMATRIX4X3FV 798 +#define GLUNLOCKARRAYSEXT 799 +#define GLUNMAPBUFFER 800 +#define GLUNMAPBUFFERARB 801 +#define GLUSEPROGRAMOBJECTARB 802 +#define GLVALIDATEPROGRAM 803 +#define GLVALIDATEPROGRAMARB 804 +#define GLVERTEX2HNV 805 +#define GLVERTEX2HVNV 806 +#define GLVERTEX3HNV 807 +#define GLVERTEX3HVNV 808 +#define GLVERTEX4HNV 809 +#define GLVERTEX4HVNV 810 +#define GLVERTEXARRAYRANGENV 811 +#define GLVERTEXATTRIB1D 812 +#define GLVERTEXATTRIB1DARB 813 +#define GLVERTEXATTRIB1DNV 814 +#define GLVERTEXATTRIB1DV 815 +#define GLVERTEXATTRIB1DVARB 816 +#define GLVERTEXATTRIB1DVNV 817 +#define GLVERTEXATTRIB1F 818 +#define GLVERTEXATTRIB1FARB 819 +#define GLVERTEXATTRIB1FNV 820 +#define GLVERTEXATTRIB1FV 821 +#define GLVERTEXATTRIB1FVARB 822 +#define GLVERTEXATTRIB1FVNV 823 +#define GLVERTEXATTRIB1HNV 824 +#define GLVERTEXATTRIB1HVNV 825 +#define GLVERTEXATTRIB1S 826 +#define GLVERTEXATTRIB1SARB 827 +#define GLVERTEXATTRIB1SNV 828 +#define GLVERTEXATTRIB1SV 829 +#define GLVERTEXATTRIB1SVARB 830 +#define GLVERTEXATTRIB1SVNV 831 +#define GLVERTEXATTRIB2D 832 +#define GLVERTEXATTRIB2DARB 833 +#define GLVERTEXATTRIB2DNV 834 +#define GLVERTEXATTRIB2DV 835 +#define GLVERTEXATTRIB2DVARB 836 +#define GLVERTEXATTRIB2DVNV 837 +#define GLVERTEXATTRIB2F 838 +#define GLVERTEXATTRIB2FARB 839 +#define GLVERTEXATTRIB2FNV 840 +#define GLVERTEXATTRIB2FV 841 +#define GLVERTEXATTRIB2FVARB 842 +#define GLVERTEXATTRIB2FVNV 843 +#define GLVERTEXATTRIB2HNV 844 +#define GLVERTEXATTRIB2HVNV 845 +#define GLVERTEXATTRIB2S 846 +#define GLVERTEXATTRIB2SARB 847 +#define GLVERTEXATTRIB2SNV 848 +#define GLVERTEXATTRIB2SV 849 +#define GLVERTEXATTRIB2SVARB 850 +#define GLVERTEXATTRIB2SVNV 851 +#define GLVERTEXATTRIB3D 852 +#define GLVERTEXATTRIB3DARB 853 +#define GLVERTEXATTRIB3DNV 854 +#define GLVERTEXATTRIB3DV 855 +#define GLVERTEXATTRIB3DVARB 856 +#define GLVERTEXATTRIB3DVNV 857 +#define GLVERTEXATTRIB3F 858 +#define GLVERTEXATTRIB3FARB 859 +#define GLVERTEXATTRIB3FNV 860 +#define GLVERTEXATTRIB3FV 861 +#define GLVERTEXATTRIB3FVARB 862 +#define GLVERTEXATTRIB3FVNV 863 +#define GLVERTEXATTRIB3HNV 864 +#define GLVERTEXATTRIB3HVNV 865 +#define GLVERTEXATTRIB3S 866 +#define GLVERTEXATTRIB3SARB 867 +#define GLVERTEXATTRIB3SNV 868 +#define GLVERTEXATTRIB3SV 869 +#define GLVERTEXATTRIB3SVARB 870 +#define GLVERTEXATTRIB3SVNV 871 +#define GLVERTEXATTRIB4BV 872 +#define GLVERTEXATTRIB4BVARB 873 +#define GLVERTEXATTRIB4D 874 +#define GLVERTEXATTRIB4DARB 875 +#define GLVERTEXATTRIB4DNV 876 +#define GLVERTEXATTRIB4DV 877 +#define GLVERTEXATTRIB4DVARB 878 +#define GLVERTEXATTRIB4DVNV 879 +#define GLVERTEXATTRIB4F 880 +#define GLVERTEXATTRIB4FARB 881 +#define GLVERTEXATTRIB4FNV 882 +#define GLVERTEXATTRIB4FV 883 +#define GLVERTEXATTRIB4FVARB 884 +#define GLVERTEXATTRIB4FVNV 885 +#define GLVERTEXATTRIB4HNV 886 +#define GLVERTEXATTRIB4HVNV 887 +#define GLVERTEXATTRIB4IV 888 +#define GLVERTEXATTRIB4IVARB 889 +#define GLVERTEXATTRIB4NBV 890 +#define GLVERTEXATTRIB4NBVARB 891 +#define GLVERTEXATTRIB4NIV 892 +#define GLVERTEXATTRIB4NIVARB 893 +#define GLVERTEXATTRIB4NSV 894 +#define GLVERTEXATTRIB4NSVARB 895 +#define GLVERTEXATTRIB4NUB 896 +#define GLVERTEXATTRIB4NUBARB 897 +#define GLVERTEXATTRIB4NUBV 898 +#define GLVERTEXATTRIB4NUBVARB 899 +#define GLVERTEXATTRIB4NUIV 900 +#define GLVERTEXATTRIB4NUIVARB 901 +#define GLVERTEXATTRIB4NUSV 902 +#define GLVERTEXATTRIB4NUSVARB 903 +#define GLVERTEXATTRIB4S 904 +#define GLVERTEXATTRIB4SARB 905 +#define GLVERTEXATTRIB4SNV 906 +#define GLVERTEXATTRIB4SV 907 +#define GLVERTEXATTRIB4SVARB 908 +#define GLVERTEXATTRIB4SVNV 909 +#define GLVERTEXATTRIB4UBNV 910 +#define GLVERTEXATTRIB4UBV 911 +#define GLVERTEXATTRIB4UBVARB 912 +#define GLVERTEXATTRIB4UBVNV 913 +#define GLVERTEXATTRIB4UIV 914 +#define GLVERTEXATTRIB4UIVARB 915 +#define GLVERTEXATTRIB4USV 916 +#define GLVERTEXATTRIB4USVARB 917 +#define GLVERTEXATTRIBI1I 918 +#define GLVERTEXATTRIBI1IEXT 919 +#define GLVERTEXATTRIBI1IV 920 +#define GLVERTEXATTRIBI1IVEXT 921 +#define GLVERTEXATTRIBI1UI 922 +#define GLVERTEXATTRIBI1UIEXT 923 +#define GLVERTEXATTRIBI1UIV 924 +#define GLVERTEXATTRIBI1UIVEXT 925 +#define GLVERTEXATTRIBI2I 926 +#define GLVERTEXATTRIBI2IEXT 927 +#define GLVERTEXATTRIBI2IV 928 +#define GLVERTEXATTRIBI2IVEXT 929 +#define GLVERTEXATTRIBI2UI 930 +#define GLVERTEXATTRIBI2UIEXT 931 +#define GLVERTEXATTRIBI2UIV 932 +#define GLVERTEXATTRIBI2UIVEXT 933 +#define GLVERTEXATTRIBI3I 934 +#define GLVERTEXATTRIBI3IEXT 935 +#define GLVERTEXATTRIBI3IV 936 +#define GLVERTEXATTRIBI3IVEXT 937 +#define GLVERTEXATTRIBI3UI 938 +#define GLVERTEXATTRIBI3UIEXT 939 +#define GLVERTEXATTRIBI3UIV 940 +#define GLVERTEXATTRIBI3UIVEXT 941 +#define GLVERTEXATTRIBI4BV 942 +#define GLVERTEXATTRIBI4BVEXT 943 +#define GLVERTEXATTRIBI4I 944 +#define GLVERTEXATTRIBI4IEXT 945 +#define GLVERTEXATTRIBI4IV 946 +#define GLVERTEXATTRIBI4IVEXT 947 +#define GLVERTEXATTRIBI4SV 948 +#define GLVERTEXATTRIBI4SVEXT 949 +#define GLVERTEXATTRIBI4UBV 950 +#define GLVERTEXATTRIBI4UBVEXT 951 +#define GLVERTEXATTRIBI4UI 952 +#define GLVERTEXATTRIBI4UIEXT 953 +#define GLVERTEXATTRIBI4UIV 954 +#define GLVERTEXATTRIBI4UIVEXT 955 +#define GLVERTEXATTRIBI4USV 956 +#define GLVERTEXATTRIBI4USVEXT 957 +#define GLVERTEXATTRIBIPOINTER 958 +#define GLVERTEXATTRIBIPOINTEREXT 959 +#define GLVERTEXATTRIBPOINTER 960 +#define GLVERTEXATTRIBPOINTERNV 961 +#define GLVERTEXATTRIBS1DVNV 962 +#define GLVERTEXATTRIBS1FVNV 963 +#define GLVERTEXATTRIBS1HVNV 964 +#define GLVERTEXATTRIBS1SVNV 965 +#define GLVERTEXATTRIBS2DVNV 966 +#define GLVERTEXATTRIBS2FVNV 967 +#define GLVERTEXATTRIBS2HVNV 968 +#define GLVERTEXATTRIBS2SVNV 969 +#define GLVERTEXATTRIBS3DVNV 970 +#define GLVERTEXATTRIBS3FVNV 971 +#define GLVERTEXATTRIBS3HVNV 972 +#define GLVERTEXATTRIBS3SVNV 973 +#define GLVERTEXATTRIBS4DVNV 974 +#define GLVERTEXATTRIBS4FVNV 975 +#define GLVERTEXATTRIBS4HVNV 976 +#define GLVERTEXATTRIBS4SVNV 977 +#define GLVERTEXATTRIBS4UBVNV 978 +#define GLVERTEXPOINTEREXT 979 +#define GLWINDOWPOS2D 980 +#define GLWINDOWPOS2DARB 981 +#define GLWINDOWPOS2DV 982 +#define GLWINDOWPOS2DVARB 983 +#define GLWINDOWPOS2F 984 +#define GLWINDOWPOS2FARB 985 +#define GLWINDOWPOS2FV 986 +#define GLWINDOWPOS2FVARB 987 +#define GLWINDOWPOS2I 988 +#define GLWINDOWPOS2IARB 989 +#define GLWINDOWPOS2IV 990 +#define GLWINDOWPOS2IVARB 991 +#define GLWINDOWPOS2S 992 +#define GLWINDOWPOS2SARB 993 +#define GLWINDOWPOS2SV 994 +#define GLWINDOWPOS2SVARB 995 +#define GLWINDOWPOS3D 996 +#define GLWINDOWPOS3DARB 997 +#define GLWINDOWPOS3DV 998 +#define GLWINDOWPOS3DVARB 999 +#define GLWINDOWPOS3F 1000 +#define GLWINDOWPOS3FARB 1001 +#define GLWINDOWPOS3FV 1002 +#define GLWINDOWPOS3FVARB 1003 +#define GLWINDOWPOS3I 1004 +#define GLWINDOWPOS3IARB 1005 +#define GLWINDOWPOS3IV 1006 +#define GLWINDOWPOS3IVARB 1007 +#define GLWINDOWPOS3S 1008 +#define GLWINDOWPOS3SARB 1009 +#define GLWINDOWPOS3SV 1010 +#define GLWINDOWPOS3SVARB 1011 +#define WGLALLOCATEMEMORYNV 1012 +#define WGLBINDSWAPBARRIERNV 1013 +#define WGLBINDTEXIMAGEARB 1014 +#define WGLBINDVIDEOIMAGENV 1015 +#define WGLCHOOSEPIXELFORMATARB 1016 +#define WGLCREATEBUFFERREGIONARB 1017 +#define WGLCREATECONTEXTATTRIBSARB 1018 +#define WGLCREATEPBUFFERARB 1019 +#define WGLDELETEBUFFERREGIONARB 1020 +#define WGLDESTROYPBUFFERARB 1021 +#define WGLDXCLOSEDEVICENV 1022 +#define WGLDXLOCKOBJECTSNV 1023 +#define WGLDXOPENDEVICENV 1024 +#define WGLDXREGISTEROBJECTNV 1025 +#define WGLDXSETRESOURCESHAREHANDLENV 1026 +#define WGLDXUNLOCKOBJECTSNV 1027 +#define WGLDXUNREGISTEROBJECTNV 1028 +#define WGLFREEMEMORYNV 1029 +#define WGLGETCURRENTCONTEXT 1030 +#define WGLGETCURRENTREADDCARB 1031 +#define WGLGETEXTENSIONSSTRINGARB 1032 +#define WGLGETEXTENSIONSSTRINGEXT 1033 +#define WGLGETPBUFFERDCARB 1034 +#define WGLGETPIXELFORMATATTRIBFVARB 1035 +#define WGLGETPIXELFORMATATTRIBIVARB 1036 +#define WGLGETPROCADDRESS 1037 +#define WGLGETSWAPINTERVALEXT 1038 +#define WGLGETVIDEODEVICENV 1039 +#define WGLGETVIDEOINFONV 1040 +#define WGLJOINSWAPGROUPNV 1041 +#define WGLMAKECONTEXTCURRENTARB 1042 +#define WGLQUERYFRAMECOUNTNV 1043 +#define WGLQUERYMAXSWAPGROUPSNV 1044 +#define WGLQUERYPBUFFERARB 1045 +#define WGLQUERYSWAPGROUPNV 1046 +#define WGLRELEASEPBUFFERDCARB 1047 +#define WGLRELEASETEXIMAGEARB 1048 +#define WGLRELEASEVIDEODEVICENV 1049 +#define WGLRELEASEVIDEOIMAGENV 1050 +#define WGLRESETFRAMECOUNTNV 1051 +#define WGLRESTOREBUFFERREGIONARB 1052 +#define WGLSAVEBUFFERREGIONARB 1053 +#define WGLSENDPBUFFERTOVIDEONV 1054 +#define WGLSETPBUFFERATTRIBARB 1055 +#define WGLSWAPINTERVALEXT 1056 + +#define GLFINISHGLUT 0 +#define GLVIEWPORTGLUT 1 +#define WGLDELETECONTEXTGLUT 2 +#define WGLGETCURRENTCONTEXTGLUT 3 +#define WGLGETCURRENTDCGLUT 4 +#define WGLGETPROCADDRESSGLUT 5 +#define WGLMAKECURRENTGLUT 6 + +extern gl_func_struct gl_addr_dll[9]; +extern gl_func_struct gl_addr[1057]; +extern gl_func_struct gl_addr_glut[7]; + +#define glBlendFuncDLL ((PFNGLBLENDFUNCDLLPROC)gl_addr_dll[GLBLENDFUNCDLL].func) +#define glColorMaskDLL ((PFNGLCOLORMASKDLLPROC)gl_addr_dll[GLCOLORMASKDLL].func) +#define glDeleteTexturesDLL ((PFNGLDELETETEXTURESDLLPROC)gl_addr_dll[GLDELETETEXTURESDLL].func) +#define glDepthMaskDLL ((PFNGLDEPTHMASKDLLPROC)gl_addr_dll[GLDEPTHMASKDLL].func) +#define glFinishDLL ((PFNGLFINISHDLLPROC)gl_addr_dll[GLFINISHDLL].func) +#define glGenTexturesDLL ((PFNGLGENTEXTURESDLLPROC)gl_addr_dll[GLGENTEXTURESDLL].func) +#define glScissorDLL ((PFNGLSCISSORDLLPROC)gl_addr_dll[GLSCISSORDLL].func) +#define glViewportDLL ((PFNGLVIEWPORTDLLPROC)gl_addr_dll[GLVIEWPORTDLL].func) +#define wglGetProcAddressDLL ((PFNWGLGETPROCADDRESSDLLPROC)gl_addr_dll[WGLGETPROCADDRESSDLL].func) + +#define glActiveStencilFaceEXT ((PFNGLACTIVESTENCILFACEEXTPROC)gl_addr[GLACTIVESTENCILFACEEXT].func) +#define glActiveTextureARB ((PFNGLACTIVETEXTUREARBPROC)gl_addr[GLACTIVETEXTUREARB].func) +#define glActiveVaryingNV ((PFNGLACTIVEVARYINGNVPROC)gl_addr[GLACTIVEVARYINGNV].func) +#define glAreProgramsResidentNV ((PFNGLAREPROGRAMSRESIDENTNVPROC)gl_addr[GLAREPROGRAMSRESIDENTNV].func) +#define glAreTexturesResidentEXT ((PFNGLARETEXTURESRESIDENTEXTPROC)gl_addr[GLARETEXTURESRESIDENTEXT].func) +#define glArrayElementEXT ((PFNGLARRAYELEMENTEXTPROC)gl_addr[GLARRAYELEMENTEXT].func) +#define glAttachObjectARB ((PFNGLATTACHOBJECTARBPROC)gl_addr[GLATTACHOBJECTARB].func) +#define glAttachShader ((PFNGLATTACHSHADERPROC)gl_addr[GLATTACHSHADER].func) +#define glBeginConditionalRender ((PFNGLBEGINCONDITIONALRENDERPROC)gl_addr[GLBEGINCONDITIONALRENDER].func) +#define glBeginConditionalRenderNV ((PFNGLBEGINCONDITIONALRENDERNVPROC)gl_addr[GLBEGINCONDITIONALRENDERNV].func) +#define glBeginOcclusionQueryNV ((PFNGLBEGINOCCLUSIONQUERYNVPROC)gl_addr[GLBEGINOCCLUSIONQUERYNV].func) +#define glBeginQuery ((PFNGLBEGINQUERYPROC)gl_addr[GLBEGINQUERY].func) +#define glBeginQueryARB ((PFNGLBEGINQUERYARBPROC)gl_addr[GLBEGINQUERYARB].func) +#define glBeginTransformFeedback ((PFNGLBEGINTRANSFORMFEEDBACKPROC)gl_addr[GLBEGINTRANSFORMFEEDBACK].func) +#define glBeginTransformFeedbackNV ((PFNGLBEGINTRANSFORMFEEDBACKNVPROC)gl_addr[GLBEGINTRANSFORMFEEDBACKNV].func) +#define glBindAttribLocation ((PFNGLBINDATTRIBLOCATIONPROC)gl_addr[GLBINDATTRIBLOCATION].func) +#define glBindAttribLocationARB ((PFNGLBINDATTRIBLOCATIONARBPROC)gl_addr[GLBINDATTRIBLOCATIONARB].func) +#define glBindBuffer ((PFNGLBINDBUFFERPROC)gl_addr[GLBINDBUFFER].func) +#define glBindBufferBase ((PFNGLBINDBUFFERBASEPROC)gl_addr[GLBINDBUFFERBASE].func) +#define glBindBufferOffsetNV ((PFNGLBINDBUFFEROFFSETNVPROC)gl_addr[GLBINDBUFFEROFFSETNV].func) +#define glBindBufferRange ((PFNGLBINDBUFFERRANGEPROC)gl_addr[GLBINDBUFFERRANGE].func) +#define glBindBufferRangeNV ((PFNGLBINDBUFFERRANGENVPROC)gl_addr[GLBINDBUFFERRANGENV].func) +#define glBindFragDataLocation ((PFNGLBINDFRAGDATALOCATIONPROC)gl_addr[GLBINDFRAGDATALOCATION].func) +#define glBindFragDataLocationEXT ((PFNGLBINDFRAGDATALOCATIONEXTPROC)gl_addr[GLBINDFRAGDATALOCATIONEXT].func) +#define glBindFramebuffer ((PFNGLBINDFRAMEBUFFERPROC)gl_addr[GLBINDFRAMEBUFFER].func) +#define glBindProgramARB ((PFNGLBINDPROGRAMARBPROC)gl_addr[GLBINDPROGRAMARB].func) +#define glBindProgramNV ((PFNGLBINDPROGRAMNVPROC)gl_addr[GLBINDPROGRAMNV].func) +#define glBindRenderbuffer ((PFNGLBINDRENDERBUFFERPROC)gl_addr[GLBINDRENDERBUFFER].func) +#define glBindSampler ((PFNGLBINDSAMPLERPROC)gl_addr[GLBINDSAMPLER].func) +#define glBindTextureEXT ((PFNGLBINDTEXTUREEXTPROC)gl_addr[GLBINDTEXTUREEXT].func) +#define glBindVertexArray ((PFNGLBINDVERTEXARRAYPROC)gl_addr[GLBINDVERTEXARRAY].func) +#define glBlendColor ((PFNGLBLENDCOLORPROC)gl_addr[GLBLENDCOLOR].func) +#define glBlendColorEXT ((PFNGLBLENDCOLOREXTPROC)gl_addr[GLBLENDCOLOREXT].func) +#define glBlendEquation ((PFNGLBLENDEQUATIONPROC)gl_addr[GLBLENDEQUATION].func) +#define glBlendEquationEXT ((PFNGLBLENDEQUATIONEXTPROC)gl_addr[GLBLENDEQUATIONEXT].func) +#define glBlendEquationSeparate ((PFNGLBLENDEQUATIONSEPARATEPROC)gl_addr[GLBLENDEQUATIONSEPARATE].func) +#define glBlendEquationSeparateEXT ((PFNGLBLENDEQUATIONSEPARATEEXTPROC)gl_addr[GLBLENDEQUATIONSEPARATEEXT].func) +#define glBlendFuncSeparate ((PFNGLBLENDFUNCSEPARATEPROC)gl_addr[GLBLENDFUNCSEPARATE].func) +#define glBlendFuncSeparateEXT ((PFNGLBLENDFUNCSEPARATEEXTPROC)gl_addr[GLBLENDFUNCSEPARATEEXT].func) +#define glBlitFramebuffer ((PFNGLBLITFRAMEBUFFERPROC)gl_addr[GLBLITFRAMEBUFFER].func) +#define glBlitFramebufferEXT ((PFNGLBLITFRAMEBUFFEREXTPROC)gl_addr[GLBLITFRAMEBUFFEREXT].func) +#define glBufferData ((PFNGLBUFFERDATAPROC)gl_addr[GLBUFFERDATA].func) +#define glBufferSubData ((PFNGLBUFFERSUBDATAPROC)gl_addr[GLBUFFERSUBDATA].func) +#define glBufferSubDataARB ((PFNGLBUFFERSUBDATAARBPROC)gl_addr[GLBUFFERSUBDATAARB].func) +#define glCheckFramebufferStatus ((PFNGLCHECKFRAMEBUFFERSTATUSPROC)gl_addr[GLCHECKFRAMEBUFFERSTATUS].func) +#define glCheckFramebufferStatusEXT ((PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)gl_addr[GLCHECKFRAMEBUFFERSTATUSEXT].func) +#define glCheckNamedFramebufferStatusEXT ((PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC)gl_addr[GLCHECKNAMEDFRAMEBUFFERSTATUSEXT].func) +#define glClearBufferfi ((PFNGLCLEARBUFFERFIPROC)gl_addr[GLCLEARBUFFERFI].func) +#define glClearBufferfv ((PFNGLCLEARBUFFERFVPROC)gl_addr[GLCLEARBUFFERFV].func) +#define glClearBufferiv ((PFNGLCLEARBUFFERIVPROC)gl_addr[GLCLEARBUFFERIV].func) +#define glClearBufferuiv ((PFNGLCLEARBUFFERUIVPROC)gl_addr[GLCLEARBUFFERUIV].func) +#define glClearColorIiEXT ((PFNGLCLEARCOLORIIEXTPROC)gl_addr[GLCLEARCOLORIIEXT].func) +#define glClearColorIuiEXT ((PFNGLCLEARCOLORIUIEXTPROC)gl_addr[GLCLEARCOLORIUIEXT].func) +#define glClearDepthdNV ((PFNGLCLEARDEPTHDNVPROC)gl_addr[GLCLEARDEPTHDNV].func) +#define glClientActiveTextureARB ((PFNGLCLIENTACTIVETEXTUREARBPROC)gl_addr[GLCLIENTACTIVETEXTUREARB].func) +#define glClientAttribDefaultEXT ((PFNGLCLIENTATTRIBDEFAULTEXTPROC)gl_addr[GLCLIENTATTRIBDEFAULTEXT].func) +#define glColor3hNV ((PFNGLCOLOR3HNVPROC)gl_addr[GLCOLOR3HNV].func) +#define glColor3hvNV ((PFNGLCOLOR3HVNVPROC)gl_addr[GLCOLOR3HVNV].func) +#define glColor4hNV ((PFNGLCOLOR4HNVPROC)gl_addr[GLCOLOR4HNV].func) +#define glColor4hvNV ((PFNGLCOLOR4HVNVPROC)gl_addr[GLCOLOR4HVNV].func) +#define glColorMaski ((PFNGLCOLORMASKIPROC)gl_addr[GLCOLORMASKI].func) +#define glColorMaskIndexedEXT ((PFNGLCOLORMASKINDEXEDEXTPROC)gl_addr[GLCOLORMASKINDEXEDEXT].func) +#define glColorPointerEXT ((PFNGLCOLORPOINTEREXTPROC)gl_addr[GLCOLORPOINTEREXT].func) +#define glColorSubTable ((PFNGLCOLORSUBTABLEPROC)gl_addr[GLCOLORSUBTABLE].func) +#define glColorSubTableEXT ((PFNGLCOLORSUBTABLEEXTPROC)gl_addr[GLCOLORSUBTABLEEXT].func) +#define glColorTable ((PFNGLCOLORTABLEPROC)gl_addr[GLCOLORTABLE].func) +#define glColorTableEXT ((PFNGLCOLORTABLEEXTPROC)gl_addr[GLCOLORTABLEEXT].func) +#define glColorTableParameterfv ((PFNGLCOLORTABLEPARAMETERFVPROC)gl_addr[GLCOLORTABLEPARAMETERFV].func) +#define glColorTableParameteriv ((PFNGLCOLORTABLEPARAMETERIVPROC)gl_addr[GLCOLORTABLEPARAMETERIV].func) +#define glCombinerInputNV ((PFNGLCOMBINERINPUTNVPROC)gl_addr[GLCOMBINERINPUTNV].func) +#define glCombinerOutputNV ((PFNGLCOMBINEROUTPUTNVPROC)gl_addr[GLCOMBINEROUTPUTNV].func) +#define glCombinerParameterfNV ((PFNGLCOMBINERPARAMETERFNVPROC)gl_addr[GLCOMBINERPARAMETERFNV].func) +#define glCombinerParameterfvNV ((PFNGLCOMBINERPARAMETERFVNVPROC)gl_addr[GLCOMBINERPARAMETERFVNV].func) +#define glCombinerParameteriNV ((PFNGLCOMBINERPARAMETERINVPROC)gl_addr[GLCOMBINERPARAMETERINV].func) +#define glCombinerParameterivNV ((PFNGLCOMBINERPARAMETERIVNVPROC)gl_addr[GLCOMBINERPARAMETERIVNV].func) +#define glCombinerStageParameterfvNV ((PFNGLCOMBINERSTAGEPARAMETERFVNVPROC)gl_addr[GLCOMBINERSTAGEPARAMETERFVNV].func) +#define glCompileShader ((PFNGLCOMPILESHADERPROC)gl_addr[GLCOMPILESHADER].func) +#define glCompileShaderARB ((PFNGLCOMPILESHADERARBPROC)gl_addr[GLCOMPILESHADERARB].func) +#define glCompressedMultiTexImage1DEXT ((PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC)gl_addr[GLCOMPRESSEDMULTITEXIMAGE1DEXT].func) +#define glCompressedMultiTexImage2DEXT ((PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC)gl_addr[GLCOMPRESSEDMULTITEXIMAGE2DEXT].func) +#define glCompressedMultiTexImage3DEXT ((PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC)gl_addr[GLCOMPRESSEDMULTITEXIMAGE3DEXT].func) +#define glCompressedMultiTexSubImage1DEXT ((PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC)gl_addr[GLCOMPRESSEDMULTITEXSUBIMAGE1DEXT].func) +#define glCompressedMultiTexSubImage2DEXT ((PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC)gl_addr[GLCOMPRESSEDMULTITEXSUBIMAGE2DEXT].func) +#define glCompressedMultiTexSubImage3DEXT ((PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC)gl_addr[GLCOMPRESSEDMULTITEXSUBIMAGE3DEXT].func) +#define glCompressedTexImage1D ((PFNGLCOMPRESSEDTEXIMAGE1DPROC)gl_addr[GLCOMPRESSEDTEXIMAGE1D].func) +#define glCompressedTexImage1DARB ((PFNGLCOMPRESSEDTEXIMAGE1DARBPROC)gl_addr[GLCOMPRESSEDTEXIMAGE1DARB].func) +#define glCompressedTexImage2D ((PFNGLCOMPRESSEDTEXIMAGE2DPROC)gl_addr[GLCOMPRESSEDTEXIMAGE2D].func) +#define glCompressedTexImage2DARB ((PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)gl_addr[GLCOMPRESSEDTEXIMAGE2DARB].func) +#define glCompressedTexImage3D ((PFNGLCOMPRESSEDTEXIMAGE3DPROC)gl_addr[GLCOMPRESSEDTEXIMAGE3D].func) +#define glCompressedTexImage3DARB ((PFNGLCOMPRESSEDTEXIMAGE3DARBPROC)gl_addr[GLCOMPRESSEDTEXIMAGE3DARB].func) +#define glCompressedTexSubImage1D ((PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)gl_addr[GLCOMPRESSEDTEXSUBIMAGE1D].func) +#define glCompressedTexSubImage1DARB ((PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC)gl_addr[GLCOMPRESSEDTEXSUBIMAGE1DARB].func) +#define glCompressedTexSubImage2D ((PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)gl_addr[GLCOMPRESSEDTEXSUBIMAGE2D].func) +#define glCompressedTexSubImage2DARB ((PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC)gl_addr[GLCOMPRESSEDTEXSUBIMAGE2DARB].func) +#define glCompressedTexSubImage3D ((PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)gl_addr[GLCOMPRESSEDTEXSUBIMAGE3D].func) +#define glCompressedTexSubImage3DARB ((PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC)gl_addr[GLCOMPRESSEDTEXSUBIMAGE3DARB].func) +#define glCompressedTextureImage1DEXT ((PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC)gl_addr[GLCOMPRESSEDTEXTUREIMAGE1DEXT].func) +#define glCompressedTextureImage2DEXT ((PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC)gl_addr[GLCOMPRESSEDTEXTUREIMAGE2DEXT].func) +#define glCompressedTextureImage3DEXT ((PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC)gl_addr[GLCOMPRESSEDTEXTUREIMAGE3DEXT].func) +#define glCompressedTextureSubImage1DEXT ((PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC)gl_addr[GLCOMPRESSEDTEXTURESUBIMAGE1DEXT].func) +#define glCompressedTextureSubImage2DEXT ((PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC)gl_addr[GLCOMPRESSEDTEXTURESUBIMAGE2DEXT].func) +#define glCompressedTextureSubImage3DEXT ((PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC)gl_addr[GLCOMPRESSEDTEXTURESUBIMAGE3DEXT].func) +#define glConvolutionFilter1D ((PFNGLCONVOLUTIONFILTER1DPROC)gl_addr[GLCONVOLUTIONFILTER1D].func) +#define glConvolutionFilter2D ((PFNGLCONVOLUTIONFILTER2DPROC)gl_addr[GLCONVOLUTIONFILTER2D].func) +#define glConvolutionParameterf ((PFNGLCONVOLUTIONPARAMETERFPROC)gl_addr[GLCONVOLUTIONPARAMETERF].func) +#define glConvolutionParameterfv ((PFNGLCONVOLUTIONPARAMETERFVPROC)gl_addr[GLCONVOLUTIONPARAMETERFV].func) +#define glConvolutionParameteri ((PFNGLCONVOLUTIONPARAMETERIPROC)gl_addr[GLCONVOLUTIONPARAMETERI].func) +#define glConvolutionParameteriv ((PFNGLCONVOLUTIONPARAMETERIVPROC)gl_addr[GLCONVOLUTIONPARAMETERIV].func) +#define glCopyColorSubTable ((PFNGLCOPYCOLORSUBTABLEPROC)gl_addr[GLCOPYCOLORSUBTABLE].func) +#define glCopyColorTable ((PFNGLCOPYCOLORTABLEPROC)gl_addr[GLCOPYCOLORTABLE].func) +#define glCopyConvolutionFilter1D ((PFNGLCOPYCONVOLUTIONFILTER1DPROC)gl_addr[GLCOPYCONVOLUTIONFILTER1D].func) +#define glCopyConvolutionFilter2D ((PFNGLCOPYCONVOLUTIONFILTER2DPROC)gl_addr[GLCOPYCONVOLUTIONFILTER2D].func) +#define glCopyImageSubData ((PFNGLCOPYIMAGESUBDATAPROC)gl_addr[GLCOPYIMAGESUBDATA].func) +#define glCopyMultiTexImage1DEXT ((PFNGLCOPYMULTITEXIMAGE1DEXTPROC)gl_addr[GLCOPYMULTITEXIMAGE1DEXT].func) +#define glCopyMultiTexImage2DEXT ((PFNGLCOPYMULTITEXIMAGE2DEXTPROC)gl_addr[GLCOPYMULTITEXIMAGE2DEXT].func) +#define glCopyMultiTexSubImage1DEXT ((PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC)gl_addr[GLCOPYMULTITEXSUBIMAGE1DEXT].func) +#define glCopyMultiTexSubImage3DEXT ((PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC)gl_addr[GLCOPYMULTITEXSUBIMAGE3DEXT].func) +#define glCopyTexSubImage3D ((PFNGLCOPYTEXSUBIMAGE3DPROC)gl_addr[GLCOPYTEXSUBIMAGE3D].func) +#define glCopyTexSubImage3DEXT ((PFNGLCOPYTEXSUBIMAGE3DEXTPROC)gl_addr[GLCOPYTEXSUBIMAGE3DEXT].func) +#define glCopyTextureImage1DEXT ((PFNGLCOPYTEXTUREIMAGE1DEXTPROC)gl_addr[GLCOPYTEXTUREIMAGE1DEXT].func) +#define glCopyTextureImage2DEXT ((PFNGLCOPYTEXTUREIMAGE2DEXTPROC)gl_addr[GLCOPYTEXTUREIMAGE2DEXT].func) +#define glCopyTextureSubImage1DEXT ((PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC)gl_addr[GLCOPYTEXTURESUBIMAGE1DEXT].func) +#define glCopyTextureSubImage2DEXT ((PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC)gl_addr[GLCOPYTEXTURESUBIMAGE2DEXT].func) +#define glCopyTextureSubImage3DEXT ((PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC)gl_addr[GLCOPYTEXTURESUBIMAGE3DEXT].func) +#define glCreateProgram ((PFNGLCREATEPROGRAMPROC)gl_addr[GLCREATEPROGRAM].func) +#define glCreateProgramObjectARB ((PFNGLCREATEPROGRAMOBJECTARBPROC)gl_addr[GLCREATEPROGRAMOBJECTARB].func) +#define glCreateShader ((PFNGLCREATESHADERPROC)gl_addr[GLCREATESHADER].func) +#define glCreateShaderObjectARB ((PFNGLCREATESHADEROBJECTARBPROC)gl_addr[GLCREATESHADEROBJECTARB].func) +#define glDeleteBuffers ((PFNGLDELETEBUFFERSPROC)gl_addr[GLDELETEBUFFERS].func) +#define glDeleteFencesNV ((PFNGLDELETEFENCESNVPROC)gl_addr[GLDELETEFENCESNV].func) +#define glDeleteFramebuffers ((PFNGLDELETEFRAMEBUFFERSPROC)gl_addr[GLDELETEFRAMEBUFFERS].func) +#define glDeleteObjectARB ((PFNGLDELETEOBJECTARBPROC)gl_addr[GLDELETEOBJECTARB].func) +#define glDeleteOcclusionQueriesNV ((PFNGLDELETEOCCLUSIONQUERIESNVPROC)gl_addr[GLDELETEOCCLUSIONQUERIESNV].func) +#define glDeleteProgram ((PFNGLDELETEPROGRAMPROC)gl_addr[GLDELETEPROGRAM].func) +#define glDeleteProgramsARB ((PFNGLDELETEPROGRAMSARBPROC)gl_addr[GLDELETEPROGRAMSARB].func) +#define glDeleteProgramsNV ((PFNGLDELETEPROGRAMSNVPROC)gl_addr[GLDELETEPROGRAMSNV].func) +#define glDeleteQueries ((PFNGLDELETEQUERIESPROC)gl_addr[GLDELETEQUERIES].func) +#define glDeleteQueriesARB ((PFNGLDELETEQUERIESARBPROC)gl_addr[GLDELETEQUERIESARB].func) +#define glDeleteRenderbuffers ((PFNGLDELETERENDERBUFFERSPROC)gl_addr[GLDELETERENDERBUFFERS].func) +#define glDeleteSamplers ((PFNGLDELETESAMPLERSPROC)gl_addr[GLDELETESAMPLERS].func) +#define glDeleteShader ((PFNGLDELETESHADERPROC)gl_addr[GLDELETESHADER].func) +#define glDeleteTexturesEXT ((PFNGLDELETETEXTURESEXTPROC)gl_addr[GLDELETETEXTURESEXT].func) +#define glDeleteVertexArrays ((PFNGLDELETEVERTEXARRAYSPROC)gl_addr[GLDELETEVERTEXARRAYS].func) +#define glDepthBoundsdNV ((PFNGLDEPTHBOUNDSDNVPROC)gl_addr[GLDEPTHBOUNDSDNV].func) +#define glDepthBoundsEXT ((PFNGLDEPTHBOUNDSEXTPROC)gl_addr[GLDEPTHBOUNDSEXT].func) +#define glDepthRangedNV ((PFNGLDEPTHRANGEDNVPROC)gl_addr[GLDEPTHRANGEDNV].func) +#define glDetachObjectARB ((PFNGLDETACHOBJECTARBPROC)gl_addr[GLDETACHOBJECTARB].func) +#define glDetachShader ((PFNGLDETACHSHADERPROC)gl_addr[GLDETACHSHADER].func) +#define glDisableClientStateIndexedEXT ((PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC)gl_addr[GLDISABLECLIENTSTATEINDEXEDEXT].func) +#define glDisablei ((PFNGLDISABLEIPROC)gl_addr[GLDISABLEI].func) +#define glDisableIndexedEXT ((PFNGLDISABLEINDEXEDEXTPROC)gl_addr[GLDISABLEINDEXEDEXT].func) +#define glDisableVertexAttribArray ((PFNGLDISABLEVERTEXATTRIBARRAYPROC)gl_addr[GLDISABLEVERTEXATTRIBARRAY].func) +#define glDrawArraysEXT ((PFNGLDRAWARRAYSEXTPROC)gl_addr[GLDRAWARRAYSEXT].func) +#define glDrawArraysInstancedARB ((PFNGLDRAWARRAYSINSTANCEDARBPROC)gl_addr[GLDRAWARRAYSINSTANCEDARB].func) +#define glDrawArraysInstancedEXT ((PFNGLDRAWARRAYSINSTANCEDEXTPROC)gl_addr[GLDRAWARRAYSINSTANCEDEXT].func) +#define glDrawBuffers ((PFNGLDRAWBUFFERSPROC)gl_addr[GLDRAWBUFFERS].func) +#define glDrawBuffersARB ((PFNGLDRAWBUFFERSARBPROC)gl_addr[GLDRAWBUFFERSARB].func) +#define glDrawBuffersATI ((PFNGLDRAWBUFFERSATIPROC)gl_addr[GLDRAWBUFFERSATI].func) +#define glDrawElementsInstancedARB ((PFNGLDRAWELEMENTSINSTANCEDARBPROC)gl_addr[GLDRAWELEMENTSINSTANCEDARB].func) +#define glDrawElementsInstancedEXT ((PFNGLDRAWELEMENTSINSTANCEDEXTPROC)gl_addr[GLDRAWELEMENTSINSTANCEDEXT].func) +#define glDrawRangeElementsEXT ((PFNGLDRAWRANGEELEMENTSEXTPROC)gl_addr[GLDRAWRANGEELEMENTSEXT].func) +#define glEdgeFlagPointerEXT ((PFNGLEDGEFLAGPOINTEREXTPROC)gl_addr[GLEDGEFLAGPOINTEREXT].func) +#define glEnableClientStateIndexedEXT ((PFNGLENABLECLIENTSTATEINDEXEDEXTPROC)gl_addr[GLENABLECLIENTSTATEINDEXEDEXT].func) +#define glEnablei ((PFNGLENABLEIPROC)gl_addr[GLENABLEI].func) +#define glEnableIndexedEXT ((PFNGLENABLEINDEXEDEXTPROC)gl_addr[GLENABLEINDEXEDEXT].func) +#define glEndConditionalRender ((PFNGLENDCONDITIONALRENDERPROC)gl_addr[GLENDCONDITIONALRENDER].func) +#define glEndConditionalRenderNV ((PFNGLENDCONDITIONALRENDERNVPROC)gl_addr[GLENDCONDITIONALRENDERNV].func) +#define glEndOcclusionQueryNV ((PFNGLENDOCCLUSIONQUERYNVPROC)gl_addr[GLENDOCCLUSIONQUERYNV].func) +#define glEndQuery ((PFNGLENDQUERYPROC)gl_addr[GLENDQUERY].func) +#define glEndQueryARB ((PFNGLENDQUERYARBPROC)gl_addr[GLENDQUERYARB].func) +#define glEndTransformFeedback ((PFNGLENDTRANSFORMFEEDBACKPROC)gl_addr[GLENDTRANSFORMFEEDBACK].func) +#define glEndTransformFeedbackNV ((PFNGLENDTRANSFORMFEEDBACKNVPROC)gl_addr[GLENDTRANSFORMFEEDBACKNV].func) +#define glExecuteProgramNV ((PFNGLEXECUTEPROGRAMNVPROC)gl_addr[GLEXECUTEPROGRAMNV].func) +#define glFinalCombinerInputNV ((PFNGLFINALCOMBINERINPUTNVPROC)gl_addr[GLFINALCOMBINERINPUTNV].func) +#define glFinishFenceNV ((PFNGLFINISHFENCENVPROC)gl_addr[GLFINISHFENCENV].func) +#define glFlushMappedBufferRange ((PFNGLFLUSHMAPPEDBUFFERRANGEPROC)gl_addr[GLFLUSHMAPPEDBUFFERRANGE].func) +#define glFlushPixelDataRangeNV ((PFNGLFLUSHPIXELDATARANGENVPROC)gl_addr[GLFLUSHPIXELDATARANGENV].func) +#define glFlushVertexArrayRangeNV ((PFNGLFLUSHVERTEXARRAYRANGENVPROC)gl_addr[GLFLUSHVERTEXARRAYRANGENV].func) +#define glFogCoordd ((PFNGLFOGCOORDDPROC)gl_addr[GLFOGCOORDD].func) +#define glFogCoorddEXT ((PFNGLFOGCOORDDEXTPROC)gl_addr[GLFOGCOORDDEXT].func) +#define glFogCoorddv ((PFNGLFOGCOORDDVPROC)gl_addr[GLFOGCOORDDV].func) +#define glFogCoorddvEXT ((PFNGLFOGCOORDDVEXTPROC)gl_addr[GLFOGCOORDDVEXT].func) +#define glFogCoordf ((PFNGLFOGCOORDFPROC)gl_addr[GLFOGCOORDF].func) +#define glFogCoordfEXT ((PFNGLFOGCOORDFEXTPROC)gl_addr[GLFOGCOORDFEXT].func) +#define glFogCoordfv ((PFNGLFOGCOORDFVPROC)gl_addr[GLFOGCOORDFV].func) +#define glFogCoordfvEXT ((PFNGLFOGCOORDFVEXTPROC)gl_addr[GLFOGCOORDFVEXT].func) +#define glFogCoordhNV ((PFNGLFOGCOORDHNVPROC)gl_addr[GLFOGCOORDHNV].func) +#define glFogCoordhvNV ((PFNGLFOGCOORDHVNVPROC)gl_addr[GLFOGCOORDHVNV].func) +#define glFogCoordPointer ((PFNGLFOGCOORDPOINTERPROC)gl_addr[GLFOGCOORDPOINTER].func) +#define glFogCoordPointerEXT ((PFNGLFOGCOORDPOINTEREXTPROC)gl_addr[GLFOGCOORDPOINTEREXT].func) +#define glFramebufferDrawBufferEXT ((PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC)gl_addr[GLFRAMEBUFFERDRAWBUFFEREXT].func) +#define glFramebufferDrawBuffersEXT ((PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC)gl_addr[GLFRAMEBUFFERDRAWBUFFERSEXT].func) +#define glFramebufferReadBufferEXT ((PFNGLFRAMEBUFFERREADBUFFEREXTPROC)gl_addr[GLFRAMEBUFFERREADBUFFEREXT].func) +#define glFramebufferRenderbuffer ((PFNGLFRAMEBUFFERRENDERBUFFERPROC)gl_addr[GLFRAMEBUFFERRENDERBUFFER].func) +#define glFramebufferTexture ((PFNGLFRAMEBUFFERTEXTUREPROC)gl_addr[GLFRAMEBUFFERTEXTURE].func) +#define glFramebufferTexture1D ((PFNGLFRAMEBUFFERTEXTURE1DPROC)gl_addr[GLFRAMEBUFFERTEXTURE1D].func) +#define glFramebufferTexture1DEXT ((PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)gl_addr[GLFRAMEBUFFERTEXTURE1DEXT].func) +#define glFramebufferTexture2D ((PFNGLFRAMEBUFFERTEXTURE2DPROC)gl_addr[GLFRAMEBUFFERTEXTURE2D].func) +#define glFramebufferTexture3D ((PFNGLFRAMEBUFFERTEXTURE3DPROC)gl_addr[GLFRAMEBUFFERTEXTURE3D].func) +#define glFramebufferTexture3DEXT ((PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)gl_addr[GLFRAMEBUFFERTEXTURE3DEXT].func) +#define glFramebufferTextureARB ((PFNGLFRAMEBUFFERTEXTUREARBPROC)gl_addr[GLFRAMEBUFFERTEXTUREARB].func) +#define glFramebufferTextureEXT ((PFNGLFRAMEBUFFERTEXTUREEXTPROC)gl_addr[GLFRAMEBUFFERTEXTUREEXT].func) +#define glFramebufferTextureFaceARB ((PFNGLFRAMEBUFFERTEXTUREFACEARBPROC)gl_addr[GLFRAMEBUFFERTEXTUREFACEARB].func) +#define glFramebufferTextureFaceEXT ((PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC)gl_addr[GLFRAMEBUFFERTEXTUREFACEEXT].func) +#define glFramebufferTextureLayer ((PFNGLFRAMEBUFFERTEXTURELAYERPROC)gl_addr[GLFRAMEBUFFERTEXTURELAYER].func) +#define glFramebufferTextureLayerARB ((PFNGLFRAMEBUFFERTEXTURELAYERARBPROC)gl_addr[GLFRAMEBUFFERTEXTURELAYERARB].func) +#define glFramebufferTextureLayerEXT ((PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC)gl_addr[GLFRAMEBUFFERTEXTURELAYEREXT].func) +#define glGenBuffers ((PFNGLGENBUFFERSPROC)gl_addr[GLGENBUFFERS].func) +#define glGenBuffersARB ((PFNGLGENBUFFERSARBPROC)gl_addr[GLGENBUFFERSARB].func) +#define glGenerateMipmap ((PFNGLGENERATEMIPMAPPROC)gl_addr[GLGENERATEMIPMAP].func) +#define glGenerateMipmapEXT ((PFNGLGENERATEMIPMAPEXTPROC)gl_addr[GLGENERATEMIPMAPEXT].func) +#define glGenerateMultiTexMipmapEXT ((PFNGLGENERATEMULTITEXMIPMAPEXTPROC)gl_addr[GLGENERATEMULTITEXMIPMAPEXT].func) +#define glGenerateTextureMipmapEXT ((PFNGLGENERATETEXTUREMIPMAPEXTPROC)gl_addr[GLGENERATETEXTUREMIPMAPEXT].func) +#define glGenFencesNV ((PFNGLGENFENCESNVPROC)gl_addr[GLGENFENCESNV].func) +#define glGenFramebuffers ((PFNGLGENFRAMEBUFFERSPROC)gl_addr[GLGENFRAMEBUFFERS].func) +#define glGenOcclusionQueriesNV ((PFNGLGENOCCLUSIONQUERIESNVPROC)gl_addr[GLGENOCCLUSIONQUERIESNV].func) +#define glGenProgramsARB ((PFNGLGENPROGRAMSARBPROC)gl_addr[GLGENPROGRAMSARB].func) +#define glGenProgramsNV ((PFNGLGENPROGRAMSNVPROC)gl_addr[GLGENPROGRAMSNV].func) +#define glGenQueries ((PFNGLGENQUERIESPROC)gl_addr[GLGENQUERIES].func) +#define glGenQueriesARB ((PFNGLGENQUERIESARBPROC)gl_addr[GLGENQUERIESARB].func) +#define glGenRenderbuffers ((PFNGLGENRENDERBUFFERSPROC)gl_addr[GLGENRENDERBUFFERS].func) +#define glGenSamplers ((PFNGLGENSAMPLERSPROC)gl_addr[GLGENSAMPLERS].func) +#define glGenTexturesEXT ((PFNGLGENTEXTURESEXTPROC)gl_addr[GLGENTEXTURESEXT].func) +#define glGenVertexArrays ((PFNGLGENVERTEXARRAYSPROC)gl_addr[GLGENVERTEXARRAYS].func) +#define glGetActiveAttrib ((PFNGLGETACTIVEATTRIBPROC)gl_addr[GLGETACTIVEATTRIB].func) +#define glGetActiveAttribARB ((PFNGLGETACTIVEATTRIBARBPROC)gl_addr[GLGETACTIVEATTRIBARB].func) +#define glGetActiveUniform ((PFNGLGETACTIVEUNIFORMPROC)gl_addr[GLGETACTIVEUNIFORM].func) +#define glGetActiveUniformARB ((PFNGLGETACTIVEUNIFORMARBPROC)gl_addr[GLGETACTIVEUNIFORMARB].func) +#define glGetActiveVaryingNV ((PFNGLGETACTIVEVARYINGNVPROC)gl_addr[GLGETACTIVEVARYINGNV].func) +#define glGetAttachedObjectsARB ((PFNGLGETATTACHEDOBJECTSARBPROC)gl_addr[GLGETATTACHEDOBJECTSARB].func) +#define glGetAttachedShaders ((PFNGLGETATTACHEDSHADERSPROC)gl_addr[GLGETATTACHEDSHADERS].func) +#define glGetAttribLocation ((PFNGLGETATTRIBLOCATIONPROC)gl_addr[GLGETATTRIBLOCATION].func) +#define glGetAttribLocationARB ((PFNGLGETATTRIBLOCATIONARBPROC)gl_addr[GLGETATTRIBLOCATIONARB].func) +#define glGetBooleani_v ((PFNGLGETBOOLEANI_VPROC)gl_addr[GLGETBOOLEANI_V].func) +#define glGetBooleanIndexedvEXT ((PFNGLGETBOOLEANINDEXEDVEXTPROC)gl_addr[GLGETBOOLEANINDEXEDVEXT].func) +#define glGetBufferParameteriv ((PFNGLGETBUFFERPARAMETERIVPROC)gl_addr[GLGETBUFFERPARAMETERIV].func) +#define glGetBufferParameterivARB ((PFNGLGETBUFFERPARAMETERIVARBPROC)gl_addr[GLGETBUFFERPARAMETERIVARB].func) +#define glGetBufferPointerv ((PFNGLGETBUFFERPOINTERVPROC)gl_addr[GLGETBUFFERPOINTERV].func) +#define glGetBufferPointervARB ((PFNGLGETBUFFERPOINTERVARBPROC)gl_addr[GLGETBUFFERPOINTERVARB].func) +#define glGetBufferSubData ((PFNGLGETBUFFERSUBDATAPROC)gl_addr[GLGETBUFFERSUBDATA].func) +#define glGetBufferSubDataARB ((PFNGLGETBUFFERSUBDATAARBPROC)gl_addr[GLGETBUFFERSUBDATAARB].func) +#define glGetColorTable ((PFNGLGETCOLORTABLEPROC)gl_addr[GLGETCOLORTABLE].func) +#define glGetColorTableEXT ((PFNGLGETCOLORTABLEEXTPROC)gl_addr[GLGETCOLORTABLEEXT].func) +#define glGetColorTableParameterfv ((PFNGLGETCOLORTABLEPARAMETERFVPROC)gl_addr[GLGETCOLORTABLEPARAMETERFV].func) +#define glGetColorTableParameterfvEXT ((PFNGLGETCOLORTABLEPARAMETERFVEXTPROC)gl_addr[GLGETCOLORTABLEPARAMETERFVEXT].func) +#define glGetColorTableParameteriv ((PFNGLGETCOLORTABLEPARAMETERIVPROC)gl_addr[GLGETCOLORTABLEPARAMETERIV].func) +#define glGetColorTableParameterivEXT ((PFNGLGETCOLORTABLEPARAMETERIVEXTPROC)gl_addr[GLGETCOLORTABLEPARAMETERIVEXT].func) +#define glGetCombinerInputParameterfvNV ((PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC)gl_addr[GLGETCOMBINERINPUTPARAMETERFVNV].func) +#define glGetCombinerInputParameterivNV ((PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC)gl_addr[GLGETCOMBINERINPUTPARAMETERIVNV].func) +#define glGetCombinerOutputParameterfvNV ((PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC)gl_addr[GLGETCOMBINEROUTPUTPARAMETERFVNV].func) +#define glGetCombinerOutputParameterivNV ((PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC)gl_addr[GLGETCOMBINEROUTPUTPARAMETERIVNV].func) +#define glGetCombinerStageParameterfvNV ((PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC)gl_addr[GLGETCOMBINERSTAGEPARAMETERFVNV].func) +#define glGetCompressedMultiTexImageEXT ((PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC)gl_addr[GLGETCOMPRESSEDMULTITEXIMAGEEXT].func) +#define glGetCompressedTexImage ((PFNGLGETCOMPRESSEDTEXIMAGEPROC)gl_addr[GLGETCOMPRESSEDTEXIMAGE].func) +#define glGetCompressedTexImageARB ((PFNGLGETCOMPRESSEDTEXIMAGEARBPROC)gl_addr[GLGETCOMPRESSEDTEXIMAGEARB].func) +#define glGetCompressedTextureImageEXT ((PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC)gl_addr[GLGETCOMPRESSEDTEXTUREIMAGEEXT].func) +#define glGetConvolutionFilter ((PFNGLGETCONVOLUTIONFILTERPROC)gl_addr[GLGETCONVOLUTIONFILTER].func) +#define glGetConvolutionParameterfv ((PFNGLGETCONVOLUTIONPARAMETERFVPROC)gl_addr[GLGETCONVOLUTIONPARAMETERFV].func) +#define glGetConvolutionParameteriv ((PFNGLGETCONVOLUTIONPARAMETERIVPROC)gl_addr[GLGETCONVOLUTIONPARAMETERIV].func) +#define glGetDoubleIndexedvEXT ((PFNGLGETDOUBLEINDEXEDVEXTPROC)gl_addr[GLGETDOUBLEINDEXEDVEXT].func) +#define glGetFenceivNV ((PFNGLGETFENCEIVNVPROC)gl_addr[GLGETFENCEIVNV].func) +#define glGetFinalCombinerInputParameterfvNV ((PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC)gl_addr[GLGETFINALCOMBINERINPUTPARAMETERFVNV].func) +#define glGetFinalCombinerInputParameterivNV ((PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC)gl_addr[GLGETFINALCOMBINERINPUTPARAMETERIVNV].func) +#define glGetFloatIndexedvEXT ((PFNGLGETFLOATINDEXEDVEXTPROC)gl_addr[GLGETFLOATINDEXEDVEXT].func) +#define glGetFragDataLocation ((PFNGLGETFRAGDATALOCATIONPROC)gl_addr[GLGETFRAGDATALOCATION].func) +#define glGetFragDataLocationEXT ((PFNGLGETFRAGDATALOCATIONEXTPROC)gl_addr[GLGETFRAGDATALOCATIONEXT].func) +#define glGetFramebufferAttachmentParameteriv ((PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)gl_addr[GLGETFRAMEBUFFERATTACHMENTPARAMETERIV].func) +#define glGetFramebufferAttachmentParameterivEXT ((PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)gl_addr[GLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXT].func) +#define glGetFramebufferParameterivEXT ((PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC)gl_addr[GLGETFRAMEBUFFERPARAMETERIVEXT].func) +#define glGetHandleARB ((PFNGLGETHANDLEARBPROC)gl_addr[GLGETHANDLEARB].func) +#define glGetHistogram ((PFNGLGETHISTOGRAMPROC)gl_addr[GLGETHISTOGRAM].func) +#define glGetHistogramParameterfv ((PFNGLGETHISTOGRAMPARAMETERFVPROC)gl_addr[GLGETHISTOGRAMPARAMETERFV].func) +#define glGetHistogramParameteriv ((PFNGLGETHISTOGRAMPARAMETERIVPROC)gl_addr[GLGETHISTOGRAMPARAMETERIV].func) +#define glGetInfoLogARB ((PFNGLGETINFOLOGARBPROC)gl_addr[GLGETINFOLOGARB].func) +#define glGetIntegeri_v ((PFNGLGETINTEGERI_VPROC)gl_addr[GLGETINTEGERI_V].func) +#define glGetIntegerIndexedvEXT ((PFNGLGETINTEGERINDEXEDVEXTPROC)gl_addr[GLGETINTEGERINDEXEDVEXT].func) +#define glGetMinmax ((PFNGLGETMINMAXPROC)gl_addr[GLGETMINMAX].func) +#define glGetMinmaxParameterfv ((PFNGLGETMINMAXPARAMETERFVPROC)gl_addr[GLGETMINMAXPARAMETERFV].func) +#define glGetMinmaxParameteriv ((PFNGLGETMINMAXPARAMETERIVPROC)gl_addr[GLGETMINMAXPARAMETERIV].func) +#define glGetMultisamplefvNV ((PFNGLGETMULTISAMPLEFVNVPROC)gl_addr[GLGETMULTISAMPLEFVNV].func) +#define glGetMultiTexEnvfvEXT ((PFNGLGETMULTITEXENVFVEXTPROC)gl_addr[GLGETMULTITEXENVFVEXT].func) +#define glGetMultiTexEnvivEXT ((PFNGLGETMULTITEXENVIVEXTPROC)gl_addr[GLGETMULTITEXENVIVEXT].func) +#define glGetMultiTexGendvEXT ((PFNGLGETMULTITEXGENDVEXTPROC)gl_addr[GLGETMULTITEXGENDVEXT].func) +#define glGetMultiTexGenfvEXT ((PFNGLGETMULTITEXGENFVEXTPROC)gl_addr[GLGETMULTITEXGENFVEXT].func) +#define glGetMultiTexGenivEXT ((PFNGLGETMULTITEXGENIVEXTPROC)gl_addr[GLGETMULTITEXGENIVEXT].func) +#define glGetMultiTexImageEXT ((PFNGLGETMULTITEXIMAGEEXTPROC)gl_addr[GLGETMULTITEXIMAGEEXT].func) +#define glGetMultiTexLevelParameterfvEXT ((PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC)gl_addr[GLGETMULTITEXLEVELPARAMETERFVEXT].func) +#define glGetMultiTexLevelParameterivEXT ((PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC)gl_addr[GLGETMULTITEXLEVELPARAMETERIVEXT].func) +#define glGetMultiTexParameterfvEXT ((PFNGLGETMULTITEXPARAMETERFVEXTPROC)gl_addr[GLGETMULTITEXPARAMETERFVEXT].func) +#define glGetMultiTexParameterIivEXT ((PFNGLGETMULTITEXPARAMETERIIVEXTPROC)gl_addr[GLGETMULTITEXPARAMETERIIVEXT].func) +#define glGetMultiTexParameterIuivEXT ((PFNGLGETMULTITEXPARAMETERIUIVEXTPROC)gl_addr[GLGETMULTITEXPARAMETERIUIVEXT].func) +#define glGetMultiTexParameterivEXT ((PFNGLGETMULTITEXPARAMETERIVEXTPROC)gl_addr[GLGETMULTITEXPARAMETERIVEXT].func) +#define glGetNamedBufferParameterivEXT ((PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC)gl_addr[GLGETNAMEDBUFFERPARAMETERIVEXT].func) +#define glGetNamedBufferPointervEXT ((PFNGLGETNAMEDBUFFERPOINTERVEXTPROC)gl_addr[GLGETNAMEDBUFFERPOINTERVEXT].func) +#define glGetNamedBufferSubDataEXT ((PFNGLGETNAMEDBUFFERSUBDATAEXTPROC)gl_addr[GLGETNAMEDBUFFERSUBDATAEXT].func) +#define glGetNamedFramebufferAttachmentParameterivEXT ((PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)gl_addr[GLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXT].func) +#define glGetNamedProgramivEXT ((PFNGLGETNAMEDPROGRAMIVEXTPROC)gl_addr[GLGETNAMEDPROGRAMIVEXT].func) +#define glGetNamedProgramLocalParameterdvEXT ((PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC)gl_addr[GLGETNAMEDPROGRAMLOCALPARAMETERDVEXT].func) +#define glGetNamedProgramLocalParameterfvEXT ((PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC)gl_addr[GLGETNAMEDPROGRAMLOCALPARAMETERFVEXT].func) +#define glGetNamedProgramLocalParameterIivEXT ((PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC)gl_addr[GLGETNAMEDPROGRAMLOCALPARAMETERIIVEXT].func) +#define glGetNamedProgramLocalParameterIuivEXT ((PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC)gl_addr[GLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXT].func) +#define glGetNamedProgramStringEXT ((PFNGLGETNAMEDPROGRAMSTRINGEXTPROC)gl_addr[GLGETNAMEDPROGRAMSTRINGEXT].func) +#define glGetNamedRenderbufferParameterivEXT ((PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC)gl_addr[GLGETNAMEDRENDERBUFFERPARAMETERIVEXT].func) +#define glGetObjectParameterfvARB ((PFNGLGETOBJECTPARAMETERFVARBPROC)gl_addr[GLGETOBJECTPARAMETERFVARB].func) +#define glGetObjectParameterivARB ((PFNGLGETOBJECTPARAMETERIVARBPROC)gl_addr[GLGETOBJECTPARAMETERIVARB].func) +#define glGetOcclusionQueryivNV ((PFNGLGETOCCLUSIONQUERYIVNVPROC)gl_addr[GLGETOCCLUSIONQUERYIVNV].func) +#define glGetOcclusionQueryuivNV ((PFNGLGETOCCLUSIONQUERYUIVNVPROC)gl_addr[GLGETOCCLUSIONQUERYUIVNV].func) +#define glGetPointerIndexedvEXT ((PFNGLGETPOINTERINDEXEDVEXTPROC)gl_addr[GLGETPOINTERINDEXEDVEXT].func) +#define glGetPointervEXT ((PFNGLGETPOINTERVEXTPROC)gl_addr[GLGETPOINTERVEXT].func) +#define glGetProgramEnvParameterdvARB ((PFNGLGETPROGRAMENVPARAMETERDVARBPROC)gl_addr[GLGETPROGRAMENVPARAMETERDVARB].func) +#define glGetProgramEnvParameterIivNV ((PFNGLGETPROGRAMENVPARAMETERIIVNVPROC)gl_addr[GLGETPROGRAMENVPARAMETERIIVNV].func) +#define glGetProgramEnvParameterIuivNV ((PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC)gl_addr[GLGETPROGRAMENVPARAMETERIUIVNV].func) +#define glGetProgramInfoLog ((PFNGLGETPROGRAMINFOLOGPROC)gl_addr[GLGETPROGRAMINFOLOG].func) +#define glGetProgramiv ((PFNGLGETPROGRAMIVPROC)gl_addr[GLGETPROGRAMIV].func) +#define glGetProgramivNV ((PFNGLGETPROGRAMIVNVPROC)gl_addr[GLGETPROGRAMIVNV].func) +#define glGetProgramLocalParameterdvARB ((PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC)gl_addr[GLGETPROGRAMLOCALPARAMETERDVARB].func) +#define glGetProgramLocalParameterfvARB ((PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC)gl_addr[GLGETPROGRAMLOCALPARAMETERFVARB].func) +#define glGetProgramLocalParameterIivNV ((PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC)gl_addr[GLGETPROGRAMLOCALPARAMETERIIVNV].func) +#define glGetProgramLocalParameterIuivNV ((PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC)gl_addr[GLGETPROGRAMLOCALPARAMETERIUIVNV].func) +#define glGetProgramNamedParameterdvNV ((PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC)gl_addr[GLGETPROGRAMNAMEDPARAMETERDVNV].func) +#define glGetProgramNamedParameterfvNV ((PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC)gl_addr[GLGETPROGRAMNAMEDPARAMETERFVNV].func) +#define glGetProgramParameterdvNV ((PFNGLGETPROGRAMPARAMETERDVNVPROC)gl_addr[GLGETPROGRAMPARAMETERDVNV].func) +#define glGetProgramParameterfvNV ((PFNGLGETPROGRAMPARAMETERFVNVPROC)gl_addr[GLGETPROGRAMPARAMETERFVNV].func) +#define glGetProgramStringARB ((PFNGLGETPROGRAMSTRINGARBPROC)gl_addr[GLGETPROGRAMSTRINGARB].func) +#define glGetProgramStringNV ((PFNGLGETPROGRAMSTRINGNVPROC)gl_addr[GLGETPROGRAMSTRINGNV].func) +#define glGetQueryiv ((PFNGLGETQUERYIVPROC)gl_addr[GLGETQUERYIV].func) +#define glGetQueryivARB ((PFNGLGETQUERYIVARBPROC)gl_addr[GLGETQUERYIVARB].func) +#define glGetQueryObjecti64vEXT ((PFNGLGETQUERYOBJECTI64VEXTPROC)gl_addr[GLGETQUERYOBJECTI64VEXT].func) +#define glGetQueryObjectiv ((PFNGLGETQUERYOBJECTIVPROC)gl_addr[GLGETQUERYOBJECTIV].func) +#define glGetQueryObjectivARB ((PFNGLGETQUERYOBJECTIVARBPROC)gl_addr[GLGETQUERYOBJECTIVARB].func) +#define glGetQueryObjectui64v ((PFNGLGETQUERYOBJECTUI64VPROC)gl_addr[GLGETQUERYOBJECTUI64V].func) +#define glGetQueryObjectui64vEXT ((PFNGLGETQUERYOBJECTUI64VEXTPROC)gl_addr[GLGETQUERYOBJECTUI64VEXT].func) +#define glGetQueryObjectuiv ((PFNGLGETQUERYOBJECTUIVPROC)gl_addr[GLGETQUERYOBJECTUIV].func) +#define glGetQueryObjectuivARB ((PFNGLGETQUERYOBJECTUIVARBPROC)gl_addr[GLGETQUERYOBJECTUIVARB].func) +#define glGetRenderbufferParameteriv ((PFNGLGETRENDERBUFFERPARAMETERIVPROC)gl_addr[GLGETRENDERBUFFERPARAMETERIV].func) +#define glGetRenderbufferParameterivEXT ((PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)gl_addr[GLGETRENDERBUFFERPARAMETERIVEXT].func) +#define glGetSeparableFilter ((PFNGLGETSEPARABLEFILTERPROC)gl_addr[GLGETSEPARABLEFILTER].func) +#define glGetShaderInfoLog ((PFNGLGETSHADERINFOLOGPROC)gl_addr[GLGETSHADERINFOLOG].func) +#define glGetShaderiv ((PFNGLGETSHADERIVPROC)gl_addr[GLGETSHADERIV].func) +#define glGetShaderSource ((PFNGLGETSHADERSOURCEPROC)gl_addr[GLGETSHADERSOURCE].func) +#define glGetShaderSourceARB ((PFNGLGETSHADERSOURCEARBPROC)gl_addr[GLGETSHADERSOURCEARB].func) +#define glGetStringi ((PFNGLGETSTRINGIPROC)gl_addr[GLGETSTRINGI].func) +#define glGetTexParameterIiv ((PFNGLGETTEXPARAMETERIIVPROC)gl_addr[GLGETTEXPARAMETERIIV].func) +#define glGetTexParameterIivEXT ((PFNGLGETTEXPARAMETERIIVEXTPROC)gl_addr[GLGETTEXPARAMETERIIVEXT].func) +#define glGetTexParameterIuiv ((PFNGLGETTEXPARAMETERIUIVPROC)gl_addr[GLGETTEXPARAMETERIUIV].func) +#define glGetTexParameterIuivEXT ((PFNGLGETTEXPARAMETERIUIVEXTPROC)gl_addr[GLGETTEXPARAMETERIUIVEXT].func) +#define glGetTextureLevelParameterfvEXT ((PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC)gl_addr[GLGETTEXTURELEVELPARAMETERFVEXT].func) +#define glGetTextureLevelParameterivEXT ((PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC)gl_addr[GLGETTEXTURELEVELPARAMETERIVEXT].func) +#define glGetTextureParameterfvEXT ((PFNGLGETTEXTUREPARAMETERFVEXTPROC)gl_addr[GLGETTEXTUREPARAMETERFVEXT].func) +#define glGetTextureParameterIivEXT ((PFNGLGETTEXTUREPARAMETERIIVEXTPROC)gl_addr[GLGETTEXTUREPARAMETERIIVEXT].func) +#define glGetTextureParameterIuivEXT ((PFNGLGETTEXTUREPARAMETERIUIVEXTPROC)gl_addr[GLGETTEXTUREPARAMETERIUIVEXT].func) +#define glGetTextureParameterivEXT ((PFNGLGETTEXTUREPARAMETERIVEXTPROC)gl_addr[GLGETTEXTUREPARAMETERIVEXT].func) +#define glGetTrackMatrixivNV ((PFNGLGETTRACKMATRIXIVNVPROC)gl_addr[GLGETTRACKMATRIXIVNV].func) +#define glGetTransformFeedbackVarying ((PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)gl_addr[GLGETTRANSFORMFEEDBACKVARYING].func) +#define glGetTransformFeedbackVaryingNV ((PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC)gl_addr[GLGETTRANSFORMFEEDBACKVARYINGNV].func) +#define glGetUniformBufferSizeEXT ((PFNGLGETUNIFORMBUFFERSIZEEXTPROC)gl_addr[GLGETUNIFORMBUFFERSIZEEXT].func) +#define glGetUniformfv ((PFNGLGETUNIFORMFVPROC)gl_addr[GLGETUNIFORMFV].func) +#define glGetUniformfvARB ((PFNGLGETUNIFORMFVARBPROC)gl_addr[GLGETUNIFORMFVARB].func) +#define glGetUniformiv ((PFNGLGETUNIFORMIVPROC)gl_addr[GLGETUNIFORMIV].func) +#define glGetUniformivARB ((PFNGLGETUNIFORMIVARBPROC)gl_addr[GLGETUNIFORMIVARB].func) +#define glGetUniformLocation ((PFNGLGETUNIFORMLOCATIONPROC)gl_addr[GLGETUNIFORMLOCATION].func) +#define glGetUniformLocationARB ((PFNGLGETUNIFORMLOCATIONARBPROC)gl_addr[GLGETUNIFORMLOCATIONARB].func) +#define glGetUniformOffsetEXT ((PFNGLGETUNIFORMOFFSETEXTPROC)gl_addr[GLGETUNIFORMOFFSETEXT].func) +#define glGetUniformuiv ((PFNGLGETUNIFORMUIVPROC)gl_addr[GLGETUNIFORMUIV].func) +#define glGetUniformuivEXT ((PFNGLGETUNIFORMUIVEXTPROC)gl_addr[GLGETUNIFORMUIVEXT].func) +#define glGetVaryingLocationNV ((PFNGLGETVARYINGLOCATIONNVPROC)gl_addr[GLGETVARYINGLOCATIONNV].func) +#define glGetVertexAttribdv ((PFNGLGETVERTEXATTRIBDVPROC)gl_addr[GLGETVERTEXATTRIBDV].func) +#define glGetVertexAttribdvARB ((PFNGLGETVERTEXATTRIBDVARBPROC)gl_addr[GLGETVERTEXATTRIBDVARB].func) +#define glGetVertexAttribdvNV ((PFNGLGETVERTEXATTRIBDVNVPROC)gl_addr[GLGETVERTEXATTRIBDVNV].func) +#define glGetVertexAttribfv ((PFNGLGETVERTEXATTRIBFVPROC)gl_addr[GLGETVERTEXATTRIBFV].func) +#define glGetVertexAttribfvARB ((PFNGLGETVERTEXATTRIBFVARBPROC)gl_addr[GLGETVERTEXATTRIBFVARB].func) +#define glGetVertexAttribfvNV ((PFNGLGETVERTEXATTRIBFVNVPROC)gl_addr[GLGETVERTEXATTRIBFVNV].func) +#define glGetVertexAttribIiv ((PFNGLGETVERTEXATTRIBIIVPROC)gl_addr[GLGETVERTEXATTRIBIIV].func) +#define glGetVertexAttribIivEXT ((PFNGLGETVERTEXATTRIBIIVEXTPROC)gl_addr[GLGETVERTEXATTRIBIIVEXT].func) +#define glGetVertexAttribIuiv ((PFNGLGETVERTEXATTRIBIUIVPROC)gl_addr[GLGETVERTEXATTRIBIUIV].func) +#define glGetVertexAttribIuivEXT ((PFNGLGETVERTEXATTRIBIUIVEXTPROC)gl_addr[GLGETVERTEXATTRIBIUIVEXT].func) +#define glGetVertexAttribiv ((PFNGLGETVERTEXATTRIBIVPROC)gl_addr[GLGETVERTEXATTRIBIV].func) +#define glGetVertexAttribivARB ((PFNGLGETVERTEXATTRIBIVARBPROC)gl_addr[GLGETVERTEXATTRIBIVARB].func) +#define glGetVertexAttribivNV ((PFNGLGETVERTEXATTRIBIVNVPROC)gl_addr[GLGETVERTEXATTRIBIVNV].func) +#define glGetVertexAttribPointerv ((PFNGLGETVERTEXATTRIBPOINTERVPROC)gl_addr[GLGETVERTEXATTRIBPOINTERV].func) +#define glGetVertexAttribPointervARB ((PFNGLGETVERTEXATTRIBPOINTERVARBPROC)gl_addr[GLGETVERTEXATTRIBPOINTERVARB].func) +#define glGetVertexAttribPointervNV ((PFNGLGETVERTEXATTRIBPOINTERVNVPROC)gl_addr[GLGETVERTEXATTRIBPOINTERVNV].func) +#define glGetVideoi64vNV ((PFNGLGETVIDEOI64VNVPROC)gl_addr[GLGETVIDEOI64VNV].func) +#define glGetVideoivNV ((PFNGLGETVIDEOIVNVPROC)gl_addr[GLGETVIDEOIVNV].func) +#define glGetVideoui64vNV ((PFNGLGETVIDEOUI64VNVPROC)gl_addr[GLGETVIDEOUI64VNV].func) +#define glGetVideouivNV ((PFNGLGETVIDEOUIVNVPROC)gl_addr[GLGETVIDEOUIVNV].func) +#define glHistogram ((PFNGLHISTOGRAMPROC)gl_addr[GLHISTOGRAM].func) +#define glIndexPointerEXT ((PFNGLINDEXPOINTEREXTPROC)gl_addr[GLINDEXPOINTEREXT].func) +#define glIsBuffer ((PFNGLISBUFFERPROC)gl_addr[GLISBUFFER].func) +#define glIsEnabledi ((PFNGLISENABLEDIPROC)gl_addr[GLISENABLEDI].func) +#define glIsEnabledIndexedEXT ((PFNGLISENABLEDINDEXEDEXTPROC)gl_addr[GLISENABLEDINDEXEDEXT].func) +#define glIsFenceNV ((PFNGLISFENCENVPROC)gl_addr[GLISFENCENV].func) +#define glIsFramebuffer ((PFNGLISFRAMEBUFFERPROC)gl_addr[GLISFRAMEBUFFER].func) +#define glIsFramebufferEXT ((PFNGLISFRAMEBUFFEREXTPROC)gl_addr[GLISFRAMEBUFFEREXT].func) +#define glIsOcclusionQueryNV ((PFNGLISOCCLUSIONQUERYNVPROC)gl_addr[GLISOCCLUSIONQUERYNV].func) +#define glIsProgram ((PFNGLISPROGRAMPROC)gl_addr[GLISPROGRAM].func) +#define glIsProgramARB ((PFNGLISPROGRAMARBPROC)gl_addr[GLISPROGRAMARB].func) +#define glIsProgramNV ((PFNGLISPROGRAMNVPROC)gl_addr[GLISPROGRAMNV].func) +#define glIsQuery ((PFNGLISQUERYPROC)gl_addr[GLISQUERY].func) +#define glIsQueryARB ((PFNGLISQUERYARBPROC)gl_addr[GLISQUERYARB].func) +#define glIsRenderbuffer ((PFNGLISRENDERBUFFERPROC)gl_addr[GLISRENDERBUFFER].func) +#define glIsRenderbufferEXT ((PFNGLISRENDERBUFFEREXTPROC)gl_addr[GLISRENDERBUFFEREXT].func) +#define glIsShader ((PFNGLISSHADERPROC)gl_addr[GLISSHADER].func) +#define glIsTextureEXT ((PFNGLISTEXTUREEXTPROC)gl_addr[GLISTEXTUREEXT].func) +#define glIsVertexArray ((PFNGLISVERTEXARRAYPROC)gl_addr[GLISVERTEXARRAY].func) +#define glLinkProgram ((PFNGLLINKPROGRAMPROC)gl_addr[GLLINKPROGRAM].func) +#define glLinkProgramARB ((PFNGLLINKPROGRAMARBPROC)gl_addr[GLLINKPROGRAMARB].func) +#define glLoadProgramNV ((PFNGLLOADPROGRAMNVPROC)gl_addr[GLLOADPROGRAMNV].func) +#define glLoadTransposeMatrixd ((PFNGLLOADTRANSPOSEMATRIXDPROC)gl_addr[GLLOADTRANSPOSEMATRIXD].func) +#define glLoadTransposeMatrixdARB ((PFNGLLOADTRANSPOSEMATRIXDARBPROC)gl_addr[GLLOADTRANSPOSEMATRIXDARB].func) +#define glLoadTransposeMatrixfARB ((PFNGLLOADTRANSPOSEMATRIXFARBPROC)gl_addr[GLLOADTRANSPOSEMATRIXFARB].func) +#define glLockArraysEXT ((PFNGLLOCKARRAYSEXTPROC)gl_addr[GLLOCKARRAYSEXT].func) +#define glMapBuffer ((PFNGLMAPBUFFERPROC)gl_addr[GLMAPBUFFER].func) +#define glMapBufferARB ((PFNGLMAPBUFFERARBPROC)gl_addr[GLMAPBUFFERARB].func) +#define glMapBufferRange ((PFNGLMAPBUFFERRANGEPROC)gl_addr[GLMAPBUFFERRANGE].func) +#define glMatrixFrustumEXT ((PFNGLMATRIXFRUSTUMEXTPROC)gl_addr[GLMATRIXFRUSTUMEXT].func) +#define glMatrixLoaddEXT ((PFNGLMATRIXLOADDEXTPROC)gl_addr[GLMATRIXLOADDEXT].func) +#define glMatrixLoadfEXT ((PFNGLMATRIXLOADFEXTPROC)gl_addr[GLMATRIXLOADFEXT].func) +#define glMatrixLoadIdentityEXT ((PFNGLMATRIXLOADIDENTITYEXTPROC)gl_addr[GLMATRIXLOADIDENTITYEXT].func) +#define glMatrixLoadTransposedEXT ((PFNGLMATRIXLOADTRANSPOSEDEXTPROC)gl_addr[GLMATRIXLOADTRANSPOSEDEXT].func) +#define glMatrixLoadTransposefEXT ((PFNGLMATRIXLOADTRANSPOSEFEXTPROC)gl_addr[GLMATRIXLOADTRANSPOSEFEXT].func) +#define glMatrixMultdEXT ((PFNGLMATRIXMULTDEXTPROC)gl_addr[GLMATRIXMULTDEXT].func) +#define glMatrixMultfEXT ((PFNGLMATRIXMULTFEXTPROC)gl_addr[GLMATRIXMULTFEXT].func) +#define glMatrixMultTransposedEXT ((PFNGLMATRIXMULTTRANSPOSEDEXTPROC)gl_addr[GLMATRIXMULTTRANSPOSEDEXT].func) +#define glMatrixMultTransposefEXT ((PFNGLMATRIXMULTTRANSPOSEFEXTPROC)gl_addr[GLMATRIXMULTTRANSPOSEFEXT].func) +#define glMatrixOrthoEXT ((PFNGLMATRIXORTHOEXTPROC)gl_addr[GLMATRIXORTHOEXT].func) +#define glMatrixPopEXT ((PFNGLMATRIXPOPEXTPROC)gl_addr[GLMATRIXPOPEXT].func) +#define glMatrixPushEXT ((PFNGLMATRIXPUSHEXTPROC)gl_addr[GLMATRIXPUSHEXT].func) +#define glMatrixRotatedEXT ((PFNGLMATRIXROTATEDEXTPROC)gl_addr[GLMATRIXROTATEDEXT].func) +#define glMatrixRotatefEXT ((PFNGLMATRIXROTATEFEXTPROC)gl_addr[GLMATRIXROTATEFEXT].func) +#define glMatrixScaledEXT ((PFNGLMATRIXSCALEDEXTPROC)gl_addr[GLMATRIXSCALEDEXT].func) +#define glMatrixScalefEXT ((PFNGLMATRIXSCALEFEXTPROC)gl_addr[GLMATRIXSCALEFEXT].func) +#define glMatrixTranslatedEXT ((PFNGLMATRIXTRANSLATEDEXTPROC)gl_addr[GLMATRIXTRANSLATEDEXT].func) +#define glMatrixTranslatefEXT ((PFNGLMATRIXTRANSLATEFEXTPROC)gl_addr[GLMATRIXTRANSLATEFEXT].func) +#define glMinmax ((PFNGLMINMAXPROC)gl_addr[GLMINMAX].func) +#define glMultiDrawArrays ((PFNGLMULTIDRAWARRAYSPROC)gl_addr[GLMULTIDRAWARRAYS].func) +#define glMultiDrawArraysEXT ((PFNGLMULTIDRAWARRAYSEXTPROC)gl_addr[GLMULTIDRAWARRAYSEXT].func) +#define glMultiDrawElements ((PFNGLMULTIDRAWELEMENTSPROC)gl_addr[GLMULTIDRAWELEMENTS].func) +#define glMultiDrawElementsEXT ((PFNGLMULTIDRAWELEMENTSEXTPROC)gl_addr[GLMULTIDRAWELEMENTSEXT].func) +#define glMultiTexBufferEXT ((PFNGLMULTITEXBUFFEREXTPROC)gl_addr[GLMULTITEXBUFFEREXT].func) +#define glMultiTexCoord1d ((PFNGLMULTITEXCOORD1DPROC)gl_addr[GLMULTITEXCOORD1D].func) +#define glMultiTexCoord1dARB ((PFNGLMULTITEXCOORD1DARBPROC)gl_addr[GLMULTITEXCOORD1DARB].func) +#define glMultiTexCoord1dv ((PFNGLMULTITEXCOORD1DVPROC)gl_addr[GLMULTITEXCOORD1DV].func) +#define glMultiTexCoord1dvARB ((PFNGLMULTITEXCOORD1DVARBPROC)gl_addr[GLMULTITEXCOORD1DVARB].func) +#define glMultiTexCoord1f ((PFNGLMULTITEXCOORD1FPROC)gl_addr[GLMULTITEXCOORD1F].func) +#define glMultiTexCoord1fARB ((PFNGLMULTITEXCOORD1FARBPROC)gl_addr[GLMULTITEXCOORD1FARB].func) +#define glMultiTexCoord1fv ((PFNGLMULTITEXCOORD1FVPROC)gl_addr[GLMULTITEXCOORD1FV].func) +#define glMultiTexCoord1fvARB ((PFNGLMULTITEXCOORD1FVARBPROC)gl_addr[GLMULTITEXCOORD1FVARB].func) +#define glMultiTexCoord1hNV ((PFNGLMULTITEXCOORD1HNVPROC)gl_addr[GLMULTITEXCOORD1HNV].func) +#define glMultiTexCoord1hvNV ((PFNGLMULTITEXCOORD1HVNVPROC)gl_addr[GLMULTITEXCOORD1HVNV].func) +#define glMultiTexCoord1i ((PFNGLMULTITEXCOORD1IPROC)gl_addr[GLMULTITEXCOORD1I].func) +#define glMultiTexCoord1iARB ((PFNGLMULTITEXCOORD1IARBPROC)gl_addr[GLMULTITEXCOORD1IARB].func) +#define glMultiTexCoord1iv ((PFNGLMULTITEXCOORD1IVPROC)gl_addr[GLMULTITEXCOORD1IV].func) +#define glMultiTexCoord1ivARB ((PFNGLMULTITEXCOORD1IVARBPROC)gl_addr[GLMULTITEXCOORD1IVARB].func) +#define glMultiTexCoord1s ((PFNGLMULTITEXCOORD1SPROC)gl_addr[GLMULTITEXCOORD1S].func) +#define glMultiTexCoord1sARB ((PFNGLMULTITEXCOORD1SARBPROC)gl_addr[GLMULTITEXCOORD1SARB].func) +#define glMultiTexCoord1sv ((PFNGLMULTITEXCOORD1SVPROC)gl_addr[GLMULTITEXCOORD1SV].func) +#define glMultiTexCoord1svARB ((PFNGLMULTITEXCOORD1SVARBPROC)gl_addr[GLMULTITEXCOORD1SVARB].func) +#define glMultiTexCoord2d ((PFNGLMULTITEXCOORD2DPROC)gl_addr[GLMULTITEXCOORD2D].func) +#define glMultiTexCoord2dARB ((PFNGLMULTITEXCOORD2DARBPROC)gl_addr[GLMULTITEXCOORD2DARB].func) +#define glMultiTexCoord2dv ((PFNGLMULTITEXCOORD2DVPROC)gl_addr[GLMULTITEXCOORD2DV].func) +#define glMultiTexCoord2dvARB ((PFNGLMULTITEXCOORD2DVARBPROC)gl_addr[GLMULTITEXCOORD2DVARB].func) +#define glMultiTexCoord2fARB ((PFNGLMULTITEXCOORD2FARBPROC)gl_addr[GLMULTITEXCOORD2FARB].func) +#define glMultiTexCoord2fvARB ((PFNGLMULTITEXCOORD2FVARBPROC)gl_addr[GLMULTITEXCOORD2FVARB].func) +#define glMultiTexCoord2hNV ((PFNGLMULTITEXCOORD2HNVPROC)gl_addr[GLMULTITEXCOORD2HNV].func) +#define glMultiTexCoord2hvNV ((PFNGLMULTITEXCOORD2HVNVPROC)gl_addr[GLMULTITEXCOORD2HVNV].func) +#define glMultiTexCoord2i ((PFNGLMULTITEXCOORD2IPROC)gl_addr[GLMULTITEXCOORD2I].func) +#define glMultiTexCoord2iARB ((PFNGLMULTITEXCOORD2IARBPROC)gl_addr[GLMULTITEXCOORD2IARB].func) +#define glMultiTexCoord2iv ((PFNGLMULTITEXCOORD2IVPROC)gl_addr[GLMULTITEXCOORD2IV].func) +#define glMultiTexCoord2ivARB ((PFNGLMULTITEXCOORD2IVARBPROC)gl_addr[GLMULTITEXCOORD2IVARB].func) +#define glMultiTexCoord2s ((PFNGLMULTITEXCOORD2SPROC)gl_addr[GLMULTITEXCOORD2S].func) +#define glMultiTexCoord2sARB ((PFNGLMULTITEXCOORD2SARBPROC)gl_addr[GLMULTITEXCOORD2SARB].func) +#define glMultiTexCoord2sv ((PFNGLMULTITEXCOORD2SVPROC)gl_addr[GLMULTITEXCOORD2SV].func) +#define glMultiTexCoord2svARB ((PFNGLMULTITEXCOORD2SVARBPROC)gl_addr[GLMULTITEXCOORD2SVARB].func) +#define glMultiTexCoord3d ((PFNGLMULTITEXCOORD3DPROC)gl_addr[GLMULTITEXCOORD3D].func) +#define glMultiTexCoord3dARB ((PFNGLMULTITEXCOORD3DARBPROC)gl_addr[GLMULTITEXCOORD3DARB].func) +#define glMultiTexCoord3dv ((PFNGLMULTITEXCOORD3DVPROC)gl_addr[GLMULTITEXCOORD3DV].func) +#define glMultiTexCoord3dvARB ((PFNGLMULTITEXCOORD3DVARBPROC)gl_addr[GLMULTITEXCOORD3DVARB].func) +#define glMultiTexCoord3f ((PFNGLMULTITEXCOORD3FPROC)gl_addr[GLMULTITEXCOORD3F].func) +#define glMultiTexCoord3fARB ((PFNGLMULTITEXCOORD3FARBPROC)gl_addr[GLMULTITEXCOORD3FARB].func) +#define glMultiTexCoord3fv ((PFNGLMULTITEXCOORD3FVPROC)gl_addr[GLMULTITEXCOORD3FV].func) +#define glMultiTexCoord3fvARB ((PFNGLMULTITEXCOORD3FVARBPROC)gl_addr[GLMULTITEXCOORD3FVARB].func) +#define glMultiTexCoord3hNV ((PFNGLMULTITEXCOORD3HNVPROC)gl_addr[GLMULTITEXCOORD3HNV].func) +#define glMultiTexCoord3hvNV ((PFNGLMULTITEXCOORD3HVNVPROC)gl_addr[GLMULTITEXCOORD3HVNV].func) +#define glMultiTexCoord3i ((PFNGLMULTITEXCOORD3IPROC)gl_addr[GLMULTITEXCOORD3I].func) +#define glMultiTexCoord3iARB ((PFNGLMULTITEXCOORD3IARBPROC)gl_addr[GLMULTITEXCOORD3IARB].func) +#define glMultiTexCoord3iv ((PFNGLMULTITEXCOORD3IVPROC)gl_addr[GLMULTITEXCOORD3IV].func) +#define glMultiTexCoord3ivARB ((PFNGLMULTITEXCOORD3IVARBPROC)gl_addr[GLMULTITEXCOORD3IVARB].func) +#define glMultiTexCoord3s ((PFNGLMULTITEXCOORD3SPROC)gl_addr[GLMULTITEXCOORD3S].func) +#define glMultiTexCoord3sARB ((PFNGLMULTITEXCOORD3SARBPROC)gl_addr[GLMULTITEXCOORD3SARB].func) +#define glMultiTexCoord3sv ((PFNGLMULTITEXCOORD3SVPROC)gl_addr[GLMULTITEXCOORD3SV].func) +#define glMultiTexCoord3svARB ((PFNGLMULTITEXCOORD3SVARBPROC)gl_addr[GLMULTITEXCOORD3SVARB].func) +#define glMultiTexCoord4d ((PFNGLMULTITEXCOORD4DPROC)gl_addr[GLMULTITEXCOORD4D].func) +#define glMultiTexCoord4dARB ((PFNGLMULTITEXCOORD4DARBPROC)gl_addr[GLMULTITEXCOORD4DARB].func) +#define glMultiTexCoord4dv ((PFNGLMULTITEXCOORD4DVPROC)gl_addr[GLMULTITEXCOORD4DV].func) +#define glMultiTexCoord4dvARB ((PFNGLMULTITEXCOORD4DVARBPROC)gl_addr[GLMULTITEXCOORD4DVARB].func) +#define glMultiTexCoord4f ((PFNGLMULTITEXCOORD4FPROC)gl_addr[GLMULTITEXCOORD4F].func) +#define glMultiTexCoord4fARB ((PFNGLMULTITEXCOORD4FARBPROC)gl_addr[GLMULTITEXCOORD4FARB].func) +#define glMultiTexCoord4fv ((PFNGLMULTITEXCOORD4FVPROC)gl_addr[GLMULTITEXCOORD4FV].func) +#define glMultiTexCoord4fvARB ((PFNGLMULTITEXCOORD4FVARBPROC)gl_addr[GLMULTITEXCOORD4FVARB].func) +#define glMultiTexCoord4hNV ((PFNGLMULTITEXCOORD4HNVPROC)gl_addr[GLMULTITEXCOORD4HNV].func) +#define glMultiTexCoord4hvNV ((PFNGLMULTITEXCOORD4HVNVPROC)gl_addr[GLMULTITEXCOORD4HVNV].func) +#define glMultiTexCoord4i ((PFNGLMULTITEXCOORD4IPROC)gl_addr[GLMULTITEXCOORD4I].func) +#define glMultiTexCoord4iARB ((PFNGLMULTITEXCOORD4IARBPROC)gl_addr[GLMULTITEXCOORD4IARB].func) +#define glMultiTexCoord4iv ((PFNGLMULTITEXCOORD4IVPROC)gl_addr[GLMULTITEXCOORD4IV].func) +#define glMultiTexCoord4ivARB ((PFNGLMULTITEXCOORD4IVARBPROC)gl_addr[GLMULTITEXCOORD4IVARB].func) +#define glMultiTexCoord4s ((PFNGLMULTITEXCOORD4SPROC)gl_addr[GLMULTITEXCOORD4S].func) +#define glMultiTexCoord4sARB ((PFNGLMULTITEXCOORD4SARBPROC)gl_addr[GLMULTITEXCOORD4SARB].func) +#define glMultiTexCoord4sv ((PFNGLMULTITEXCOORD4SVPROC)gl_addr[GLMULTITEXCOORD4SV].func) +#define glMultiTexCoord4svARB ((PFNGLMULTITEXCOORD4SVARBPROC)gl_addr[GLMULTITEXCOORD4SVARB].func) +#define glMultiTexCoordPointerEXT ((PFNGLMULTITEXCOORDPOINTEREXTPROC)gl_addr[GLMULTITEXCOORDPOINTEREXT].func) +#define glMultiTexEnvfEXT ((PFNGLMULTITEXENVFEXTPROC)gl_addr[GLMULTITEXENVFEXT].func) +#define glMultiTexEnvfvEXT ((PFNGLMULTITEXENVFVEXTPROC)gl_addr[GLMULTITEXENVFVEXT].func) +#define glMultiTexEnviEXT ((PFNGLMULTITEXENVIEXTPROC)gl_addr[GLMULTITEXENVIEXT].func) +#define glMultiTexEnvivEXT ((PFNGLMULTITEXENVIVEXTPROC)gl_addr[GLMULTITEXENVIVEXT].func) +#define glMultiTexGendEXT ((PFNGLMULTITEXGENDEXTPROC)gl_addr[GLMULTITEXGENDEXT].func) +#define glMultiTexGendvEXT ((PFNGLMULTITEXGENDVEXTPROC)gl_addr[GLMULTITEXGENDVEXT].func) +#define glMultiTexGenfEXT ((PFNGLMULTITEXGENFEXTPROC)gl_addr[GLMULTITEXGENFEXT].func) +#define glMultiTexGenfvEXT ((PFNGLMULTITEXGENFVEXTPROC)gl_addr[GLMULTITEXGENFVEXT].func) +#define glMultiTexGeniEXT ((PFNGLMULTITEXGENIEXTPROC)gl_addr[GLMULTITEXGENIEXT].func) +#define glMultiTexGenivEXT ((PFNGLMULTITEXGENIVEXTPROC)gl_addr[GLMULTITEXGENIVEXT].func) +#define glMultiTexImage1DEXT ((PFNGLMULTITEXIMAGE1DEXTPROC)gl_addr[GLMULTITEXIMAGE1DEXT].func) +#define glMultiTexImage2DEXT ((PFNGLMULTITEXIMAGE2DEXTPROC)gl_addr[GLMULTITEXIMAGE2DEXT].func) +#define glMultiTexImage3DEXT ((PFNGLMULTITEXIMAGE3DEXTPROC)gl_addr[GLMULTITEXIMAGE3DEXT].func) +#define glMultiTexParameterfEXT ((PFNGLMULTITEXPARAMETERFEXTPROC)gl_addr[GLMULTITEXPARAMETERFEXT].func) +#define glMultiTexParameterfvEXT ((PFNGLMULTITEXPARAMETERFVEXTPROC)gl_addr[GLMULTITEXPARAMETERFVEXT].func) +#define glMultiTexParameteriEXT ((PFNGLMULTITEXPARAMETERIEXTPROC)gl_addr[GLMULTITEXPARAMETERIEXT].func) +#define glMultiTexParameterIivEXT ((PFNGLMULTITEXPARAMETERIIVEXTPROC)gl_addr[GLMULTITEXPARAMETERIIVEXT].func) +#define glMultiTexParameterIuivEXT ((PFNGLMULTITEXPARAMETERIUIVEXTPROC)gl_addr[GLMULTITEXPARAMETERIUIVEXT].func) +#define glMultiTexParameterivEXT ((PFNGLMULTITEXPARAMETERIVEXTPROC)gl_addr[GLMULTITEXPARAMETERIVEXT].func) +#define glMultiTexRenderbufferEXT ((PFNGLMULTITEXRENDERBUFFEREXTPROC)gl_addr[GLMULTITEXRENDERBUFFEREXT].func) +#define glMultiTexSubImage1DEXT ((PFNGLMULTITEXSUBIMAGE1DEXTPROC)gl_addr[GLMULTITEXSUBIMAGE1DEXT].func) +#define glMultiTexSubImage2DEXT ((PFNGLMULTITEXSUBIMAGE2DEXTPROC)gl_addr[GLMULTITEXSUBIMAGE2DEXT].func) +#define glMultiTexSubImage3DEXT ((PFNGLMULTITEXSUBIMAGE3DEXTPROC)gl_addr[GLMULTITEXSUBIMAGE3DEXT].func) +#define glMultTransposeMatrixd ((PFNGLMULTTRANSPOSEMATRIXDPROC)gl_addr[GLMULTTRANSPOSEMATRIXD].func) +#define glMultTransposeMatrixdARB ((PFNGLMULTTRANSPOSEMATRIXDARBPROC)gl_addr[GLMULTTRANSPOSEMATRIXDARB].func) +#define glMultTransposeMatrixfARB ((PFNGLMULTTRANSPOSEMATRIXFARBPROC)gl_addr[GLMULTTRANSPOSEMATRIXFARB].func) +#define glNamedFramebufferRenderbufferEXT ((PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC)gl_addr[GLNAMEDFRAMEBUFFERRENDERBUFFEREXT].func) +#define glNamedFramebufferTexture1DEXT ((PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC)gl_addr[GLNAMEDFRAMEBUFFERTEXTURE1DEXT].func) +#define glNamedFramebufferTexture2DEXT ((PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC)gl_addr[GLNAMEDFRAMEBUFFERTEXTURE2DEXT].func) +#define glNamedFramebufferTexture3DEXT ((PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC)gl_addr[GLNAMEDFRAMEBUFFERTEXTURE3DEXT].func) +#define glNamedFramebufferTextureEXT ((PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC)gl_addr[GLNAMEDFRAMEBUFFERTEXTUREEXT].func) +#define glNamedFramebufferTextureFaceEXT ((PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC)gl_addr[GLNAMEDFRAMEBUFFERTEXTUREFACEEXT].func) +#define glNamedFramebufferTextureLayerEXT ((PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC)gl_addr[GLNAMEDFRAMEBUFFERTEXTURELAYEREXT].func) +#define glNamedProgramLocalParameter4dEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETER4DEXT].func) +#define glNamedProgramLocalParameter4dvEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETER4DVEXT].func) +#define glNamedProgramLocalParameter4fEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETER4FEXT].func) +#define glNamedProgramLocalParameter4fvEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETER4FVEXT].func) +#define glNamedProgramLocalParameterI4iEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETERI4IEXT].func) +#define glNamedProgramLocalParameterI4ivEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETERI4IVEXT].func) +#define glNamedProgramLocalParameterI4uiEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETERI4UIEXT].func) +#define glNamedProgramLocalParameterI4uivEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETERI4UIVEXT].func) +#define glNamedProgramLocalParameters4fvEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETERS4FVEXT].func) +#define glNamedProgramLocalParametersI4ivEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETERSI4IVEXT].func) +#define glNamedProgramLocalParametersI4uivEXT ((PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC)gl_addr[GLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXT].func) +#define glNamedProgramStringEXT ((PFNGLNAMEDPROGRAMSTRINGEXTPROC)gl_addr[GLNAMEDPROGRAMSTRINGEXT].func) +#define glNamedRenderbufferStorageEXT ((PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC)gl_addr[GLNAMEDRENDERBUFFERSTORAGEEXT].func) +#define glNamedRenderbufferStorageMultisampleCoverageEXT ((PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC)gl_addr[GLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXT].func) +#define glNamedRenderbufferStorageMultisampleEXT ((PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)gl_addr[GLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXT].func) +#define glNormal3hNV ((PFNGLNORMAL3HNVPROC)gl_addr[GLNORMAL3HNV].func) +#define glNormal3hvNV ((PFNGLNORMAL3HVNVPROC)gl_addr[GLNORMAL3HVNV].func) +#define glNormalPointerEXT ((PFNGLNORMALPOINTEREXTPROC)gl_addr[GLNORMALPOINTEREXT].func) +#define glPixelDataRangeNV ((PFNGLPIXELDATARANGENVPROC)gl_addr[GLPIXELDATARANGENV].func) +#define glPointParameterfARB ((PFNGLPOINTPARAMETERFARBPROC)gl_addr[GLPOINTPARAMETERFARB].func) +#define glPointParameterfEXT ((PFNGLPOINTPARAMETERFEXTPROC)gl_addr[GLPOINTPARAMETERFEXT].func) +#define glPointParameterfvARB ((PFNGLPOINTPARAMETERFVARBPROC)gl_addr[GLPOINTPARAMETERFVARB].func) +#define glPointParameterfvEXT ((PFNGLPOINTPARAMETERFVEXTPROC)gl_addr[GLPOINTPARAMETERFVEXT].func) +#define glPointParameteriNV ((PFNGLPOINTPARAMETERINVPROC)gl_addr[GLPOINTPARAMETERINV].func) +#define glPointParameteriv ((PFNGLPOINTPARAMETERIVPROC)gl_addr[GLPOINTPARAMETERIV].func) +#define glPointParameterivNV ((PFNGLPOINTPARAMETERIVNVPROC)gl_addr[GLPOINTPARAMETERIVNV].func) +#define glPresentFrameDualFillNV ((PFNGLPRESENTFRAMEDUALFILLNVPROC)gl_addr[GLPRESENTFRAMEDUALFILLNV].func) +#define glPresentFrameKeyedNV ((PFNGLPRESENTFRAMEKEYEDNVPROC)gl_addr[GLPRESENTFRAMEKEYEDNV].func) +#define glPrimitiveRestartNV ((PFNGLPRIMITIVERESTARTNVPROC)gl_addr[GLPRIMITIVERESTARTNV].func) +#define glPrioritizeTexturesEXT ((PFNGLPRIORITIZETEXTURESEXTPROC)gl_addr[GLPRIORITIZETEXTURESEXT].func) +#define glProgramBufferParametersIivNV ((PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC)gl_addr[GLPROGRAMBUFFERPARAMETERSIIVNV].func) +#define glProgramBufferParametersIuivNV ((PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC)gl_addr[GLPROGRAMBUFFERPARAMETERSIUIVNV].func) +#define glProgramEnvParameter4dARB ((PFNGLPROGRAMENVPARAMETER4DARBPROC)gl_addr[GLPROGRAMENVPARAMETER4DARB].func) +#define glProgramEnvParameter4dvARB ((PFNGLPROGRAMENVPARAMETER4DVARBPROC)gl_addr[GLPROGRAMENVPARAMETER4DVARB].func) +#define glProgramEnvParameterI4iNV ((PFNGLPROGRAMENVPARAMETERI4INVPROC)gl_addr[GLPROGRAMENVPARAMETERI4INV].func) +#define glProgramEnvParameterI4ivNV ((PFNGLPROGRAMENVPARAMETERI4IVNVPROC)gl_addr[GLPROGRAMENVPARAMETERI4IVNV].func) +#define glProgramEnvParameterI4uiNV ((PFNGLPROGRAMENVPARAMETERI4UINVPROC)gl_addr[GLPROGRAMENVPARAMETERI4UINV].func) +#define glProgramEnvParameterI4uivNV ((PFNGLPROGRAMENVPARAMETERI4UIVNVPROC)gl_addr[GLPROGRAMENVPARAMETERI4UIVNV].func) +#define glProgramEnvParametersI4ivNV ((PFNGLPROGRAMENVPARAMETERSI4IVNVPROC)gl_addr[GLPROGRAMENVPARAMETERSI4IVNV].func) +#define glProgramEnvParametersI4uivNV ((PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC)gl_addr[GLPROGRAMENVPARAMETERSI4UIVNV].func) +#define glProgramLocalParameter4dARB ((PFNGLPROGRAMLOCALPARAMETER4DARBPROC)gl_addr[GLPROGRAMLOCALPARAMETER4DARB].func) +#define glProgramLocalParameter4dvARB ((PFNGLPROGRAMLOCALPARAMETER4DVARBPROC)gl_addr[GLPROGRAMLOCALPARAMETER4DVARB].func) +#define glProgramLocalParameterI4iNV ((PFNGLPROGRAMLOCALPARAMETERI4INVPROC)gl_addr[GLPROGRAMLOCALPARAMETERI4INV].func) +#define glProgramLocalParameterI4ivNV ((PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC)gl_addr[GLPROGRAMLOCALPARAMETERI4IVNV].func) +#define glProgramLocalParameterI4uiNV ((PFNGLPROGRAMLOCALPARAMETERI4UINVPROC)gl_addr[GLPROGRAMLOCALPARAMETERI4UINV].func) +#define glProgramLocalParameterI4uivNV ((PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC)gl_addr[GLPROGRAMLOCALPARAMETERI4UIVNV].func) +#define glProgramLocalParametersI4ivNV ((PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC)gl_addr[GLPROGRAMLOCALPARAMETERSI4IVNV].func) +#define glProgramLocalParametersI4uivNV ((PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC)gl_addr[GLPROGRAMLOCALPARAMETERSI4UIVNV].func) +#define glProgramNamedParameter4dNV ((PFNGLPROGRAMNAMEDPARAMETER4DNVPROC)gl_addr[GLPROGRAMNAMEDPARAMETER4DNV].func) +#define glProgramNamedParameter4dvNV ((PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC)gl_addr[GLPROGRAMNAMEDPARAMETER4DVNV].func) +#define glProgramNamedParameter4fNV ((PFNGLPROGRAMNAMEDPARAMETER4FNVPROC)gl_addr[GLPROGRAMNAMEDPARAMETER4FNV].func) +#define glProgramNamedParameter4fvNV ((PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC)gl_addr[GLPROGRAMNAMEDPARAMETER4FVNV].func) +#define glProgramParameter4dNV ((PFNGLPROGRAMPARAMETER4DNVPROC)gl_addr[GLPROGRAMPARAMETER4DNV].func) +#define glProgramParameter4dvNV ((PFNGLPROGRAMPARAMETER4DVNVPROC)gl_addr[GLPROGRAMPARAMETER4DVNV].func) +#define glProgramParameter4fNV ((PFNGLPROGRAMPARAMETER4FNVPROC)gl_addr[GLPROGRAMPARAMETER4FNV].func) +#define glProgramParameter4fvNV ((PFNGLPROGRAMPARAMETER4FVNVPROC)gl_addr[GLPROGRAMPARAMETER4FVNV].func) +#define glProgramParameteriARB ((PFNGLPROGRAMPARAMETERIARBPROC)gl_addr[GLPROGRAMPARAMETERIARB].func) +#define glProgramParameteriEXT ((PFNGLPROGRAMPARAMETERIEXTPROC)gl_addr[GLPROGRAMPARAMETERIEXT].func) +#define glProgramParameters4dvNV ((PFNGLPROGRAMPARAMETERS4DVNVPROC)gl_addr[GLPROGRAMPARAMETERS4DVNV].func) +#define glProgramParameters4fvNV ((PFNGLPROGRAMPARAMETERS4FVNVPROC)gl_addr[GLPROGRAMPARAMETERS4FVNV].func) +#define glProgramStringARB ((PFNGLPROGRAMSTRINGARBPROC)gl_addr[GLPROGRAMSTRINGARB].func) +#define glProgramUniform1fEXT ((PFNGLPROGRAMUNIFORM1FEXTPROC)gl_addr[GLPROGRAMUNIFORM1FEXT].func) +#define glProgramUniform1fvEXT ((PFNGLPROGRAMUNIFORM1FVEXTPROC)gl_addr[GLPROGRAMUNIFORM1FVEXT].func) +#define glProgramUniform1iEXT ((PFNGLPROGRAMUNIFORM1IEXTPROC)gl_addr[GLPROGRAMUNIFORM1IEXT].func) +#define glProgramUniform1ivEXT ((PFNGLPROGRAMUNIFORM1IVEXTPROC)gl_addr[GLPROGRAMUNIFORM1IVEXT].func) +#define glProgramUniform1uiEXT ((PFNGLPROGRAMUNIFORM1UIEXTPROC)gl_addr[GLPROGRAMUNIFORM1UIEXT].func) +#define glProgramUniform1uivEXT ((PFNGLPROGRAMUNIFORM1UIVEXTPROC)gl_addr[GLPROGRAMUNIFORM1UIVEXT].func) +#define glProgramUniform2fEXT ((PFNGLPROGRAMUNIFORM2FEXTPROC)gl_addr[GLPROGRAMUNIFORM2FEXT].func) +#define glProgramUniform2fvEXT ((PFNGLPROGRAMUNIFORM2FVEXTPROC)gl_addr[GLPROGRAMUNIFORM2FVEXT].func) +#define glProgramUniform2iEXT ((PFNGLPROGRAMUNIFORM2IEXTPROC)gl_addr[GLPROGRAMUNIFORM2IEXT].func) +#define glProgramUniform2ivEXT ((PFNGLPROGRAMUNIFORM2IVEXTPROC)gl_addr[GLPROGRAMUNIFORM2IVEXT].func) +#define glProgramUniform2uiEXT ((PFNGLPROGRAMUNIFORM2UIEXTPROC)gl_addr[GLPROGRAMUNIFORM2UIEXT].func) +#define glProgramUniform2uivEXT ((PFNGLPROGRAMUNIFORM2UIVEXTPROC)gl_addr[GLPROGRAMUNIFORM2UIVEXT].func) +#define glProgramUniform3fEXT ((PFNGLPROGRAMUNIFORM3FEXTPROC)gl_addr[GLPROGRAMUNIFORM3FEXT].func) +#define glProgramUniform3fvEXT ((PFNGLPROGRAMUNIFORM3FVEXTPROC)gl_addr[GLPROGRAMUNIFORM3FVEXT].func) +#define glProgramUniform3iEXT ((PFNGLPROGRAMUNIFORM3IEXTPROC)gl_addr[GLPROGRAMUNIFORM3IEXT].func) +#define glProgramUniform3ivEXT ((PFNGLPROGRAMUNIFORM3IVEXTPROC)gl_addr[GLPROGRAMUNIFORM3IVEXT].func) +#define glProgramUniform3uiEXT ((PFNGLPROGRAMUNIFORM3UIEXTPROC)gl_addr[GLPROGRAMUNIFORM3UIEXT].func) +#define glProgramUniform3uivEXT ((PFNGLPROGRAMUNIFORM3UIVEXTPROC)gl_addr[GLPROGRAMUNIFORM3UIVEXT].func) +#define glProgramUniform4fEXT ((PFNGLPROGRAMUNIFORM4FEXTPROC)gl_addr[GLPROGRAMUNIFORM4FEXT].func) +#define glProgramUniform4fvEXT ((PFNGLPROGRAMUNIFORM4FVEXTPROC)gl_addr[GLPROGRAMUNIFORM4FVEXT].func) +#define glProgramUniform4iEXT ((PFNGLPROGRAMUNIFORM4IEXTPROC)gl_addr[GLPROGRAMUNIFORM4IEXT].func) +#define glProgramUniform4ivEXT ((PFNGLPROGRAMUNIFORM4IVEXTPROC)gl_addr[GLPROGRAMUNIFORM4IVEXT].func) +#define glProgramUniform4uiEXT ((PFNGLPROGRAMUNIFORM4UIEXTPROC)gl_addr[GLPROGRAMUNIFORM4UIEXT].func) +#define glProgramUniform4uivEXT ((PFNGLPROGRAMUNIFORM4UIVEXTPROC)gl_addr[GLPROGRAMUNIFORM4UIVEXT].func) +#define glProgramUniformMatrix2fvEXT ((PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX2FVEXT].func) +#define glProgramUniformMatrix2x3fvEXT ((PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX2X3FVEXT].func) +#define glProgramUniformMatrix2x4fvEXT ((PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX2X4FVEXT].func) +#define glProgramUniformMatrix3fvEXT ((PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX3FVEXT].func) +#define glProgramUniformMatrix3x2fvEXT ((PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX3X2FVEXT].func) +#define glProgramUniformMatrix3x4fvEXT ((PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX3X4FVEXT].func) +#define glProgramUniformMatrix4fvEXT ((PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX4FVEXT].func) +#define glProgramUniformMatrix4x2fvEXT ((PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX4X2FVEXT].func) +#define glProgramUniformMatrix4x3fvEXT ((PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC)gl_addr[GLPROGRAMUNIFORMMATRIX4X3FVEXT].func) +#define glProgramVertexLimitNV ((PFNGLPROGRAMVERTEXLIMITNVPROC)gl_addr[GLPROGRAMVERTEXLIMITNV].func) +#define glPushClientAttribDefaultEXT ((PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC)gl_addr[GLPUSHCLIENTATTRIBDEFAULTEXT].func) +#define glQueryCounter ((PFNGLQUERYCOUNTERPROC)gl_addr[GLQUERYCOUNTER].func) +#define glRenderbufferStorage ((PFNGLRENDERBUFFERSTORAGEPROC)gl_addr[GLRENDERBUFFERSTORAGE].func) +#define glRenderbufferStorageMultisample ((PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)gl_addr[GLRENDERBUFFERSTORAGEMULTISAMPLE].func) +#define glRenderbufferStorageMultisampleEXT ((PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)gl_addr[GLRENDERBUFFERSTORAGEMULTISAMPLEEXT].func) +#define glRequestResidentProgramsNV ((PFNGLREQUESTRESIDENTPROGRAMSNVPROC)gl_addr[GLREQUESTRESIDENTPROGRAMSNV].func) +#define glResetHistogram ((PFNGLRESETHISTOGRAMPROC)gl_addr[GLRESETHISTOGRAM].func) +#define glResetMinmax ((PFNGLRESETMINMAXPROC)gl_addr[GLRESETMINMAX].func) +#define glSampleCoverage ((PFNGLSAMPLECOVERAGEPROC)gl_addr[GLSAMPLECOVERAGE].func) +#define glSampleCoverageARB ((PFNGLSAMPLECOVERAGEARBPROC)gl_addr[GLSAMPLECOVERAGEARB].func) +#define glSampleMaskIndexedNV ((PFNGLSAMPLEMASKINDEXEDNVPROC)gl_addr[GLSAMPLEMASKINDEXEDNV].func) +#define glSamplerParameterf ((PFNGLSAMPLERPARAMETERFPROC)gl_addr[GLSAMPLERPARAMETERF].func) +#define glSamplerParameterfv ((PFNGLSAMPLERPARAMETERFVPROC)gl_addr[GLSAMPLERPARAMETERFV].func) +#define glSamplerParameteri ((PFNGLSAMPLERPARAMETERIPROC)gl_addr[GLSAMPLERPARAMETERI].func) +#define glSecondaryColor3b ((PFNGLSECONDARYCOLOR3BPROC)gl_addr[GLSECONDARYCOLOR3B].func) +#define glSecondaryColor3bEXT ((PFNGLSECONDARYCOLOR3BEXTPROC)gl_addr[GLSECONDARYCOLOR3BEXT].func) +#define glSecondaryColor3bv ((PFNGLSECONDARYCOLOR3BVPROC)gl_addr[GLSECONDARYCOLOR3BV].func) +#define glSecondaryColor3bvEXT ((PFNGLSECONDARYCOLOR3BVEXTPROC)gl_addr[GLSECONDARYCOLOR3BVEXT].func) +#define glSecondaryColor3d ((PFNGLSECONDARYCOLOR3DPROC)gl_addr[GLSECONDARYCOLOR3D].func) +#define glSecondaryColor3dEXT ((PFNGLSECONDARYCOLOR3DEXTPROC)gl_addr[GLSECONDARYCOLOR3DEXT].func) +#define glSecondaryColor3dv ((PFNGLSECONDARYCOLOR3DVPROC)gl_addr[GLSECONDARYCOLOR3DV].func) +#define glSecondaryColor3dvEXT ((PFNGLSECONDARYCOLOR3DVEXTPROC)gl_addr[GLSECONDARYCOLOR3DVEXT].func) +#define glSecondaryColor3f ((PFNGLSECONDARYCOLOR3FPROC)gl_addr[GLSECONDARYCOLOR3F].func) +#define glSecondaryColor3fEXT ((PFNGLSECONDARYCOLOR3FEXTPROC)gl_addr[GLSECONDARYCOLOR3FEXT].func) +#define glSecondaryColor3fv ((PFNGLSECONDARYCOLOR3FVPROC)gl_addr[GLSECONDARYCOLOR3FV].func) +#define glSecondaryColor3fvEXT ((PFNGLSECONDARYCOLOR3FVEXTPROC)gl_addr[GLSECONDARYCOLOR3FVEXT].func) +#define glSecondaryColor3hNV ((PFNGLSECONDARYCOLOR3HNVPROC)gl_addr[GLSECONDARYCOLOR3HNV].func) +#define glSecondaryColor3hvNV ((PFNGLSECONDARYCOLOR3HVNVPROC)gl_addr[GLSECONDARYCOLOR3HVNV].func) +#define glSecondaryColor3i ((PFNGLSECONDARYCOLOR3IPROC)gl_addr[GLSECONDARYCOLOR3I].func) +#define glSecondaryColor3iEXT ((PFNGLSECONDARYCOLOR3IEXTPROC)gl_addr[GLSECONDARYCOLOR3IEXT].func) +#define glSecondaryColor3iv ((PFNGLSECONDARYCOLOR3IVPROC)gl_addr[GLSECONDARYCOLOR3IV].func) +#define glSecondaryColor3ivEXT ((PFNGLSECONDARYCOLOR3IVEXTPROC)gl_addr[GLSECONDARYCOLOR3IVEXT].func) +#define glSecondaryColor3s ((PFNGLSECONDARYCOLOR3SPROC)gl_addr[GLSECONDARYCOLOR3S].func) +#define glSecondaryColor3sEXT ((PFNGLSECONDARYCOLOR3SEXTPROC)gl_addr[GLSECONDARYCOLOR3SEXT].func) +#define glSecondaryColor3sv ((PFNGLSECONDARYCOLOR3SVPROC)gl_addr[GLSECONDARYCOLOR3SV].func) +#define glSecondaryColor3svEXT ((PFNGLSECONDARYCOLOR3SVEXTPROC)gl_addr[GLSECONDARYCOLOR3SVEXT].func) +#define glSecondaryColor3ub ((PFNGLSECONDARYCOLOR3UBPROC)gl_addr[GLSECONDARYCOLOR3UB].func) +#define glSecondaryColor3ubEXT ((PFNGLSECONDARYCOLOR3UBEXTPROC)gl_addr[GLSECONDARYCOLOR3UBEXT].func) +#define glSecondaryColor3ubv ((PFNGLSECONDARYCOLOR3UBVPROC)gl_addr[GLSECONDARYCOLOR3UBV].func) +#define glSecondaryColor3ubvEXT ((PFNGLSECONDARYCOLOR3UBVEXTPROC)gl_addr[GLSECONDARYCOLOR3UBVEXT].func) +#define glSecondaryColor3ui ((PFNGLSECONDARYCOLOR3UIPROC)gl_addr[GLSECONDARYCOLOR3UI].func) +#define glSecondaryColor3uiEXT ((PFNGLSECONDARYCOLOR3UIEXTPROC)gl_addr[GLSECONDARYCOLOR3UIEXT].func) +#define glSecondaryColor3uiv ((PFNGLSECONDARYCOLOR3UIVPROC)gl_addr[GLSECONDARYCOLOR3UIV].func) +#define glSecondaryColor3uivEXT ((PFNGLSECONDARYCOLOR3UIVEXTPROC)gl_addr[GLSECONDARYCOLOR3UIVEXT].func) +#define glSecondaryColor3us ((PFNGLSECONDARYCOLOR3USPROC)gl_addr[GLSECONDARYCOLOR3US].func) +#define glSecondaryColor3usEXT ((PFNGLSECONDARYCOLOR3USEXTPROC)gl_addr[GLSECONDARYCOLOR3USEXT].func) +#define glSecondaryColor3usv ((PFNGLSECONDARYCOLOR3USVPROC)gl_addr[GLSECONDARYCOLOR3USV].func) +#define glSecondaryColor3usvEXT ((PFNGLSECONDARYCOLOR3USVEXTPROC)gl_addr[GLSECONDARYCOLOR3USVEXT].func) +#define glSecondaryColorPointer ((PFNGLSECONDARYCOLORPOINTERPROC)gl_addr[GLSECONDARYCOLORPOINTER].func) +#define glSecondaryColorPointerEXT ((PFNGLSECONDARYCOLORPOINTEREXTPROC)gl_addr[GLSECONDARYCOLORPOINTEREXT].func) +#define glSeparableFilter2D ((PFNGLSEPARABLEFILTER2DPROC)gl_addr[GLSEPARABLEFILTER2D].func) +#define glSetFenceNV ((PFNGLSETFENCENVPROC)gl_addr[GLSETFENCENV].func) +#define glShaderSource ((PFNGLSHADERSOURCEPROC)gl_addr[GLSHADERSOURCE].func) +#define glShaderSourceARB ((PFNGLSHADERSOURCEARBPROC)gl_addr[GLSHADERSOURCEARB].func) +#define glStencilFuncSeparate ((PFNGLSTENCILFUNCSEPARATEPROC)gl_addr[GLSTENCILFUNCSEPARATE].func) +#define glStencilMaskSeparate ((PFNGLSTENCILMASKSEPARATEPROC)gl_addr[GLSTENCILMASKSEPARATE].func) +#define glStencilOpSeparate ((PFNGLSTENCILOPSEPARATEPROC)gl_addr[GLSTENCILOPSEPARATE].func) +#define glTestFenceNV ((PFNGLTESTFENCENVPROC)gl_addr[GLTESTFENCENV].func) +#define glTexBufferARB ((PFNGLTEXBUFFERARBPROC)gl_addr[GLTEXBUFFERARB].func) +#define glTexBufferEXT ((PFNGLTEXBUFFEREXTPROC)gl_addr[GLTEXBUFFEREXT].func) +#define glTexCoord1hNV ((PFNGLTEXCOORD1HNVPROC)gl_addr[GLTEXCOORD1HNV].func) +#define glTexCoord1hvNV ((PFNGLTEXCOORD1HVNVPROC)gl_addr[GLTEXCOORD1HVNV].func) +#define glTexCoord2hNV ((PFNGLTEXCOORD2HNVPROC)gl_addr[GLTEXCOORD2HNV].func) +#define glTexCoord2hvNV ((PFNGLTEXCOORD2HVNVPROC)gl_addr[GLTEXCOORD2HVNV].func) +#define glTexCoord3hNV ((PFNGLTEXCOORD3HNVPROC)gl_addr[GLTEXCOORD3HNV].func) +#define glTexCoord3hvNV ((PFNGLTEXCOORD3HVNVPROC)gl_addr[GLTEXCOORD3HVNV].func) +#define glTexCoord4hNV ((PFNGLTEXCOORD4HNVPROC)gl_addr[GLTEXCOORD4HNV].func) +#define glTexCoord4hvNV ((PFNGLTEXCOORD4HVNVPROC)gl_addr[GLTEXCOORD4HVNV].func) +#define glTexCoordPointerEXT ((PFNGLTEXCOORDPOINTEREXTPROC)gl_addr[GLTEXCOORDPOINTEREXT].func) +#define glTexImage3D ((PFNGLTEXIMAGE3DPROC)gl_addr[GLTEXIMAGE3D].func) +#define glTexImage3DEXT ((PFNGLTEXIMAGE3DEXTPROC)gl_addr[GLTEXIMAGE3DEXT].func) +#define glTexParameterIiv ((PFNGLTEXPARAMETERIIVPROC)gl_addr[GLTEXPARAMETERIIV].func) +#define glTexParameterIivEXT ((PFNGLTEXPARAMETERIIVEXTPROC)gl_addr[GLTEXPARAMETERIIVEXT].func) +#define glTexParameterIuiv ((PFNGLTEXPARAMETERIUIVPROC)gl_addr[GLTEXPARAMETERIUIV].func) +#define glTexParameterIuivEXT ((PFNGLTEXPARAMETERIUIVEXTPROC)gl_addr[GLTEXPARAMETERIUIVEXT].func) +#define glTexRenderbufferNV ((PFNGLTEXRENDERBUFFERNVPROC)gl_addr[GLTEXRENDERBUFFERNV].func) +#define glTexStorage2D ((PFNGLTEXSTORAGE2DPROC)gl_addr[GLTEXSTORAGE2D].func) +#define glTexSubImage3D ((PFNGLTEXSUBIMAGE3DPROC)gl_addr[GLTEXSUBIMAGE3D].func) +#define glTexSubImage3DEXT ((PFNGLTEXSUBIMAGE3DEXTPROC)gl_addr[GLTEXSUBIMAGE3DEXT].func) +#define glTextureBarrierNV ((PFNGLTEXTUREBARRIERNVPROC)gl_addr[GLTEXTUREBARRIERNV].func) +#define glTextureBufferEXT ((PFNGLTEXTUREBUFFEREXTPROC)gl_addr[GLTEXTUREBUFFEREXT].func) +#define glTextureImage1DEXT ((PFNGLTEXTUREIMAGE1DEXTPROC)gl_addr[GLTEXTUREIMAGE1DEXT].func) +#define glTextureImage2DEXT ((PFNGLTEXTUREIMAGE2DEXTPROC)gl_addr[GLTEXTUREIMAGE2DEXT].func) +#define glTextureImage3DEXT ((PFNGLTEXTUREIMAGE3DEXTPROC)gl_addr[GLTEXTUREIMAGE3DEXT].func) +#define glTextureParameterfEXT ((PFNGLTEXTUREPARAMETERFEXTPROC)gl_addr[GLTEXTUREPARAMETERFEXT].func) +#define glTextureParameterfvEXT ((PFNGLTEXTUREPARAMETERFVEXTPROC)gl_addr[GLTEXTUREPARAMETERFVEXT].func) +#define glTextureParameteriEXT ((PFNGLTEXTUREPARAMETERIEXTPROC)gl_addr[GLTEXTUREPARAMETERIEXT].func) +#define glTextureParameterIivEXT ((PFNGLTEXTUREPARAMETERIIVEXTPROC)gl_addr[GLTEXTUREPARAMETERIIVEXT].func) +#define glTextureParameterIuivEXT ((PFNGLTEXTUREPARAMETERIUIVEXTPROC)gl_addr[GLTEXTUREPARAMETERIUIVEXT].func) +#define glTextureParameterivEXT ((PFNGLTEXTUREPARAMETERIVEXTPROC)gl_addr[GLTEXTUREPARAMETERIVEXT].func) +#define glTextureRenderbufferEXT ((PFNGLTEXTURERENDERBUFFEREXTPROC)gl_addr[GLTEXTURERENDERBUFFEREXT].func) +#define glTextureStorage2DEXT ((PFNGLTEXTURESTORAGE2DEXTPROC)gl_addr[GLTEXTURESTORAGE2DEXT].func) +#define glTextureSubImage1DEXT ((PFNGLTEXTURESUBIMAGE1DEXTPROC)gl_addr[GLTEXTURESUBIMAGE1DEXT].func) +#define glTextureSubImage2DEXT ((PFNGLTEXTURESUBIMAGE2DEXTPROC)gl_addr[GLTEXTURESUBIMAGE2DEXT].func) +#define glTextureSubImage3DEXT ((PFNGLTEXTURESUBIMAGE3DEXTPROC)gl_addr[GLTEXTURESUBIMAGE3DEXT].func) +#define glTrackMatrixNV ((PFNGLTRACKMATRIXNVPROC)gl_addr[GLTRACKMATRIXNV].func) +#define glTransformFeedbackAttribsNV ((PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC)gl_addr[GLTRANSFORMFEEDBACKATTRIBSNV].func) +#define glTransformFeedbackVaryings ((PFNGLTRANSFORMFEEDBACKVARYINGSPROC)gl_addr[GLTRANSFORMFEEDBACKVARYINGS].func) +#define glTransformFeedbackVaryingsNV ((PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC)gl_addr[GLTRANSFORMFEEDBACKVARYINGSNV].func) +#define glUniform1f ((PFNGLUNIFORM1FPROC)gl_addr[GLUNIFORM1F].func) +#define glUniform1fARB ((PFNGLUNIFORM1FARBPROC)gl_addr[GLUNIFORM1FARB].func) +#define glUniform1fv ((PFNGLUNIFORM1FVPROC)gl_addr[GLUNIFORM1FV].func) +#define glUniform1fvARB ((PFNGLUNIFORM1FVARBPROC)gl_addr[GLUNIFORM1FVARB].func) +#define glUniform1i ((PFNGLUNIFORM1IPROC)gl_addr[GLUNIFORM1I].func) +#define glUniform1iARB ((PFNGLUNIFORM1IARBPROC)gl_addr[GLUNIFORM1IARB].func) +#define glUniform1iv ((PFNGLUNIFORM1IVPROC)gl_addr[GLUNIFORM1IV].func) +#define glUniform1ivARB ((PFNGLUNIFORM1IVARBPROC)gl_addr[GLUNIFORM1IVARB].func) +#define glUniform1ui ((PFNGLUNIFORM1UIPROC)gl_addr[GLUNIFORM1UI].func) +#define glUniform1uiEXT ((PFNGLUNIFORM1UIEXTPROC)gl_addr[GLUNIFORM1UIEXT].func) +#define glUniform1uiv ((PFNGLUNIFORM1UIVPROC)gl_addr[GLUNIFORM1UIV].func) +#define glUniform1uivEXT ((PFNGLUNIFORM1UIVEXTPROC)gl_addr[GLUNIFORM1UIVEXT].func) +#define glUniform2f ((PFNGLUNIFORM2FPROC)gl_addr[GLUNIFORM2F].func) +#define glUniform2fARB ((PFNGLUNIFORM2FARBPROC)gl_addr[GLUNIFORM2FARB].func) +#define glUniform2fv ((PFNGLUNIFORM2FVPROC)gl_addr[GLUNIFORM2FV].func) +#define glUniform2fvARB ((PFNGLUNIFORM2FVARBPROC)gl_addr[GLUNIFORM2FVARB].func) +#define glUniform2i ((PFNGLUNIFORM2IPROC)gl_addr[GLUNIFORM2I].func) +#define glUniform2iARB ((PFNGLUNIFORM2IARBPROC)gl_addr[GLUNIFORM2IARB].func) +#define glUniform2iv ((PFNGLUNIFORM2IVPROC)gl_addr[GLUNIFORM2IV].func) +#define glUniform2ivARB ((PFNGLUNIFORM2IVARBPROC)gl_addr[GLUNIFORM2IVARB].func) +#define glUniform2ui ((PFNGLUNIFORM2UIPROC)gl_addr[GLUNIFORM2UI].func) +#define glUniform2uiEXT ((PFNGLUNIFORM2UIEXTPROC)gl_addr[GLUNIFORM2UIEXT].func) +#define glUniform2uiv ((PFNGLUNIFORM2UIVPROC)gl_addr[GLUNIFORM2UIV].func) +#define glUniform2uivEXT ((PFNGLUNIFORM2UIVEXTPROC)gl_addr[GLUNIFORM2UIVEXT].func) +#define glUniform3f ((PFNGLUNIFORM3FPROC)gl_addr[GLUNIFORM3F].func) +#define glUniform3fARB ((PFNGLUNIFORM3FARBPROC)gl_addr[GLUNIFORM3FARB].func) +#define glUniform3fv ((PFNGLUNIFORM3FVPROC)gl_addr[GLUNIFORM3FV].func) +#define glUniform3fvARB ((PFNGLUNIFORM3FVARBPROC)gl_addr[GLUNIFORM3FVARB].func) +#define glUniform3i ((PFNGLUNIFORM3IPROC)gl_addr[GLUNIFORM3I].func) +#define glUniform3iARB ((PFNGLUNIFORM3IARBPROC)gl_addr[GLUNIFORM3IARB].func) +#define glUniform3iv ((PFNGLUNIFORM3IVPROC)gl_addr[GLUNIFORM3IV].func) +#define glUniform3ivARB ((PFNGLUNIFORM3IVARBPROC)gl_addr[GLUNIFORM3IVARB].func) +#define glUniform3ui ((PFNGLUNIFORM3UIPROC)gl_addr[GLUNIFORM3UI].func) +#define glUniform3uiEXT ((PFNGLUNIFORM3UIEXTPROC)gl_addr[GLUNIFORM3UIEXT].func) +#define glUniform3uiv ((PFNGLUNIFORM3UIVPROC)gl_addr[GLUNIFORM3UIV].func) +#define glUniform3uivEXT ((PFNGLUNIFORM3UIVEXTPROC)gl_addr[GLUNIFORM3UIVEXT].func) +#define glUniform4f ((PFNGLUNIFORM4FPROC)gl_addr[GLUNIFORM4F].func) +#define glUniform4fARB ((PFNGLUNIFORM4FARBPROC)gl_addr[GLUNIFORM4FARB].func) +#define glUniform4fv ((PFNGLUNIFORM4FVPROC)gl_addr[GLUNIFORM4FV].func) +#define glUniform4fvARB ((PFNGLUNIFORM4FVARBPROC)gl_addr[GLUNIFORM4FVARB].func) +#define glUniform4i ((PFNGLUNIFORM4IPROC)gl_addr[GLUNIFORM4I].func) +#define glUniform4iARB ((PFNGLUNIFORM4IARBPROC)gl_addr[GLUNIFORM4IARB].func) +#define glUniform4iv ((PFNGLUNIFORM4IVPROC)gl_addr[GLUNIFORM4IV].func) +#define glUniform4ivARB ((PFNGLUNIFORM4IVARBPROC)gl_addr[GLUNIFORM4IVARB].func) +#define glUniform4ui ((PFNGLUNIFORM4UIPROC)gl_addr[GLUNIFORM4UI].func) +#define glUniform4uiEXT ((PFNGLUNIFORM4UIEXTPROC)gl_addr[GLUNIFORM4UIEXT].func) +#define glUniform4uiv ((PFNGLUNIFORM4UIVPROC)gl_addr[GLUNIFORM4UIV].func) +#define glUniform4uivEXT ((PFNGLUNIFORM4UIVEXTPROC)gl_addr[GLUNIFORM4UIVEXT].func) +#define glUniformBufferEXT ((PFNGLUNIFORMBUFFEREXTPROC)gl_addr[GLUNIFORMBUFFEREXT].func) +#define glUniformMatrix2fv ((PFNGLUNIFORMMATRIX2FVPROC)gl_addr[GLUNIFORMMATRIX2FV].func) +#define glUniformMatrix2fvARB ((PFNGLUNIFORMMATRIX2FVARBPROC)gl_addr[GLUNIFORMMATRIX2FVARB].func) +#define glUniformMatrix2x3fv ((PFNGLUNIFORMMATRIX2X3FVPROC)gl_addr[GLUNIFORMMATRIX2X3FV].func) +#define glUniformMatrix2x4fv ((PFNGLUNIFORMMATRIX2X4FVPROC)gl_addr[GLUNIFORMMATRIX2X4FV].func) +#define glUniformMatrix3fv ((PFNGLUNIFORMMATRIX3FVPROC)gl_addr[GLUNIFORMMATRIX3FV].func) +#define glUniformMatrix3fvARB ((PFNGLUNIFORMMATRIX3FVARBPROC)gl_addr[GLUNIFORMMATRIX3FVARB].func) +#define glUniformMatrix3x2fv ((PFNGLUNIFORMMATRIX3X2FVPROC)gl_addr[GLUNIFORMMATRIX3X2FV].func) +#define glUniformMatrix3x4fv ((PFNGLUNIFORMMATRIX3X4FVPROC)gl_addr[GLUNIFORMMATRIX3X4FV].func) +#define glUniformMatrix4fv ((PFNGLUNIFORMMATRIX4FVPROC)gl_addr[GLUNIFORMMATRIX4FV].func) +#define glUniformMatrix4fvARB ((PFNGLUNIFORMMATRIX4FVARBPROC)gl_addr[GLUNIFORMMATRIX4FVARB].func) +#define glUniformMatrix4x2fv ((PFNGLUNIFORMMATRIX4X2FVPROC)gl_addr[GLUNIFORMMATRIX4X2FV].func) +#define glUniformMatrix4x3fv ((PFNGLUNIFORMMATRIX4X3FVPROC)gl_addr[GLUNIFORMMATRIX4X3FV].func) +#define glUnlockArraysEXT ((PFNGLUNLOCKARRAYSEXTPROC)gl_addr[GLUNLOCKARRAYSEXT].func) +#define glUnmapBuffer ((PFNGLUNMAPBUFFERPROC)gl_addr[GLUNMAPBUFFER].func) +#define glUnmapBufferARB ((PFNGLUNMAPBUFFERARBPROC)gl_addr[GLUNMAPBUFFERARB].func) +#define glUseProgramObjectARB ((PFNGLUSEPROGRAMOBJECTARBPROC)gl_addr[GLUSEPROGRAMOBJECTARB].func) +#define glValidateProgram ((PFNGLVALIDATEPROGRAMPROC)gl_addr[GLVALIDATEPROGRAM].func) +#define glValidateProgramARB ((PFNGLVALIDATEPROGRAMARBPROC)gl_addr[GLVALIDATEPROGRAMARB].func) +#define glVertex2hNV ((PFNGLVERTEX2HNVPROC)gl_addr[GLVERTEX2HNV].func) +#define glVertex2hvNV ((PFNGLVERTEX2HVNVPROC)gl_addr[GLVERTEX2HVNV].func) +#define glVertex3hNV ((PFNGLVERTEX3HNVPROC)gl_addr[GLVERTEX3HNV].func) +#define glVertex3hvNV ((PFNGLVERTEX3HVNVPROC)gl_addr[GLVERTEX3HVNV].func) +#define glVertex4hNV ((PFNGLVERTEX4HNVPROC)gl_addr[GLVERTEX4HNV].func) +#define glVertex4hvNV ((PFNGLVERTEX4HVNVPROC)gl_addr[GLVERTEX4HVNV].func) +#define glVertexArrayRangeNV ((PFNGLVERTEXARRAYRANGENVPROC)gl_addr[GLVERTEXARRAYRANGENV].func) +#define glVertexAttrib1d ((PFNGLVERTEXATTRIB1DPROC)gl_addr[GLVERTEXATTRIB1D].func) +#define glVertexAttrib1dARB ((PFNGLVERTEXATTRIB1DARBPROC)gl_addr[GLVERTEXATTRIB1DARB].func) +#define glVertexAttrib1dNV ((PFNGLVERTEXATTRIB1DNVPROC)gl_addr[GLVERTEXATTRIB1DNV].func) +#define glVertexAttrib1dv ((PFNGLVERTEXATTRIB1DVPROC)gl_addr[GLVERTEXATTRIB1DV].func) +#define glVertexAttrib1dvARB ((PFNGLVERTEXATTRIB1DVARBPROC)gl_addr[GLVERTEXATTRIB1DVARB].func) +#define glVertexAttrib1dvNV ((PFNGLVERTEXATTRIB1DVNVPROC)gl_addr[GLVERTEXATTRIB1DVNV].func) +#define glVertexAttrib1f ((PFNGLVERTEXATTRIB1FPROC)gl_addr[GLVERTEXATTRIB1F].func) +#define glVertexAttrib1fARB ((PFNGLVERTEXATTRIB1FARBPROC)gl_addr[GLVERTEXATTRIB1FARB].func) +#define glVertexAttrib1fNV ((PFNGLVERTEXATTRIB1FNVPROC)gl_addr[GLVERTEXATTRIB1FNV].func) +#define glVertexAttrib1fv ((PFNGLVERTEXATTRIB1FVPROC)gl_addr[GLVERTEXATTRIB1FV].func) +#define glVertexAttrib1fvARB ((PFNGLVERTEXATTRIB1FVARBPROC)gl_addr[GLVERTEXATTRIB1FVARB].func) +#define glVertexAttrib1fvNV ((PFNGLVERTEXATTRIB1FVNVPROC)gl_addr[GLVERTEXATTRIB1FVNV].func) +#define glVertexAttrib1hNV ((PFNGLVERTEXATTRIB1HNVPROC)gl_addr[GLVERTEXATTRIB1HNV].func) +#define glVertexAttrib1hvNV ((PFNGLVERTEXATTRIB1HVNVPROC)gl_addr[GLVERTEXATTRIB1HVNV].func) +#define glVertexAttrib1s ((PFNGLVERTEXATTRIB1SPROC)gl_addr[GLVERTEXATTRIB1S].func) +#define glVertexAttrib1sARB ((PFNGLVERTEXATTRIB1SARBPROC)gl_addr[GLVERTEXATTRIB1SARB].func) +#define glVertexAttrib1sNV ((PFNGLVERTEXATTRIB1SNVPROC)gl_addr[GLVERTEXATTRIB1SNV].func) +#define glVertexAttrib1sv ((PFNGLVERTEXATTRIB1SVPROC)gl_addr[GLVERTEXATTRIB1SV].func) +#define glVertexAttrib1svARB ((PFNGLVERTEXATTRIB1SVARBPROC)gl_addr[GLVERTEXATTRIB1SVARB].func) +#define glVertexAttrib1svNV ((PFNGLVERTEXATTRIB1SVNVPROC)gl_addr[GLVERTEXATTRIB1SVNV].func) +#define glVertexAttrib2d ((PFNGLVERTEXATTRIB2DPROC)gl_addr[GLVERTEXATTRIB2D].func) +#define glVertexAttrib2dARB ((PFNGLVERTEXATTRIB2DARBPROC)gl_addr[GLVERTEXATTRIB2DARB].func) +#define glVertexAttrib2dNV ((PFNGLVERTEXATTRIB2DNVPROC)gl_addr[GLVERTEXATTRIB2DNV].func) +#define glVertexAttrib2dv ((PFNGLVERTEXATTRIB2DVPROC)gl_addr[GLVERTEXATTRIB2DV].func) +#define glVertexAttrib2dvARB ((PFNGLVERTEXATTRIB2DVARBPROC)gl_addr[GLVERTEXATTRIB2DVARB].func) +#define glVertexAttrib2dvNV ((PFNGLVERTEXATTRIB2DVNVPROC)gl_addr[GLVERTEXATTRIB2DVNV].func) +#define glVertexAttrib2f ((PFNGLVERTEXATTRIB2FPROC)gl_addr[GLVERTEXATTRIB2F].func) +#define glVertexAttrib2fARB ((PFNGLVERTEXATTRIB2FARBPROC)gl_addr[GLVERTEXATTRIB2FARB].func) +#define glVertexAttrib2fNV ((PFNGLVERTEXATTRIB2FNVPROC)gl_addr[GLVERTEXATTRIB2FNV].func) +#define glVertexAttrib2fv ((PFNGLVERTEXATTRIB2FVPROC)gl_addr[GLVERTEXATTRIB2FV].func) +#define glVertexAttrib2fvARB ((PFNGLVERTEXATTRIB2FVARBPROC)gl_addr[GLVERTEXATTRIB2FVARB].func) +#define glVertexAttrib2fvNV ((PFNGLVERTEXATTRIB2FVNVPROC)gl_addr[GLVERTEXATTRIB2FVNV].func) +#define glVertexAttrib2hNV ((PFNGLVERTEXATTRIB2HNVPROC)gl_addr[GLVERTEXATTRIB2HNV].func) +#define glVertexAttrib2hvNV ((PFNGLVERTEXATTRIB2HVNVPROC)gl_addr[GLVERTEXATTRIB2HVNV].func) +#define glVertexAttrib2s ((PFNGLVERTEXATTRIB2SPROC)gl_addr[GLVERTEXATTRIB2S].func) +#define glVertexAttrib2sARB ((PFNGLVERTEXATTRIB2SARBPROC)gl_addr[GLVERTEXATTRIB2SARB].func) +#define glVertexAttrib2sNV ((PFNGLVERTEXATTRIB2SNVPROC)gl_addr[GLVERTEXATTRIB2SNV].func) +#define glVertexAttrib2sv ((PFNGLVERTEXATTRIB2SVPROC)gl_addr[GLVERTEXATTRIB2SV].func) +#define glVertexAttrib2svARB ((PFNGLVERTEXATTRIB2SVARBPROC)gl_addr[GLVERTEXATTRIB2SVARB].func) +#define glVertexAttrib2svNV ((PFNGLVERTEXATTRIB2SVNVPROC)gl_addr[GLVERTEXATTRIB2SVNV].func) +#define glVertexAttrib3d ((PFNGLVERTEXATTRIB3DPROC)gl_addr[GLVERTEXATTRIB3D].func) +#define glVertexAttrib3dARB ((PFNGLVERTEXATTRIB3DARBPROC)gl_addr[GLVERTEXATTRIB3DARB].func) +#define glVertexAttrib3dNV ((PFNGLVERTEXATTRIB3DNVPROC)gl_addr[GLVERTEXATTRIB3DNV].func) +#define glVertexAttrib3dv ((PFNGLVERTEXATTRIB3DVPROC)gl_addr[GLVERTEXATTRIB3DV].func) +#define glVertexAttrib3dvARB ((PFNGLVERTEXATTRIB3DVARBPROC)gl_addr[GLVERTEXATTRIB3DVARB].func) +#define glVertexAttrib3dvNV ((PFNGLVERTEXATTRIB3DVNVPROC)gl_addr[GLVERTEXATTRIB3DVNV].func) +#define glVertexAttrib3f ((PFNGLVERTEXATTRIB3FPROC)gl_addr[GLVERTEXATTRIB3F].func) +#define glVertexAttrib3fARB ((PFNGLVERTEXATTRIB3FARBPROC)gl_addr[GLVERTEXATTRIB3FARB].func) +#define glVertexAttrib3fNV ((PFNGLVERTEXATTRIB3FNVPROC)gl_addr[GLVERTEXATTRIB3FNV].func) +#define glVertexAttrib3fv ((PFNGLVERTEXATTRIB3FVPROC)gl_addr[GLVERTEXATTRIB3FV].func) +#define glVertexAttrib3fvARB ((PFNGLVERTEXATTRIB3FVARBPROC)gl_addr[GLVERTEXATTRIB3FVARB].func) +#define glVertexAttrib3fvNV ((PFNGLVERTEXATTRIB3FVNVPROC)gl_addr[GLVERTEXATTRIB3FVNV].func) +#define glVertexAttrib3hNV ((PFNGLVERTEXATTRIB3HNVPROC)gl_addr[GLVERTEXATTRIB3HNV].func) +#define glVertexAttrib3hvNV ((PFNGLVERTEXATTRIB3HVNVPROC)gl_addr[GLVERTEXATTRIB3HVNV].func) +#define glVertexAttrib3s ((PFNGLVERTEXATTRIB3SPROC)gl_addr[GLVERTEXATTRIB3S].func) +#define glVertexAttrib3sARB ((PFNGLVERTEXATTRIB3SARBPROC)gl_addr[GLVERTEXATTRIB3SARB].func) +#define glVertexAttrib3sNV ((PFNGLVERTEXATTRIB3SNVPROC)gl_addr[GLVERTEXATTRIB3SNV].func) +#define glVertexAttrib3sv ((PFNGLVERTEXATTRIB3SVPROC)gl_addr[GLVERTEXATTRIB3SV].func) +#define glVertexAttrib3svARB ((PFNGLVERTEXATTRIB3SVARBPROC)gl_addr[GLVERTEXATTRIB3SVARB].func) +#define glVertexAttrib3svNV ((PFNGLVERTEXATTRIB3SVNVPROC)gl_addr[GLVERTEXATTRIB3SVNV].func) +#define glVertexAttrib4bv ((PFNGLVERTEXATTRIB4BVPROC)gl_addr[GLVERTEXATTRIB4BV].func) +#define glVertexAttrib4bvARB ((PFNGLVERTEXATTRIB4BVARBPROC)gl_addr[GLVERTEXATTRIB4BVARB].func) +#define glVertexAttrib4d ((PFNGLVERTEXATTRIB4DPROC)gl_addr[GLVERTEXATTRIB4D].func) +#define glVertexAttrib4dARB ((PFNGLVERTEXATTRIB4DARBPROC)gl_addr[GLVERTEXATTRIB4DARB].func) +#define glVertexAttrib4dNV ((PFNGLVERTEXATTRIB4DNVPROC)gl_addr[GLVERTEXATTRIB4DNV].func) +#define glVertexAttrib4dv ((PFNGLVERTEXATTRIB4DVPROC)gl_addr[GLVERTEXATTRIB4DV].func) +#define glVertexAttrib4dvARB ((PFNGLVERTEXATTRIB4DVARBPROC)gl_addr[GLVERTEXATTRIB4DVARB].func) +#define glVertexAttrib4dvNV ((PFNGLVERTEXATTRIB4DVNVPROC)gl_addr[GLVERTEXATTRIB4DVNV].func) +#define glVertexAttrib4f ((PFNGLVERTEXATTRIB4FPROC)gl_addr[GLVERTEXATTRIB4F].func) +#define glVertexAttrib4fARB ((PFNGLVERTEXATTRIB4FARBPROC)gl_addr[GLVERTEXATTRIB4FARB].func) +#define glVertexAttrib4fNV ((PFNGLVERTEXATTRIB4FNVPROC)gl_addr[GLVERTEXATTRIB4FNV].func) +#define glVertexAttrib4fv ((PFNGLVERTEXATTRIB4FVPROC)gl_addr[GLVERTEXATTRIB4FV].func) +#define glVertexAttrib4fvARB ((PFNGLVERTEXATTRIB4FVARBPROC)gl_addr[GLVERTEXATTRIB4FVARB].func) +#define glVertexAttrib4fvNV ((PFNGLVERTEXATTRIB4FVNVPROC)gl_addr[GLVERTEXATTRIB4FVNV].func) +#define glVertexAttrib4hNV ((PFNGLVERTEXATTRIB4HNVPROC)gl_addr[GLVERTEXATTRIB4HNV].func) +#define glVertexAttrib4hvNV ((PFNGLVERTEXATTRIB4HVNVPROC)gl_addr[GLVERTEXATTRIB4HVNV].func) +#define glVertexAttrib4iv ((PFNGLVERTEXATTRIB4IVPROC)gl_addr[GLVERTEXATTRIB4IV].func) +#define glVertexAttrib4ivARB ((PFNGLVERTEXATTRIB4IVARBPROC)gl_addr[GLVERTEXATTRIB4IVARB].func) +#define glVertexAttrib4Nbv ((PFNGLVERTEXATTRIB4NBVPROC)gl_addr[GLVERTEXATTRIB4NBV].func) +#define glVertexAttrib4NbvARB ((PFNGLVERTEXATTRIB4NBVARBPROC)gl_addr[GLVERTEXATTRIB4NBVARB].func) +#define glVertexAttrib4Niv ((PFNGLVERTEXATTRIB4NIVPROC)gl_addr[GLVERTEXATTRIB4NIV].func) +#define glVertexAttrib4NivARB ((PFNGLVERTEXATTRIB4NIVARBPROC)gl_addr[GLVERTEXATTRIB4NIVARB].func) +#define glVertexAttrib4Nsv ((PFNGLVERTEXATTRIB4NSVPROC)gl_addr[GLVERTEXATTRIB4NSV].func) +#define glVertexAttrib4NsvARB ((PFNGLVERTEXATTRIB4NSVARBPROC)gl_addr[GLVERTEXATTRIB4NSVARB].func) +#define glVertexAttrib4Nub ((PFNGLVERTEXATTRIB4NUBPROC)gl_addr[GLVERTEXATTRIB4NUB].func) +#define glVertexAttrib4NubARB ((PFNGLVERTEXATTRIB4NUBARBPROC)gl_addr[GLVERTEXATTRIB4NUBARB].func) +#define glVertexAttrib4Nubv ((PFNGLVERTEXATTRIB4NUBVPROC)gl_addr[GLVERTEXATTRIB4NUBV].func) +#define glVertexAttrib4NubvARB ((PFNGLVERTEXATTRIB4NUBVARBPROC)gl_addr[GLVERTEXATTRIB4NUBVARB].func) +#define glVertexAttrib4Nuiv ((PFNGLVERTEXATTRIB4NUIVPROC)gl_addr[GLVERTEXATTRIB4NUIV].func) +#define glVertexAttrib4NuivARB ((PFNGLVERTEXATTRIB4NUIVARBPROC)gl_addr[GLVERTEXATTRIB4NUIVARB].func) +#define glVertexAttrib4Nusv ((PFNGLVERTEXATTRIB4NUSVPROC)gl_addr[GLVERTEXATTRIB4NUSV].func) +#define glVertexAttrib4NusvARB ((PFNGLVERTEXATTRIB4NUSVARBPROC)gl_addr[GLVERTEXATTRIB4NUSVARB].func) +#define glVertexAttrib4s ((PFNGLVERTEXATTRIB4SPROC)gl_addr[GLVERTEXATTRIB4S].func) +#define glVertexAttrib4sARB ((PFNGLVERTEXATTRIB4SARBPROC)gl_addr[GLVERTEXATTRIB4SARB].func) +#define glVertexAttrib4sNV ((PFNGLVERTEXATTRIB4SNVPROC)gl_addr[GLVERTEXATTRIB4SNV].func) +#define glVertexAttrib4sv ((PFNGLVERTEXATTRIB4SVPROC)gl_addr[GLVERTEXATTRIB4SV].func) +#define glVertexAttrib4svARB ((PFNGLVERTEXATTRIB4SVARBPROC)gl_addr[GLVERTEXATTRIB4SVARB].func) +#define glVertexAttrib4svNV ((PFNGLVERTEXATTRIB4SVNVPROC)gl_addr[GLVERTEXATTRIB4SVNV].func) +#define glVertexAttrib4ubNV ((PFNGLVERTEXATTRIB4UBNVPROC)gl_addr[GLVERTEXATTRIB4UBNV].func) +#define glVertexAttrib4ubv ((PFNGLVERTEXATTRIB4UBVPROC)gl_addr[GLVERTEXATTRIB4UBV].func) +#define glVertexAttrib4ubvARB ((PFNGLVERTEXATTRIB4UBVARBPROC)gl_addr[GLVERTEXATTRIB4UBVARB].func) +#define glVertexAttrib4ubvNV ((PFNGLVERTEXATTRIB4UBVNVPROC)gl_addr[GLVERTEXATTRIB4UBVNV].func) +#define glVertexAttrib4uiv ((PFNGLVERTEXATTRIB4UIVPROC)gl_addr[GLVERTEXATTRIB4UIV].func) +#define glVertexAttrib4uivARB ((PFNGLVERTEXATTRIB4UIVARBPROC)gl_addr[GLVERTEXATTRIB4UIVARB].func) +#define glVertexAttrib4usv ((PFNGLVERTEXATTRIB4USVPROC)gl_addr[GLVERTEXATTRIB4USV].func) +#define glVertexAttrib4usvARB ((PFNGLVERTEXATTRIB4USVARBPROC)gl_addr[GLVERTEXATTRIB4USVARB].func) +#define glVertexAttribI1i ((PFNGLVERTEXATTRIBI1IPROC)gl_addr[GLVERTEXATTRIBI1I].func) +#define glVertexAttribI1iEXT ((PFNGLVERTEXATTRIBI1IEXTPROC)gl_addr[GLVERTEXATTRIBI1IEXT].func) +#define glVertexAttribI1iv ((PFNGLVERTEXATTRIBI1IVPROC)gl_addr[GLVERTEXATTRIBI1IV].func) +#define glVertexAttribI1ivEXT ((PFNGLVERTEXATTRIBI1IVEXTPROC)gl_addr[GLVERTEXATTRIBI1IVEXT].func) +#define glVertexAttribI1ui ((PFNGLVERTEXATTRIBI1UIPROC)gl_addr[GLVERTEXATTRIBI1UI].func) +#define glVertexAttribI1uiEXT ((PFNGLVERTEXATTRIBI1UIEXTPROC)gl_addr[GLVERTEXATTRIBI1UIEXT].func) +#define glVertexAttribI1uiv ((PFNGLVERTEXATTRIBI1UIVPROC)gl_addr[GLVERTEXATTRIBI1UIV].func) +#define glVertexAttribI1uivEXT ((PFNGLVERTEXATTRIBI1UIVEXTPROC)gl_addr[GLVERTEXATTRIBI1UIVEXT].func) +#define glVertexAttribI2i ((PFNGLVERTEXATTRIBI2IPROC)gl_addr[GLVERTEXATTRIBI2I].func) +#define glVertexAttribI2iEXT ((PFNGLVERTEXATTRIBI2IEXTPROC)gl_addr[GLVERTEXATTRIBI2IEXT].func) +#define glVertexAttribI2iv ((PFNGLVERTEXATTRIBI2IVPROC)gl_addr[GLVERTEXATTRIBI2IV].func) +#define glVertexAttribI2ivEXT ((PFNGLVERTEXATTRIBI2IVEXTPROC)gl_addr[GLVERTEXATTRIBI2IVEXT].func) +#define glVertexAttribI2ui ((PFNGLVERTEXATTRIBI2UIPROC)gl_addr[GLVERTEXATTRIBI2UI].func) +#define glVertexAttribI2uiEXT ((PFNGLVERTEXATTRIBI2UIEXTPROC)gl_addr[GLVERTEXATTRIBI2UIEXT].func) +#define glVertexAttribI2uiv ((PFNGLVERTEXATTRIBI2UIVPROC)gl_addr[GLVERTEXATTRIBI2UIV].func) +#define glVertexAttribI2uivEXT ((PFNGLVERTEXATTRIBI2UIVEXTPROC)gl_addr[GLVERTEXATTRIBI2UIVEXT].func) +#define glVertexAttribI3i ((PFNGLVERTEXATTRIBI3IPROC)gl_addr[GLVERTEXATTRIBI3I].func) +#define glVertexAttribI3iEXT ((PFNGLVERTEXATTRIBI3IEXTPROC)gl_addr[GLVERTEXATTRIBI3IEXT].func) +#define glVertexAttribI3iv ((PFNGLVERTEXATTRIBI3IVPROC)gl_addr[GLVERTEXATTRIBI3IV].func) +#define glVertexAttribI3ivEXT ((PFNGLVERTEXATTRIBI3IVEXTPROC)gl_addr[GLVERTEXATTRIBI3IVEXT].func) +#define glVertexAttribI3ui ((PFNGLVERTEXATTRIBI3UIPROC)gl_addr[GLVERTEXATTRIBI3UI].func) +#define glVertexAttribI3uiEXT ((PFNGLVERTEXATTRIBI3UIEXTPROC)gl_addr[GLVERTEXATTRIBI3UIEXT].func) +#define glVertexAttribI3uiv ((PFNGLVERTEXATTRIBI3UIVPROC)gl_addr[GLVERTEXATTRIBI3UIV].func) +#define glVertexAttribI3uivEXT ((PFNGLVERTEXATTRIBI3UIVEXTPROC)gl_addr[GLVERTEXATTRIBI3UIVEXT].func) +#define glVertexAttribI4bv ((PFNGLVERTEXATTRIBI4BVPROC)gl_addr[GLVERTEXATTRIBI4BV].func) +#define glVertexAttribI4bvEXT ((PFNGLVERTEXATTRIBI4BVEXTPROC)gl_addr[GLVERTEXATTRIBI4BVEXT].func) +#define glVertexAttribI4i ((PFNGLVERTEXATTRIBI4IPROC)gl_addr[GLVERTEXATTRIBI4I].func) +#define glVertexAttribI4iEXT ((PFNGLVERTEXATTRIBI4IEXTPROC)gl_addr[GLVERTEXATTRIBI4IEXT].func) +#define glVertexAttribI4iv ((PFNGLVERTEXATTRIBI4IVPROC)gl_addr[GLVERTEXATTRIBI4IV].func) +#define glVertexAttribI4ivEXT ((PFNGLVERTEXATTRIBI4IVEXTPROC)gl_addr[GLVERTEXATTRIBI4IVEXT].func) +#define glVertexAttribI4sv ((PFNGLVERTEXATTRIBI4SVPROC)gl_addr[GLVERTEXATTRIBI4SV].func) +#define glVertexAttribI4svEXT ((PFNGLVERTEXATTRIBI4SVEXTPROC)gl_addr[GLVERTEXATTRIBI4SVEXT].func) +#define glVertexAttribI4ubv ((PFNGLVERTEXATTRIBI4UBVPROC)gl_addr[GLVERTEXATTRIBI4UBV].func) +#define glVertexAttribI4ubvEXT ((PFNGLVERTEXATTRIBI4UBVEXTPROC)gl_addr[GLVERTEXATTRIBI4UBVEXT].func) +#define glVertexAttribI4ui ((PFNGLVERTEXATTRIBI4UIPROC)gl_addr[GLVERTEXATTRIBI4UI].func) +#define glVertexAttribI4uiEXT ((PFNGLVERTEXATTRIBI4UIEXTPROC)gl_addr[GLVERTEXATTRIBI4UIEXT].func) +#define glVertexAttribI4uiv ((PFNGLVERTEXATTRIBI4UIVPROC)gl_addr[GLVERTEXATTRIBI4UIV].func) +#define glVertexAttribI4uivEXT ((PFNGLVERTEXATTRIBI4UIVEXTPROC)gl_addr[GLVERTEXATTRIBI4UIVEXT].func) +#define glVertexAttribI4usv ((PFNGLVERTEXATTRIBI4USVPROC)gl_addr[GLVERTEXATTRIBI4USV].func) +#define glVertexAttribI4usvEXT ((PFNGLVERTEXATTRIBI4USVEXTPROC)gl_addr[GLVERTEXATTRIBI4USVEXT].func) +#define glVertexAttribIPointer ((PFNGLVERTEXATTRIBIPOINTERPROC)gl_addr[GLVERTEXATTRIBIPOINTER].func) +#define glVertexAttribIPointerEXT ((PFNGLVERTEXATTRIBIPOINTEREXTPROC)gl_addr[GLVERTEXATTRIBIPOINTEREXT].func) +#define glVertexAttribPointer ((PFNGLVERTEXATTRIBPOINTERPROC)gl_addr[GLVERTEXATTRIBPOINTER].func) +#define glVertexAttribPointerNV ((PFNGLVERTEXATTRIBPOINTERNVPROC)gl_addr[GLVERTEXATTRIBPOINTERNV].func) +#define glVertexAttribs1dvNV ((PFNGLVERTEXATTRIBS1DVNVPROC)gl_addr[GLVERTEXATTRIBS1DVNV].func) +#define glVertexAttribs1fvNV ((PFNGLVERTEXATTRIBS1FVNVPROC)gl_addr[GLVERTEXATTRIBS1FVNV].func) +#define glVertexAttribs1hvNV ((PFNGLVERTEXATTRIBS1HVNVPROC)gl_addr[GLVERTEXATTRIBS1HVNV].func) +#define glVertexAttribs1svNV ((PFNGLVERTEXATTRIBS1SVNVPROC)gl_addr[GLVERTEXATTRIBS1SVNV].func) +#define glVertexAttribs2dvNV ((PFNGLVERTEXATTRIBS2DVNVPROC)gl_addr[GLVERTEXATTRIBS2DVNV].func) +#define glVertexAttribs2fvNV ((PFNGLVERTEXATTRIBS2FVNVPROC)gl_addr[GLVERTEXATTRIBS2FVNV].func) +#define glVertexAttribs2hvNV ((PFNGLVERTEXATTRIBS2HVNVPROC)gl_addr[GLVERTEXATTRIBS2HVNV].func) +#define glVertexAttribs2svNV ((PFNGLVERTEXATTRIBS2SVNVPROC)gl_addr[GLVERTEXATTRIBS2SVNV].func) +#define glVertexAttribs3dvNV ((PFNGLVERTEXATTRIBS3DVNVPROC)gl_addr[GLVERTEXATTRIBS3DVNV].func) +#define glVertexAttribs3fvNV ((PFNGLVERTEXATTRIBS3FVNVPROC)gl_addr[GLVERTEXATTRIBS3FVNV].func) +#define glVertexAttribs3hvNV ((PFNGLVERTEXATTRIBS3HVNVPROC)gl_addr[GLVERTEXATTRIBS3HVNV].func) +#define glVertexAttribs3svNV ((PFNGLVERTEXATTRIBS3SVNVPROC)gl_addr[GLVERTEXATTRIBS3SVNV].func) +#define glVertexAttribs4dvNV ((PFNGLVERTEXATTRIBS4DVNVPROC)gl_addr[GLVERTEXATTRIBS4DVNV].func) +#define glVertexAttribs4fvNV ((PFNGLVERTEXATTRIBS4FVNVPROC)gl_addr[GLVERTEXATTRIBS4FVNV].func) +#define glVertexAttribs4hvNV ((PFNGLVERTEXATTRIBS4HVNVPROC)gl_addr[GLVERTEXATTRIBS4HVNV].func) +#define glVertexAttribs4svNV ((PFNGLVERTEXATTRIBS4SVNVPROC)gl_addr[GLVERTEXATTRIBS4SVNV].func) +#define glVertexAttribs4ubvNV ((PFNGLVERTEXATTRIBS4UBVNVPROC)gl_addr[GLVERTEXATTRIBS4UBVNV].func) +#define glVertexPointerEXT ((PFNGLVERTEXPOINTEREXTPROC)gl_addr[GLVERTEXPOINTEREXT].func) +#define glWindowPos2d ((PFNGLWINDOWPOS2DPROC)gl_addr[GLWINDOWPOS2D].func) +#define glWindowPos2dARB ((PFNGLWINDOWPOS2DARBPROC)gl_addr[GLWINDOWPOS2DARB].func) +#define glWindowPos2dv ((PFNGLWINDOWPOS2DVPROC)gl_addr[GLWINDOWPOS2DV].func) +#define glWindowPos2dvARB ((PFNGLWINDOWPOS2DVARBPROC)gl_addr[GLWINDOWPOS2DVARB].func) +#define glWindowPos2f ((PFNGLWINDOWPOS2FPROC)gl_addr[GLWINDOWPOS2F].func) +#define glWindowPos2fARB ((PFNGLWINDOWPOS2FARBPROC)gl_addr[GLWINDOWPOS2FARB].func) +#define glWindowPos2fv ((PFNGLWINDOWPOS2FVPROC)gl_addr[GLWINDOWPOS2FV].func) +#define glWindowPos2fvARB ((PFNGLWINDOWPOS2FVARBPROC)gl_addr[GLWINDOWPOS2FVARB].func) +#define glWindowPos2i ((PFNGLWINDOWPOS2IPROC)gl_addr[GLWINDOWPOS2I].func) +#define glWindowPos2iARB ((PFNGLWINDOWPOS2IARBPROC)gl_addr[GLWINDOWPOS2IARB].func) +#define glWindowPos2iv ((PFNGLWINDOWPOS2IVPROC)gl_addr[GLWINDOWPOS2IV].func) +#define glWindowPos2ivARB ((PFNGLWINDOWPOS2IVARBPROC)gl_addr[GLWINDOWPOS2IVARB].func) +#define glWindowPos2s ((PFNGLWINDOWPOS2SPROC)gl_addr[GLWINDOWPOS2S].func) +#define glWindowPos2sARB ((PFNGLWINDOWPOS2SARBPROC)gl_addr[GLWINDOWPOS2SARB].func) +#define glWindowPos2sv ((PFNGLWINDOWPOS2SVPROC)gl_addr[GLWINDOWPOS2SV].func) +#define glWindowPos2svARB ((PFNGLWINDOWPOS2SVARBPROC)gl_addr[GLWINDOWPOS2SVARB].func) +#define glWindowPos3d ((PFNGLWINDOWPOS3DPROC)gl_addr[GLWINDOWPOS3D].func) +#define glWindowPos3dARB ((PFNGLWINDOWPOS3DARBPROC)gl_addr[GLWINDOWPOS3DARB].func) +#define glWindowPos3dv ((PFNGLWINDOWPOS3DVPROC)gl_addr[GLWINDOWPOS3DV].func) +#define glWindowPos3dvARB ((PFNGLWINDOWPOS3DVARBPROC)gl_addr[GLWINDOWPOS3DVARB].func) +#define glWindowPos3f ((PFNGLWINDOWPOS3FPROC)gl_addr[GLWINDOWPOS3F].func) +#define glWindowPos3fARB ((PFNGLWINDOWPOS3FARBPROC)gl_addr[GLWINDOWPOS3FARB].func) +#define glWindowPos3fv ((PFNGLWINDOWPOS3FVPROC)gl_addr[GLWINDOWPOS3FV].func) +#define glWindowPos3fvARB ((PFNGLWINDOWPOS3FVARBPROC)gl_addr[GLWINDOWPOS3FVARB].func) +#define glWindowPos3i ((PFNGLWINDOWPOS3IPROC)gl_addr[GLWINDOWPOS3I].func) +#define glWindowPos3iARB ((PFNGLWINDOWPOS3IARBPROC)gl_addr[GLWINDOWPOS3IARB].func) +#define glWindowPos3iv ((PFNGLWINDOWPOS3IVPROC)gl_addr[GLWINDOWPOS3IV].func) +#define glWindowPos3ivARB ((PFNGLWINDOWPOS3IVARBPROC)gl_addr[GLWINDOWPOS3IVARB].func) +#define glWindowPos3s ((PFNGLWINDOWPOS3SPROC)gl_addr[GLWINDOWPOS3S].func) +#define glWindowPos3sARB ((PFNGLWINDOWPOS3SARBPROC)gl_addr[GLWINDOWPOS3SARB].func) +#define glWindowPos3sv ((PFNGLWINDOWPOS3SVPROC)gl_addr[GLWINDOWPOS3SV].func) +#define glWindowPos3svARB ((PFNGLWINDOWPOS3SVARBPROC)gl_addr[GLWINDOWPOS3SVARB].func) +#define wglAllocateMemoryNV ((PFNWGLALLOCATEMEMORYNVPROC)gl_addr[WGLALLOCATEMEMORYNV].func) +#define wglBindSwapBarrierNV ((PFNWGLBINDSWAPBARRIERNVPROC)gl_addr[WGLBINDSWAPBARRIERNV].func) +#define wglBindTexImageARB ((PFNWGLBINDTEXIMAGEARBPROC)gl_addr[WGLBINDTEXIMAGEARB].func) +#define wglBindVideoImageNV ((PFNWGLBINDVIDEOIMAGENVPROC)gl_addr[WGLBINDVIDEOIMAGENV].func) +#define wglChoosePixelFormatARB ((PFNWGLCHOOSEPIXELFORMATARBPROC)gl_addr[WGLCHOOSEPIXELFORMATARB].func) +#define wglCreateBufferRegionARB ((PFNWGLCREATEBUFFERREGIONARBPROC)gl_addr[WGLCREATEBUFFERREGIONARB].func) +#define wglCreateContextAttribsARB ((PFNWGLCREATECONTEXTATTRIBSARBPROC)gl_addr[WGLCREATECONTEXTATTRIBSARB].func) +#define wglCreatePbufferARB ((PFNWGLCREATEPBUFFERARBPROC)gl_addr[WGLCREATEPBUFFERARB].func) +#define wglDeleteBufferRegionARB ((PFNWGLDELETEBUFFERREGIONARBPROC)gl_addr[WGLDELETEBUFFERREGIONARB].func) +#define wglDestroyPbufferARB ((PFNWGLDESTROYPBUFFERARBPROC)gl_addr[WGLDESTROYPBUFFERARB].func) +#define wglDXCloseDeviceNV ((PFNWGLDXCLOSEDEVICENVPROC)gl_addr[WGLDXCLOSEDEVICENV].func) +#define wglDXLockObjectsNV ((PFNWGLDXLOCKOBJECTSNVPROC)gl_addr[WGLDXLOCKOBJECTSNV].func) +#define wglDXOpenDeviceNV ((PFNWGLDXOPENDEVICENVPROC)gl_addr[WGLDXOPENDEVICENV].func) +#define wglDXRegisterObjectNV ((PFNWGLDXREGISTEROBJECTNVPROC)gl_addr[WGLDXREGISTEROBJECTNV].func) +#define wglDXSetResourceShareHandleNV ((PFNWGLDXSETRESOURCESHAREHANDLENVPROC)gl_addr[WGLDXSETRESOURCESHAREHANDLENV].func) +#define wglDXUnlockObjectsNV ((PFNWGLDXUNLOCKOBJECTSNVPROC)gl_addr[WGLDXUNLOCKOBJECTSNV].func) +#define wglDXUnregisterObjectNV ((PFNWGLDXUNREGISTEROBJECTNVPROC)gl_addr[WGLDXUNREGISTEROBJECTNV].func) +#define wglFreeMemoryNV ((PFNWGLFREEMEMORYNVPROC)gl_addr[WGLFREEMEMORYNV].func) +#define wglGetCurrentContext ((PFNWGLGETCURRENTCONTEXTPROC)gl_addr[WGLGETCURRENTCONTEXT].func) +#define wglGetCurrentReadDCARB ((PFNWGLGETCURRENTREADDCARBPROC)gl_addr[WGLGETCURRENTREADDCARB].func) +#define wglGetExtensionsStringARB ((PFNWGLGETEXTENSIONSSTRINGARBPROC)gl_addr[WGLGETEXTENSIONSSTRINGARB].func) +#define wglGetExtensionsStringEXT ((PFNWGLGETEXTENSIONSSTRINGEXTPROC)gl_addr[WGLGETEXTENSIONSSTRINGEXT].func) +#define wglGetPbufferDCARB ((PFNWGLGETPBUFFERDCARBPROC)gl_addr[WGLGETPBUFFERDCARB].func) +#define wglGetPixelFormatAttribfvARB ((PFNWGLGETPIXELFORMATATTRIBFVARBPROC)gl_addr[WGLGETPIXELFORMATATTRIBFVARB].func) +#define wglGetPixelFormatAttribivARB ((PFNWGLGETPIXELFORMATATTRIBIVARBPROC)gl_addr[WGLGETPIXELFORMATATTRIBIVARB].func) +#define wglGetProcAddress ((PFNWGLGETPROCADDRESSPROC)gl_addr[WGLGETPROCADDRESS].func) +#define wglGetSwapIntervalEXT ((PFNWGLGETSWAPINTERVALEXTPROC)gl_addr[WGLGETSWAPINTERVALEXT].func) +#define wglGetVideoDeviceNV ((PFNWGLGETVIDEODEVICENVPROC)gl_addr[WGLGETVIDEODEVICENV].func) +#define wglGetVideoInfoNV ((PFNWGLGETVIDEOINFONVPROC)gl_addr[WGLGETVIDEOINFONV].func) +#define wglJoinSwapGroupNV ((PFNWGLJOINSWAPGROUPNVPROC)gl_addr[WGLJOINSWAPGROUPNV].func) +#define wglMakeContextCurrentARB ((PFNWGLMAKECONTEXTCURRENTARBPROC)gl_addr[WGLMAKECONTEXTCURRENTARB].func) +#define wglQueryFrameCountNV ((PFNWGLQUERYFRAMECOUNTNVPROC)gl_addr[WGLQUERYFRAMECOUNTNV].func) +#define wglQueryMaxSwapGroupsNV ((PFNWGLQUERYMAXSWAPGROUPSNVPROC)gl_addr[WGLQUERYMAXSWAPGROUPSNV].func) +#define wglQueryPbufferARB ((PFNWGLQUERYPBUFFERARBPROC)gl_addr[WGLQUERYPBUFFERARB].func) +#define wglQuerySwapGroupNV ((PFNWGLQUERYSWAPGROUPNVPROC)gl_addr[WGLQUERYSWAPGROUPNV].func) +#define wglReleasePbufferDCARB ((PFNWGLRELEASEPBUFFERDCARBPROC)gl_addr[WGLRELEASEPBUFFERDCARB].func) +#define wglReleaseTexImageARB ((PFNWGLRELEASETEXIMAGEARBPROC)gl_addr[WGLRELEASETEXIMAGEARB].func) +#define wglReleaseVideoDeviceNV ((PFNWGLRELEASEVIDEODEVICENVPROC)gl_addr[WGLRELEASEVIDEODEVICENV].func) +#define wglReleaseVideoImageNV ((PFNWGLRELEASEVIDEOIMAGENVPROC)gl_addr[WGLRELEASEVIDEOIMAGENV].func) +#define wglResetFrameCountNV ((PFNWGLRESETFRAMECOUNTNVPROC)gl_addr[WGLRESETFRAMECOUNTNV].func) +#define wglRestoreBufferRegionARB ((PFNWGLRESTOREBUFFERREGIONARBPROC)gl_addr[WGLRESTOREBUFFERREGIONARB].func) +#define wglSaveBufferRegionARB ((PFNWGLSAVEBUFFERREGIONARBPROC)gl_addr[WGLSAVEBUFFERREGIONARB].func) +#define wglSendPbufferToVideoNV ((PFNWGLSENDPBUFFERTOVIDEONVPROC)gl_addr[WGLSENDPBUFFERTOVIDEONV].func) +#define wglSetPbufferAttribARB ((PFNWGLSETPBUFFERATTRIBARBPROC)gl_addr[WGLSETPBUFFERATTRIBARB].func) +#define wglSwapIntervalEXT ((PFNWGLSWAPINTERVALEXTPROC)gl_addr[WGLSWAPINTERVALEXT].func) + +#define glFinishGLUT ((PFNGLFINISHGLUTPROC)gl_addr_glut[GLFINISHGLUT].func) +#define glViewportGLUT ((PFNGLVIEWPORTGLUTPROC)gl_addr_glut[GLVIEWPORTGLUT].func) +#define wglDeleteContextGLUT ((PFNWGLDELETECONTEXTGLUTPROC)gl_addr_glut[WGLDELETECONTEXTGLUT].func) +#define wglGetCurrentContextGLUT ((PFNWGLGETCURRENTCONTEXTGLUTPROC)gl_addr_glut[WGLGETCURRENTCONTEXTGLUT].func) +#define wglGetCurrentDCGLUT ((PFNWGLGETCURRENTDCGLUTPROC)gl_addr_glut[WGLGETCURRENTDCGLUT].func) +#define wglGetProcAddressGLUT ((PFNWGLGETPROCADDRESSGLUTPROC)gl_addr_glut[WGLGETPROCADDRESSGLUT].func) +#define wglMakeCurrentGLUT ((PFNWGLMAKECURRENTGLUTPROC)gl_addr_glut[WGLMAKECURRENTGLUT].func) + +extern bool GL_VERSION_3_3; +extern bool GL_VERSION_4_0; +extern bool GL_VERSION_4_1; +extern bool GL_VERSION_4_2; +extern bool GL_VERSION_4_3; +extern bool GL_VERSION_4_4; +extern bool GL_VERSION_4_5; +extern bool GL_VERSION_4_6; + +extern void wrap_patch(); + +extern void GLAPIENTRY glAlphaFuncDLL(GLenum func, GLfloat ref); +extern void GLAPIENTRY glBeginDLL(GLenum mode); +extern void GLAPIENTRY glBindTextureDLL(GLenum target, GLuint texture); +extern void GLAPIENTRY glClearDLL(GLbitfield mask); +extern void GLAPIENTRY glClearColorDLL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +extern void GLAPIENTRY glClearDepthDLL(GLdouble depth); +extern void GLAPIENTRY glClearStencilDLL(GLint s); +extern void GLAPIENTRY glColor3fDLL(GLfloat red, GLfloat green, GLfloat blue); +extern void GLAPIENTRY glColor4fDLL(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +extern void GLAPIENTRY glColor4ubDLL(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +extern void GLAPIENTRY glColor4ubvDLL(GLubyte const * v); +extern void GLAPIENTRY glColorPointerDLL(GLint size, GLenum type, GLsizei stride, const void * pointer); +extern void GLAPIENTRY glCopyTexImage2DDLL(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +extern void GLAPIENTRY glCopyTexSubImage2DDLL(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +extern void GLAPIENTRY glCullFaceDLL(GLenum mode); +extern void GLAPIENTRY glDepthFuncDLL(GLenum func); +extern void GLAPIENTRY glDisableDLL(GLenum cap); +extern void GLAPIENTRY glDisableClientStateDLL(GLenum array); +extern void GLAPIENTRY glDrawArraysDLL(GLenum mode, GLint first, GLsizei count); +extern void GLAPIENTRY glDrawBufferDLL(GLenum buf); +extern void GLAPIENTRY glDrawElementsDLL(GLenum mode, GLsizei count, GLenum type, const void * indices); +extern void GLAPIENTRY glEnableDLL(GLenum cap); +extern void GLAPIENTRY glEnableClientStateDLL(GLenum array); +extern void GLAPIENTRY glEndDLL(); +extern void GLAPIENTRY glFogfDLL(GLenum pname, GLfloat param); +extern void GLAPIENTRY glFogfvDLL(GLenum pname, GLfloat const * params); +extern void GLAPIENTRY glFogiDLL(GLenum pname, GLint param); +extern void GLAPIENTRY glFrontFaceDLL(GLenum mode); +extern void GLAPIENTRY glFrustumDLL(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +extern void GLAPIENTRY glGetBooleanvDLL(GLenum pname, GLboolean * data); +extern GLenum GLAPIENTRY glGetErrorDLL(); +extern void GLAPIENTRY glGetFloatvDLL(GLenum pname, GLfloat * data); +extern void GLAPIENTRY glGetIntegervDLL(GLenum pname, GLint * data); +extern void GLAPIENTRY glGetMaterialfvDLL(GLenum face, GLenum pname, GLfloat * params); +extern void GLAPIENTRY glGetTexImageDLL(GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +extern void GLAPIENTRY glGetTexLevelParameterivDLL(GLenum target, GLint level, GLenum pname, GLint * params); +extern void GLAPIENTRY glGetTexParameterivDLL(GLenum target, GLenum pname, GLint * params); +extern GLboolean GLAPIENTRY glIsEnabledDLL(GLenum cap); +extern void GLAPIENTRY glLightfvDLL(GLenum light, GLenum pname, GLfloat const * params); +extern void GLAPIENTRY glLightModelfvDLL(GLenum pname, GLfloat const * params); +extern void GLAPIENTRY glLineWidthDLL(GLfloat width); +extern void GLAPIENTRY glLoadIdentityDLL(); +extern void GLAPIENTRY glLoadMatrixfDLL(GLfloat const * m); +extern void GLAPIENTRY glMaterialfDLL(GLenum face, GLenum pname, GLfloat param); +extern void GLAPIENTRY glMaterialfvDLL(GLenum face, GLenum pname, GLfloat const * params); +extern void GLAPIENTRY glMatrixModeDLL(GLenum mode); +extern void GLAPIENTRY glMultMatrixdDLL(GLdouble const * m); +extern void GLAPIENTRY glNormal3fDLL(GLfloat nx, GLfloat ny, GLfloat nz); +extern void GLAPIENTRY glNormalPointerDLL(GLenum type, GLsizei stride, const void * pointer); +extern void GLAPIENTRY glOrthoDLL(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +extern void GLAPIENTRY glPixelStoreiDLL(GLenum pname, GLint param); +extern void GLAPIENTRY glPointSizeDLL(GLfloat size); +extern void GLAPIENTRY glPolygonModeDLL(GLenum face, GLenum mode); +extern void GLAPIENTRY glPopAttribDLL(); +extern void GLAPIENTRY glPopClientAttribDLL(); +extern void GLAPIENTRY glPopMatrixDLL(); +extern void GLAPIENTRY glPushAttribDLL(GLbitfield mask); +extern void GLAPIENTRY glPushClientAttribDLL(GLbitfield mask); +extern void GLAPIENTRY glPushMatrixDLL(); +extern void GLAPIENTRY glReadBufferDLL(GLenum src); +extern void GLAPIENTRY glReadPixelsDLL(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); +extern void GLAPIENTRY glRotatefDLL(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glScalefDLL(GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glShadeModelDLL(GLenum mode); +extern void GLAPIENTRY glTexCoord2fDLL(GLfloat s, GLfloat t); +extern void GLAPIENTRY glTexCoordPointerDLL(GLint size, GLenum type, GLsizei stride, const void * pointer); +extern void GLAPIENTRY glTexEnvfDLL(GLenum target, GLenum pname, GLfloat param); +extern void GLAPIENTRY glTexEnviDLL(GLenum target, GLenum pname, GLint param); +extern void GLAPIENTRY glTexImage1DDLL(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); +extern void GLAPIENTRY glTexImage2DDLL(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); +extern void GLAPIENTRY glTexParameterfDLL(GLenum target, GLenum pname, GLfloat param); +extern void GLAPIENTRY glTexParameterfvDLL(GLenum target, GLenum pname, GLfloat const * params); +extern void GLAPIENTRY glTexParameteriDLL(GLenum target, GLenum pname, GLint param); +extern void GLAPIENTRY glTexSubImage2DDLL(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +extern void GLAPIENTRY glTranslatefDLL(GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glVertex3fDLL(GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glVertex3fvDLL(GLfloat const * v); +extern void GLAPIENTRY glVertexPointerDLL(GLint size, GLenum type, GLsizei stride, const void * pointer); +extern void GLAPIENTRY glActiveTexture(GLenum texture); +extern void GLAPIENTRY glBindBufferARB(GLenum target, GLuint buffer); +extern void GLAPIENTRY glBindBufferBaseNV(GLenum target, GLuint index, GLuint buffer); +extern void GLAPIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer); +extern void GLAPIENTRY glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture); +extern void GLAPIENTRY glBindRenderbufferEXT(GLenum target, GLuint renderbuffer); +extern void GLAPIENTRY glBufferDataARB(GLenum target, GLsizeiptrARB size, const void * data, GLenum usage); +extern void GLAPIENTRY glClampColorARB(GLenum target, GLenum clamp); +extern void GLAPIENTRY glClientActiveTexture(GLenum texture); +extern void GLAPIENTRY glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +extern void GLAPIENTRY glDeleteBuffersARB(GLsizei n, GLuint const * buffers); +extern void GLAPIENTRY glDeleteFramebuffersEXT(GLsizei n, GLuint const * framebuffers); +extern void GLAPIENTRY glDeleteRenderbuffersEXT(GLsizei n, GLuint const * renderbuffers); +extern void GLAPIENTRY glDeleteTextures(GLsizei n, GLuint const * textures); +extern void GLAPIENTRY glDisableVertexAttribArrayARB(GLuint index); +extern void GLAPIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); +extern void GLAPIENTRY glEnableVertexAttribArray(GLuint index); +extern void GLAPIENTRY glEnableVertexAttribArrayARB(GLuint index); +extern void GLAPIENTRY glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +extern void GLAPIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +extern void GLAPIENTRY glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers); +extern void GLAPIENTRY glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers); +extern void GLAPIENTRY glGenTextures(GLsizei n, GLuint * textures); +extern void GLAPIENTRY glGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat * params); +extern void GLAPIENTRY glGetProgramivARB(GLenum target, GLenum pname, GLint * params); +extern void GLAPIENTRY glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void * pixels); +extern GLboolean GLAPIENTRY glIsBufferARB(GLuint buffer); +extern void GLAPIENTRY glLoadTransposeMatrixf(GLfloat const * m); +extern void * GLAPIENTRY glMapNamedBufferEXT(GLuint buffer, GLenum access); +extern void GLAPIENTRY glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t); +extern void GLAPIENTRY glMultiTexCoord2fv(GLenum target, GLfloat const * v); +extern void GLAPIENTRY glMultTransposeMatrixf(GLfloat const * m); +extern void GLAPIENTRY glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage); +extern void GLAPIENTRY glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +extern void GLAPIENTRY glPointParameterf(GLenum pname, GLfloat param); +extern void GLAPIENTRY glPointParameterfv(GLenum pname, GLfloat const * params); +extern void GLAPIENTRY glPointParameteri(GLenum pname, GLint param); +extern void GLAPIENTRY glPrimitiveRestartIndexNV(GLuint index); +extern void GLAPIENTRY glProgramBufferParametersfvNV(GLenum target, GLuint bindingIndex, GLuint wordIndex, GLsizei count, GLfloat const * params); +extern void GLAPIENTRY glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +extern void GLAPIENTRY glProgramEnvParameter4fvARB(GLenum target, GLuint index, GLfloat const * params); +extern void GLAPIENTRY glProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLfloat const * params); +extern void GLAPIENTRY glProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +extern void GLAPIENTRY glProgramLocalParameter4fvARB(GLenum target, GLuint index, GLfloat const * params); +extern void GLAPIENTRY glProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, GLfloat const * params); +extern void GLAPIENTRY glRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +extern void GLAPIENTRY glRenderbufferStorageMultisampleCoverageNV(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +extern GLboolean GLAPIENTRY glUnmapNamedBufferEXT(GLuint buffer); +extern void GLAPIENTRY glUseProgram(GLuint program); +extern void GLAPIENTRY glVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); +extern void GLAPIENTRY glBeginGLUT(GLenum mode); +extern void GLAPIENTRY glBitmapGLUT(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte const * bitmap); +extern void GLAPIENTRY glDrawBufferGLUT(GLenum buf); +extern void GLAPIENTRY glEnableGLUT(GLenum cap); +extern void GLAPIENTRY glEndGLUT(); +extern void GLAPIENTRY glEvalMesh2GLUT(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +extern GLenum GLAPIENTRY glGetErrorGLUT(); +extern void GLAPIENTRY glGetIntegervGLUT(GLenum pname, GLint * data); +extern GLubyte const * GLAPIENTRY glGetStringGLUT(GLenum name); +extern void GLAPIENTRY glMap2fGLUT(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat const * points); +extern void GLAPIENTRY glMapGrid2fGLUT(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +extern void GLAPIENTRY glNormal3fGLUT(GLfloat nx, GLfloat ny, GLfloat nz); +extern void GLAPIENTRY glNormal3fvGLUT(GLfloat const * v); +extern void GLAPIENTRY glPixelStoreiGLUT(GLenum pname, GLint param); +extern void GLAPIENTRY glPolygonModeGLUT(GLenum face, GLenum mode); +extern void GLAPIENTRY glPopAttribGLUT(); +extern void GLAPIENTRY glPopMatrixGLUT(); +extern void GLAPIENTRY glPushAttribGLUT(GLbitfield mask); +extern void GLAPIENTRY glPushMatrixGLUT(); +extern void GLAPIENTRY glReadBufferGLUT(GLenum src); +extern void GLAPIENTRY glRotatefGLUT(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glScalefGLUT(GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glTranslatefGLUT(GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glVertex2fGLUT(GLfloat x, GLfloat y); +extern void GLAPIENTRY glVertex3fGLUT(GLfloat x, GLfloat y, GLfloat z); +extern void GLAPIENTRY glVertex3fvGLUT(GLfloat const * v); +extern HGLRC GLAPIENTRY wglCreateContextGLUT(HDC hDc); + +extern void GLAPIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params); +extern void GLAPIENTRY glStencilMask(GLuint mask); +extern void GLAPIENTRY glPrimitiveRestartIndex(GLuint index); +extern void GLAPIENTRY glClearDepthf(GLfloat d); +extern void GLAPIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary); +extern void GLAPIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const void* binary, GLsizei length); +extern void GLAPIENTRY glBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLbitfield flags); +extern void GLAPIENTRY glCreateBuffers(GLsizei n, GLuint* buffers); +extern void GLAPIENTRY glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void* data, GLbitfield flags); +extern void GLAPIENTRY glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void* data); +extern void* GLAPIENTRY glMapNamedBuffer(GLuint buffer, GLenum access); +extern GLboolean GLAPIENTRY glUnmapNamedBuffer(GLuint buffer); +extern void GLAPIENTRY glTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); + +#if DEBUG +extern constexpr void GLAPIENTRY glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message); +extern constexpr void GLAPIENTRY glPopDebugGroup(); +#endif diff --git a/thirdparty.txt b/thirdparty.txt new file mode 100644 index 0000000..e7eb4cb --- /dev/null +++ b/thirdparty.txt @@ -0,0 +1,52 @@ +SigScan.hpp combined from DivaModLoader's Source/DivaModLoader/SigScan.h and Source/DivaModLoader/SigScan.cpp +Dependencies/Helpers.h from DivaModLoader + +# MIT License + +Copyright (c) 2022 Skyth + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +- The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------- + +Detours + +# Copyright (c) Microsoft Corporation + +All rights reserved. + +# MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.