From 3c8bb36eed15b138b752d43132a9f4326da15393 Mon Sep 17 00:00:00 2001 From: khanhduytran0 Date: Thu, 31 Dec 2020 18:28:34 +0700 Subject: [PATCH] Integrate GLFW stub as project module --- .github/workflows/android.yml | 6 +- .../build.gradle | 6 +- .../jre_lwjgl3glfw.iml | 4 +- jre_lwjgl3glfw/libs/lwjgl-core-3.2.3.jar | Bin 0 -> 557037 bytes jre_lwjgl3glfw/libs/lwjgl-openal-3.2.3.jar | Bin 0 -> 89122 bytes jre_lwjgl3glfw/libs/lwjgl-opengl-3.2.3.jar | Bin 0 -> 937095 bytes .../src/main/java/android/util/ArrayMap.java | 884 ++ .../java/android/util/ContainerHelpers.java | 59 + .../main/java/android/util/EmptyArray.java | 30 + .../java/android/util/MapCollections.java | 557 + .../src/main/java/android/util/Objects.java | 87 + .../client/ClientBrandRetriever.java.z | 8 + .../src/main/java/org/lwjgl/BufferChecks.java | 293 + .../main/java/org/lwjgl/BufferUtils.java.z | 269 + .../src/main/java/org/lwjgl/LWJGLUtil.java | 640 + .../src/main/java/org/lwjgl/MemoryUtil.java.z | 430 + .../main/java/org/lwjgl/PointerBuffer.java.z | 807 ++ .../main/java/org/lwjgl/PointerWrapper.java | 43 + .../org/lwjgl/PointerWrapperAbstract.java | 92 + .../src/main/java/org/lwjgl/Sys.java | 87 + .../java/org/lwjgl/glfw/CallbackBridge.java | 82 + .../main/java/org/lwjgl/glfw/Callbacks.java | 72 + .../main/java/org/lwjgl/glfw/EventLoop.java | 85 + .../src/main/java/org/lwjgl/glfw/GLFW.java | 1224 ++ .../java/org/lwjgl/glfw/GLFWCharCallback.java | 86 + .../org/lwjgl/glfw/GLFWCharCallbackI.java | 50 + .../org/lwjgl/glfw/GLFWCharModsCallback.java | 89 + .../org/lwjgl/glfw/GLFWCharModsCallbackI.java | 55 + .../lwjgl/glfw/GLFWCursorEnterCallback.java | 86 + .../lwjgl/glfw/GLFWCursorEnterCallbackI.java | 50 + .../org/lwjgl/glfw/GLFWCursorPosCallback.java | 87 + .../lwjgl/glfw/GLFWCursorPosCallbackI.java | 56 + .../java/org/lwjgl/glfw/GLFWDropCallback.java | 101 + .../org/lwjgl/glfw/GLFWDropCallbackI.java | 53 + .../org/lwjgl/glfw/GLFWErrorCallback.java | 156 + .../org/lwjgl/glfw/GLFWErrorCallbackI.java | 50 + .../glfw/GLFWFramebufferSizeCallback.java | 87 + .../glfw/GLFWFramebufferSizeCallbackI.java | 53 + .../java/org/lwjgl/glfw/GLFWGamepadState.java | 359 + .../java/org/lwjgl/glfw/GLFWGammaRamp.java | 384 + .../main/java/org/lwjgl/glfw/GLFWImage.java | 367 + .../org/lwjgl/glfw/GLFWJoystickCallback.java | 86 + .../org/lwjgl/glfw/GLFWJoystickCallbackI.java | 50 + .../java/org/lwjgl/glfw/GLFWKeyCallback.java | 87 + .../java/org/lwjgl/glfw/GLFWKeyCallbackI.java | 57 + .../org/lwjgl/glfw/GLFWMonitorCallback.java | 86 + .../org/lwjgl/glfw/GLFWMonitorCallbackI.java | 50 + .../lwjgl/glfw/GLFWMouseButtonCallback.java | 86 + .../lwjgl/glfw/GLFWMouseButtonCallbackI.java | 54 + .../java/org/lwjgl/glfw/GLFWNativeGLX.java | 125 + .../org/lwjgl/glfw/GLFWScrollCallback.java | 87 + .../org/lwjgl/glfw/GLFWScrollCallbackI.java | 53 + .../main/java/org/lwjgl/glfw/GLFWVidMode.java | 204 + .../lwjgl/glfw/GLFWWindowCloseCallback.java | 85 + .../lwjgl/glfw/GLFWWindowCloseCallbackI.java | 47 + .../glfw/GLFWWindowContentScaleCallback.java | 87 + .../glfw/GLFWWindowContentScaleCallbackI.java | 53 + .../lwjgl/glfw/GLFWWindowFocusCallback.java | 86 + .../lwjgl/glfw/GLFWWindowFocusCallbackI.java | 50 + .../lwjgl/glfw/GLFWWindowIconifyCallback.java | 86 + .../glfw/GLFWWindowIconifyCallbackI.java | 50 + .../glfw/GLFWWindowMaximizeCallback.java | 86 + .../glfw/GLFWWindowMaximizeCallbackI.java | 50 + .../org/lwjgl/glfw/GLFWWindowPosCallback.java | 87 + .../lwjgl/glfw/GLFWWindowPosCallbackI.java | 53 + .../org/lwjgl/glfw/GLFWWindowProperties.java | 13 + .../lwjgl/glfw/GLFWWindowRefreshCallback.java | 85 + .../glfw/GLFWWindowRefreshCallbackI.java | 48 + .../lwjgl/glfw/GLFWWindowSizeCallback.java | 85 + .../lwjgl/glfw/GLFWWindowSizeCallbackI.java | 51 + .../java/org/lwjgl/glfw/package-info.java | 20 + .../src/main/java/org/lwjgl/input/Cursor.java | 270 + .../main/java/org/lwjgl/input/EventQueue.java | 61 + .../main/java/org/lwjgl/input/KeyCodes.java | 321 + .../main/java/org/lwjgl/input/Keyboard.java | 309 + .../src/main/java/org/lwjgl/input/Mouse.java | 241 + .../src/main/java/org/lwjgl/openal/AL.java | 330 + .../src/main/java/org/lwjgl/openal/AL10.java | 1931 +++ .../src/main/java/org/lwjgl/openal/ALC10.java | 530 + .../java/org/lwjgl/openal/ALCcontext.java | 115 + .../main/java/org/lwjgl/openal/ALCdevice.java | 121 + .../src/main/java/org/lwjgl/openal/EFX10.java | 143 + .../main/java/org/lwjgl/openal/EFXUtil.java | 210 + .../org/lwjgl/openal/OpenALException.java | 85 + .../src/main/java/org/lwjgl/openal/Util.java | 86 + .../org/lwjgl/opengl/ARBBufferObject.java | 5 + .../org/lwjgl/opengl/ARBShaderObjects.java | 1363 ++ .../java/org/lwjgl/opengl/AWTGLCanvas.java | 203 + .../main/java/org/lwjgl/opengl/Context.java | 50 + .../java/org/lwjgl/opengl/ContextAttribs.java | 112 + .../org/lwjgl/opengl/ContextCapabilities.java | 402 + .../main/java/org/lwjgl/opengl/ContextGL.java | 292 + .../main/java/org/lwjgl/opengl/Display.java | 1124 ++ .../lwjgl/opengl/DisplayImplementation.java | 200 + .../java/org/lwjgl/opengl/DisplayMode.java | 142 + .../main/java/org/lwjgl/opengl/Drawable.java | 77 + .../java/org/lwjgl/opengl/DrawableGL.java | 156 + .../java/org/lwjgl/opengl/DrawableLWJGL.java | 71 + .../main/java/org/lwjgl/opengl/EXTAbgr.java | 7 + .../org/lwjgl/opengl/EXTTextureRectangle.java | 8 + .../src/main/java/org/lwjgl/opengl/GL.java | 743 ++ .../src/main/java/org/lwjgl/opengl/GL11.java | 10225 ++++++++++++++++ .../src/main/java/org/lwjgl/opengl/GL15.java | 1200 ++ .../src/main/java/org/lwjgl/opengl/GL20.java | 2925 +++++ .../main/java/org/lwjgl/opengl/GLContext.java | 15 + .../main/java/org/lwjgl/opengl/GLSync.java | 47 + .../java/org/lwjgl/opengl/GlobalLock.java | 40 + .../org/lwjgl/opengl/InputImplementation.java | 134 + .../org/lwjgl/opengl/OpenGLException.java | 89 + .../main/java/org/lwjgl/opengl/Pbuffer.java | 320 + .../main/java/org/lwjgl/opengl/PeerInfo.java | 97 + .../java/org/lwjgl/opengl/PixelFormat.java | 424 + .../org/lwjgl/opengl/PixelFormatLWJGL.java | 41 + .../java/org/lwjgl/opengl/RenderTexture.java | 251 + .../java/org/lwjgl/opengl/SharedDrawable.java | 58 + .../src/main/java/org/lwjgl/opengl/Sync.java | 186 + .../src/main/java/org/lwjgl/opengl/Util.java | 90 + .../src/main/java/org/lwjgl/util/Color.java | 494 + .../main/java/org/lwjgl/util/Dimension.java | 156 + .../src/main/java/org/lwjgl/util/Display.java | 243 + .../src/main/java/org/lwjgl/util/Point.java | 170 + .../java/org/lwjgl/util/ReadableColor.java | 146 + .../org/lwjgl/util/ReadableDimension.java | 60 + .../java/org/lwjgl/util/ReadablePoint.java | 57 + .../org/lwjgl/util/ReadableRectangle.java | 48 + .../main/java/org/lwjgl/util/Rectangle.java | 581 + .../main/java/org/lwjgl/util/Renderable.java | 49 + .../src/main/java/org/lwjgl/util/Timer.java | 156 + .../main/java/org/lwjgl/util/WaveData.java | 257 + .../java/org/lwjgl/util/WritableColor.java | 126 + .../org/lwjgl/util/WritableDimension.java | 54 + .../java/org/lwjgl/util/WritablePoint.java | 45 + .../org/lwjgl/util/WritableRectangle.java | 63 + .../src/main/java/org/lwjgl/util/XPMFile.java | 302 + .../java/org/lwjgl/util/glu/Cylinder.java | 201 + .../main/java/org/lwjgl/util/glu/Disk.java | 214 + .../src/main/java/org/lwjgl/util/glu/GLU.java | 430 + .../org/lwjgl/util/glu/GLUtessellator.java | 72 + .../util/glu/GLUtessellatorCallback.java | 388 + .../glu/GLUtessellatorCallbackAdapter.java | 116 + .../main/java/org/lwjgl/util/glu/MipMap.java | 353 + .../java/org/lwjgl/util/glu/PartialDisk.java | 358 + .../org/lwjgl/util/glu/PixelStoreState.java | 84 + .../main/java/org/lwjgl/util/glu/Project.java | 411 + .../main/java/org/lwjgl/util/glu/Quadric.java | 199 + .../java/org/lwjgl/util/glu/Registry.java | 80 + .../main/java/org/lwjgl/util/glu/Sphere.java | 229 + .../main/java/org/lwjgl/util/glu/Util.java | 225 + .../util/glu/tessellation/ActiveRegion.java | 100 + .../util/glu/tessellation/CachedVertex.java | 90 + .../org/lwjgl/util/glu/tessellation/Dict.java | 172 + .../lwjgl/util/glu/tessellation/DictNode.java | 91 + .../lwjgl/util/glu/tessellation/GLUface.java | 97 + .../util/glu/tessellation/GLUhalfEdge.java | 105 + .../lwjgl/util/glu/tessellation/GLUmesh.java | 94 + .../glu/tessellation/GLUtessellatorImpl.java | 669 + .../util/glu/tessellation/GLUvertex.java | 97 + .../org/lwjgl/util/glu/tessellation/Geom.java | 350 + .../org/lwjgl/util/glu/tessellation/Mesh.java | 766 ++ .../lwjgl/util/glu/tessellation/Normal.java | 319 + .../util/glu/tessellation/PriorityQ.java | 132 + .../util/glu/tessellation/PriorityQHeap.java | 296 + .../util/glu/tessellation/PriorityQSort.java | 310 + .../lwjgl/util/glu/tessellation/Render.java | 589 + .../lwjgl/util/glu/tessellation/Sweep.java | 1384 +++ .../lwjgl/util/glu/tessellation/TessMono.java | 241 + .../util/glu/tessellation/TessState.java | 91 + .../lwjgl/util/input/ControllerAdapter.java.z | 340 + .../java/org/lwjgl/util/vector/Matrix.java | 134 + .../java/org/lwjgl/util/vector/Matrix2f.java | 400 + .../java/org/lwjgl/util/vector/Matrix3f.java | 510 + .../java/org/lwjgl/util/vector/Matrix4f.java | 849 ++ .../org/lwjgl/util/vector/Quaternion.java | 530 + .../org/lwjgl/util/vector/ReadableVector.java | 54 + .../lwjgl/util/vector/ReadableVector2f.java | 46 + .../lwjgl/util/vector/ReadableVector3f.java | 42 + .../lwjgl/util/vector/ReadableVector4f.java | 44 + .../java/org/lwjgl/util/vector/Vector.java | 112 + .../java/org/lwjgl/util/vector/Vector2f.java | 290 + .../java/org/lwjgl/util/vector/Vector3f.java | 347 + .../java/org/lwjgl/util/vector/Vector4f.java | 340 + .../lwjgl/util/vector/WritableVector2f.java | 61 + .../lwjgl/util/vector/WritableVector3f.java | 56 + .../lwjgl/util/vector/WritableVector4f.java | 57 + .../security/PojavSecurityManager.java | 10 - settings.gradle | 2 +- 186 files changed, 52497 insertions(+), 18 deletions(-) rename {jre_securitymanager => jre_lwjgl3glfw}/build.gradle (64%) rename jre_securitymanager/jre_securitymanager.iml => jre_lwjgl3glfw/jre_lwjgl3glfw.iml (82%) create mode 100644 jre_lwjgl3glfw/libs/lwjgl-core-3.2.3.jar create mode 100644 jre_lwjgl3glfw/libs/lwjgl-openal-3.2.3.jar create mode 100644 jre_lwjgl3glfw/libs/lwjgl-opengl-3.2.3.jar create mode 100644 jre_lwjgl3glfw/src/main/java/android/util/ArrayMap.java create mode 100644 jre_lwjgl3glfw/src/main/java/android/util/ContainerHelpers.java create mode 100644 jre_lwjgl3glfw/src/main/java/android/util/EmptyArray.java create mode 100644 jre_lwjgl3glfw/src/main/java/android/util/MapCollections.java create mode 100644 jre_lwjgl3glfw/src/main/java/android/util/Objects.java create mode 100644 jre_lwjgl3glfw/src/main/java/net/minecraft/client/ClientBrandRetriever.java.z create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferChecks.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferUtils.java.z create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/LWJGLUtil.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/MemoryUtil.java.z create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerBuffer.java.z create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapper.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapperAbstract.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/Sys.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/Callbacks.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/EventLoop.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGamepadState.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGammaRamp.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWImage.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWNativeGLX.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWVidMode.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowProperties.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallbackI.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/package-info.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Cursor.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/input/EventQueue.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/input/KeyCodes.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Keyboard.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Mouse.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL10.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALC10.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCcontext.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCdevice.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFX10.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFXUtil.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/OpenALException.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/Util.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBBufferObject.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBShaderObjects.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/AWTGLCanvas.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Context.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextAttribs.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextCapabilities.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextGL.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Display.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayImplementation.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayMode.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Drawable.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableGL.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableLWJGL.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTAbgr.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTTextureRectangle.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL11.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL15.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL20.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLContext.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLSync.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GlobalLock.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/InputImplementation.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/OpenGLException.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Pbuffer.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PeerInfo.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormat.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormatLWJGL.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/RenderTexture.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/SharedDrawable.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Sync.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Util.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Color.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Dimension.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Display.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Point.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableColor.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableDimension.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadablePoint.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableRectangle.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Rectangle.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Renderable.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Timer.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WaveData.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableColor.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableDimension.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritablePoint.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableRectangle.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/XPMFile.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Cylinder.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Disk.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLU.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellator.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallback.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallbackAdapter.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/MipMap.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PartialDisk.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PixelStoreState.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Project.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Quadric.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Registry.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Sphere.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Util.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/ActiveRegion.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/CachedVertex.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Dict.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/DictNode.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUface.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUhalfEdge.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUmesh.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUtessellatorImpl.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUvertex.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Geom.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Mesh.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Normal.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQ.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQHeap.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQSort.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Render.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Sweep.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessMono.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessState.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/input/ControllerAdapter.java.z create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix2f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix3f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix4f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Quaternion.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector2f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector3f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector4f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector2f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector3f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector4f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector2f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector3f.java create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector4f.java delete mode 100644 jre_securitymanager/src/main/java/net/pojavlauncher/security/PojavSecurityManager.java diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 686d052e0..653a7514f 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -22,8 +22,10 @@ jobs: # Build JRE JAR files (security manager, etc...) ./gradlew clean build - mkdir app_pojavlauncher/src/main/assets/components/internal_libs - cp jre_securitymanager/build/libs/jre_securitymanager-1.0.jar app_pojavlauncher/src/main/assets/components/internal_libs + # mkdir app_pojavlauncher/src/main/assets/components/internal_libs + rm app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl-glfw-classes.jar + cp jre_lwjgl3glfw/build/libs/jre_lwjgl3glfw-3.2.3.jar app_pojavlauncher/src/main/assets/components/lwjgl3/lwjgl3 +-glfw-classes.jar # Build the launcher ./gradlew assembleDebug diff --git a/jre_securitymanager/build.gradle b/jre_lwjgl3glfw/build.gradle similarity index 64% rename from jre_securitymanager/build.gradle rename to jre_lwjgl3glfw/build.gradle index a7476c222..ac7a70846 100644 --- a/jre_securitymanager/build.gradle +++ b/jre_lwjgl3glfw/build.gradle @@ -1,8 +1,8 @@ apply plugin: 'java' apply plugin: 'eclipse' -group = 'net.pojavlauncher.security' -version = '1.0' +group = 'org.lwjgl.glfw' +version = '3.2.3' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -15,6 +15,6 @@ repositories { } dependencies { - // implementation "..." + implementation fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/jre_securitymanager/jre_securitymanager.iml b/jre_lwjgl3glfw/jre_lwjgl3glfw.iml similarity index 82% rename from jre_securitymanager/jre_securitymanager.iml rename to jre_lwjgl3glfw/jre_lwjgl3glfw.iml index abd55253e..cbfaf964b 100644 --- a/jre_securitymanager/jre_securitymanager.iml +++ b/jre_lwjgl3glfw/jre_lwjgl3glfw.iml @@ -1,9 +1,9 @@ - + - diff --git a/jre_lwjgl3glfw/libs/lwjgl-core-3.2.3.jar b/jre_lwjgl3glfw/libs/lwjgl-core-3.2.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..756d423fd9f365fcb7c783ae8f47a847a3dfffe1 GIT binary patch literal 557037 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%0DH!Poo2Z zlx5Gh3<^4-h^M@@y}qWVzJv^=OCoXJq9MQT19SnDb^0cIa}ML3D^^Nx_OYoYt_)0k zIfjm-L)KWsI2vu1h&^0&-BrfOsk;(&upr+-%9xxPrta=)LL({mB~j>|w%U&nKktqe zr7Tvx2!8`h`PUI?dCh=(Ld}E}n)m=03;a!^-8KB%XUp-FqBc`5vz5xKBK}nMBe)mr zH+9OJhi11FSA3%4>hk_|*6sCuVwI`pXUeB1C$`?|a^q>!jQ8tCqm!muEB)Se)=5QW z79Tq9;jK&c(+9W7^T2^PYGv2<4(X4qZ|?3YcdId?=JlOx;qv&PDwwFW6JUt{@G*g-Sq40he0$o!r8^6B5l&?h4ORF z&Gln-+KOL8a?i^0HeXqNb^aN2G32wy>+{Qacu)OSXrC)+S0x#<)K9aCF%f^@>=xSQS6Au2woS@-)bJEpkF$RC)GEP)0cWJQ>)CWcoMPd0c@HdUAUgB zo}F6DJ#+e}$&%25cd7*)0y9gM!Y#5!nngf;=sH5t+`#!e8j#ZliY+|`6HDybi0u$L z@!r%KvG8XdZlp`Wk(?f&OlqYDT@skuSWmHVf>L_1zv@bz4XTBaCZxqmtg9EX*PJq@ zM1>fyuQ5ozv%Tv?l4>(fmWiA-g?vjfx}1h-cIvk_6IcEFP{)ucT`iaw_bW%M<{`JJ z!<2+47HV#8WcB2tTMKKYKull_BJ{9wrmYyvnQD^&<;CNJ&kSi20rLFO#rx5s{Er@c1Bf|w=LplVx_|0?z z7zbCR5NFnh`kiFD?L^dOEg6AM1k=mbmX5`oUpbPHaVI1KQQlZV^P@;Kh5=eyRAH8f z1WZ^><9QRbExC%=mjptx_9!5loS$Evk;fI zHuBe)Me`9#RNA&FE~(!Jt6w9N2aWO6;(x<%ePzVNW!1QR&3yOxxQtwh%o-i91UX0v zOTzZDB$5jzBP41z+W32ev0lOH^A(pcO<8gVg34s?EZ1owcYk;D={QK~sjBo~jV*>7b;zJXaxj<`ox=ZCvicd*gRjje?tja;Zj+ z2*O(tJKv>%rnkE=VyhRs#@wOi^43AQFE8uxfRb}_v@T4BI8Lm{ZwwW0NMs^R z6+T7Qz>0_-j~ljxXhEl2aEKEo2$Qe%^rY&-$Nn{mXMeIl%pBcU-c*I83ioDK$f!eZha?ii-jvBWV&h;y?%YY^Xs>h!@v_L%3`D{KO*)Y0EDU#VTZeXU%( zK>I?OPKnNqN{vE|E2%PTV);vid^hSsuUh-?sL}XBlRTGNX_fQ+B}ubV`}W9I_fUC- zlAS;BAKb-P6_PsE$KAwuZ;B^cDO$ObH{C0gG-|hQ-z{a!rZUo7j3 z#HS%K7c4$k;0TB46tO*QEO}{%Rk()OkvASYY)kk^wW0wJWct^IJf717pbvPy?^Zs~ zzH*Lojw6*E^(@Cb@lxk3)huW7X)=1&MC62&><>-oTf;*{V()}rVT^Zj24eXtc!A2e*r2&v~g*9Su+ybD0zwf#qn3ClEkV$s&oMy0E> z+I0|SjFJ%$c~((o^E0$rOt{#_$5(b5tlFFE*znkwxuR62T4J;VZS{p|=$9s}d?E;m z?9JTTie{rpq+9ymilS(H$I=bfW>Ta^>7luGRhbB(BRFTmWHoK3t$1d*7!~*|`4~^W ztTs@PdQy7E&J*#-IJsAQ^JrPs4mKl`%rl0kyp4lB?)0Soc5|`o>=Lr@I#u4`p_eyR z_iw=8`+%(7j_H;0!Q$gJaqZ2T6Ua2BA%YgHzgPzf@E)wqThSbKHH#AD#XZJknjMkJ z0_yUc7o1-SvM}wNm4C~72b|9s#J8Qmv`a_JH~?y5D{hmhTsESWYwWpNV+MGJ41?$z zFPm$y_E%ZbR%#kYE3xBgj)7is#j~W8nd!El&q3mK%M*jJrDspi^uKC1YM^naW`}Ox zKN3<}!yZ99KLp3oGmW8N9!U}CSyJ>$lk35~LuGrB9#uL&EXUQ(kFN^$$dcCvdv(j| zg1>`hdl4UHIzLRu+0Bo)3iim5*M@p^%HsKXh069IKj?71+m5}S9l^%kE|0$o^yrcQ z0(ck5{z5nkb$K9;!(Sec74Xp}{{{Fik^O~oRO<4;9GAO1J}cm(OWq6cE|UF)bd>7y zKpm&IJYFl{qeI>c_%4(Eg?7~H^1vOpyF7j?;G;+G3-B(K{e^fG>+(Pz_iK4PSKvpR z+!yd&D*FrdsMh6yJ+60od{^K{m;4XFyIA%Y@=>nK1AUzD@_4Vnj}G}Cz<0UqFZ82c zmxo_*e_+S6>S<+9%LR|9%vq59&9fjcQ|*lH;_A;JMBB`yYM~Ey~I9p zzf=Fy06DN+h#Yu6$SwdL_$~x5rZ<#3ue?(ty+ebpKR;^uW}> zR6jMp)Brm$T`)e_E*vi|_rJAAZ>D>hfpWmPfPA=KWPeGtzvL{?UlQAk>@8(a%g+v! z586w15g@Zu^|3?8{e3QO^gWv=oLnek7?K{fIUv4JJ{quvwX1u32(V>ZQ|PG50M1pQ z4!6jLC%Uw-8|ElV=qPHGyfM`*f8RQ1kfy)@zH#rD(S3oz=F55_*jfv_1uc2lfYsba zv-vaEyhq3!+AKN20;c4ZAUylU_%X7`TZmPTaltyC#-m4*FEe>A7)4?XR7|}}PK4!^KaDaKWs?VsPRn;u>M@-txVWI z#QMRir(IVPiQwwVjB$TV;AAJ-{ikcuqhGh{0af`l*({6i#r+9Ryk$BZpErmH@* z(UeSa^>3~k09Bd$TnTv5^2viW7}rJtLlUD8A!(AyFZ4?+Iu`P*z^rp6Aa}A-qE9V7sfd@}A z_~jV+gXThFm0lne!W?6%KuFdo9zz18{{d3HLwn60| z0lKLy&*+x$u{^c`D%k~V!JokR?SP)LW%AXc(L7iqi?#S50?pD$7zbIj@%aYtbo?y( z<(XkJw)}6)46{SI&^*{Y{a9^dUovc2npXXjy~=C4IhuK~A9y#SlEcg_6||Z?OT!vf zv&SzoaU7nHKLN*o%#ZvSSe^?tys_Plgr_MtPlX<5M5k8;A6?9iZPHH2dLGAEQU#qF z!%vpRGVlXVLg&Yb4KlPu3)_=h%QLhPD^zX9irO2XAHdWb6`rBxzloB%jhT#@41~?c zD2OAB8qD~1Neg(-Yp!tC77d$DdCfiWU%d1UXMtRI%C0E`c%k2kmUCoHM}1)|4CF?v zty~56lVD&zRSRWy_X(bOb&oy;)>xFJg((-v;x(ncNfbMYio=#{#WmDnB9UD+i8nP2 zSkGJKnY!5B*wYb4Go{0N^K*T~?0yVZG6TtmUd&el*am~j)YEn9>m4Eji>VmNkPiap zYe7Bx7-}J(rpD%yK~Ch6G`bRu(bfX<=)=K2yojHy`DX#2wE1(*fq0#s=30pdn|N<@ z%>4{qKL9q1Ypi*->SWSgc(vBzbO@s>>#EEmTbfd2)MwFRTWd0nkjrT{yBR1`WQ>(C z2TL(>3BtV4fDte-B_XAhB@IL|Gs~3gfd0A!)Cp4{Wy(IXhI^ohV4AqQIIS7(H$_c- zb;MUfIY9Y)uB%>oqkb8XoaWldEGg+ZiT@M>P9KnzrArOSUg!jq{t!XQt>| zJn*(PA(`8zwmWUnIk|GU3)7wb(+eDqk2j4)nTyp{g|1G(TU#LPw=m2Z`zNZZ0DP!j zf)>nezbj=fOuZJ%I(~y{lH^crW$|tT{xVx*!U3+@KD*S>h-$!=QgB_J9xPwr|2zLZ zXyrQNt3=J%ifn%PYq!ZXBIe5$|hAyP6}Hx$^Z~GQ!7S@UyBk`V$hxwYZA0XW`VT%jo*zk zV)9Wldc6$aX`ns>&7)4!oU_8^4$f(W7BZ?6WjQ~A0-&u}m{)<>~;d!Ray3aAnD zBp^G_wtuCV1${|tvUtNW1Gc}Z0>V#;xSyT7K*9P`QJTQ;Gv8*&_XTKL9B$?)!{Y?a z<3!Ello@XJf_s#%BJ|s|e4ZJ5FWqyHr_t^yN23_mY^5@X5_WoF{W86_Uz2b-LgJkY z?H4$5v-5<^0QKQI$;e%Llw6w{UVs{&zZzb!8lD+)68Rd*-&I69k=XIhDT-lDm|m-T zdRo5m#iPOgtCZnbuWWvLwtl{UYxW4v!ElIM_!zbAYPoK4@`t!vhzCFu{s_EWb8}f- z0!5R2dUA$RxQvE5WMXvg6H-c^Z&{`*yg^R*LO((|exj(F^C~=E0J$CgftJftdX^>h zPDq7XO#x-$h_q@d(aCl$gFOzy6KM8TKT|N!?Kc$mGyIaAGz) zn!iNo=An$2y8eZb6k%k&v_E_)+~weu03Qz_75bfsGT)Y=I=*R4ID9Me zNlsbDCrD$20XH(Un>VNFjm_ja1}k`Xl1Z|tnZ~ffgldkI80BUMr)&H~!(=jRZgRv8 z)hM|&Tq}R#a4=lGf<-?n#QH?64L>stAp>Rq*ozF*kmxoO zwV_4Zu+r`M%WIm!1C!wt(hg$5a8uK87NsJ%!ZxJxK?`C!MX@-sfcg~14bBxWH=m60 zw=6?GzSP3qZ-AE7x9~Tqo-?A^-J7lX-_lCk2{5Oi({B}4IyPcRkPLm8g!B5W^&$2lOwi-jTx?K|+ zQ&}{pbUSAg8r3>%Y?c~Vf2Vb?w-So35Q~B#5WB%(6GM;Ch|VydXB$55{6^@0MDRG> zuiIJIyUc!U-qBz#bEBKHUD%2nZu!*-GfMY6xFvRf&E$7HCoMfJA92_cRtFch0?Sh( z;6^GmJY!{_79tihCr6}#wE8k*z1;5_51hvFdVQr>qjeg+AYVeh{lI;1m=O4Rc6FAmj01v#x1g>ebgjFHXtCB& zDYJv=S>Jb>SPouGRK2e4XvJdHf}YVPFInNV ztiP*1V@_PJEXz7ZK&Dub8A5@k3;>+mm-K6Jp`>#Wryv2G4$S+t&45fhAk!KFPjLJ= z*)18YLV*_TK%6N1wAnNnRx|y|Spc1Q`>KG`unWK%Z7CS2qxHc6PGaT*+WSGKPRR7} zK+-}1P7IJ4tib%+9Vi$+vHE#{8D>NLHIQ-Bd=ycyb^i1ec3igh1d(2&(pc0s+^?*v z*F3|f!0STjntC%|)%Z@2>^|=rAEaZF<-CLByrbm2(^$@K@g$k4V)8!n@;nZj^Ek1V zN4(VdE{ENIRQC>0_YP9~_EG!RL$36$|I&;~pb>)w`3d1NDiMm1&iHcfw z`169O4SCJJK~1QIZD@?{d`wahYY4)Jv_{8#bkFxr(DTKb z+mK{C!*;R`zV18Pp@ICsm=os&Ue_EO$F=mNuCodHx-;GkwcInV!2*55HLc!%x01_< z(fHma79tI+?a*%v&~;BH#Nvq|MW0*y&vjf0kAhMT#4&TwgK+)=)0Y)d{NQnq{DY6d z6>xtlhq6&(a6NecT3~f0QF3Z{gOsRE(iWB9h4ld6^AQzrR@NG2Q;0B*T}jy+P0+y zwVBnY;m{hvM8sz>H>*#a`zfmUmgPClG#B$8q7%pGv}3AD3y#d+3kp*<7o0Kx z{kz8i&Ao%X*OCs~9n||(=e!w9Gy1|j2}}<_-~3(h&VZY_TDr74M+Ice9L6LI_n_5%NcT??adU~jJ|jKiPqr! ziIQSOZ}|If0$coYz_8n0@P6|i{h}jW_LM3~^kExwx6K&hV3s?A^Kx#`(xr@)#{ygtBb$jW(NyK($tH4-Nx;DbU336zsow{CUdtvbEgCSuW`19 zyx-tXyVcq?-4Y39Pw%Sazf|;0BK1VN1?z_J&~?K2@bEQhP2~|6c_V(cr44VonNYrL zYm{{Bv>Ht%)Cxr`IsfEvyqA>qI;TY)x-6QFJ-by z$nF$1RjhxP3DaD)AG!g_@G6|MiEc;V$c>{V8-z=V%$-9Z=G5rA>9(x?&ejgw;e3w`C_igIt^ z52W|kQtU~xibCS^)iG8EN6&WyT-y_wVW|bX$kcYyO?ppZ?4dHwry1uxpdEI>H=6^_ zx7=9UVvlkv+u-G^4eJlrGr#kpW038|`xm?_=H=W5qB{3VJNHXrVJ@3)vJ$Gh=i~m- zW$=(|SxP3PHurhizP!O@w8_)_D8hh-gaGat_<4X3VgZK^2Lr}%JP}a*OYdft5mqbc z;ZrMach`@g?eohCCo6y|#*k`Ja!s>{a{5v3X@HJ6r4eV1K)U7lySojNx~MR3HX4*VgV13{oY^*`0&v{RLkqZ1fW;i$p|6}0PbP= zy`T|x0f*oL?hoq-(5$f#(9JW0-lxcx$j8}pwbxCs&7V29Iof}~7Vp0!b^a`_k-Srd zidQSVg4ECd%&ooEM1+fwmZ0s=y6DT3bG?x@oKYn{n=vOoj~bZ4sVD7)t+zd&T7InT z2*0v0Z{N>l18j$5*Lqfm-<+FvEaq|Jb}+N)zH%XNC!2OS<#_@*pW1faV9Pk$*_LqQ zcR=TLGDyE>#9x%CcdiS+!Z2@>&gnpHn_!n_+V7e+G+8r#EgYo5F;i)D89AjKq>VS= zXa&ibqgx_t?w9P4ZP_wW&tmzgx=sOxwFA_%@>@eAY>EIHCQeOYzoAow*>;o=0Wa5@ zRxxyY0ryzs70zOg=$Dx?!m&%anfIpVk+TjmA4Ru`Zx8pPa913wLl zh_Y8OxVMe?0*QWTp{AME<&I}mYmc6Iu(5NTiFS+&urJcOx@U59Eeo{HUt8bo-N}M)i@0%{gLi~Fy*9Yvd%iZd zrgwv{@r)hf9c&Ha@D1z~TH_f#a-8Puz2_L;QnJZ8y}@|SZk%yq^U^DnbIyB zcZ<7BBw3!5;LRGtCezV7!^!=HS&A)ylT@v(FBaMcRG;_2Aj zzJ9eIAdOcdLG#$Y{)qw2vPv`oL$75@YVyaj5?nR#(_1Ao=F zNHK@bAvt?)F|7ZonGq>CbVz&=2T*E5e`)=ww+$VQ%vqgR;_fNkMFxPc-?~g|LL%-8 z1>xrI!rjJ{(;~^pS!e(GT`9ccy;PTxMjk)DyhR+pj*O|?N1GRt95Ww3ELo+ciz8S< zgn$_*#Oo-1tS*;ZcvF)UTj+2h_=3nRB59iiB@A|T9?fqfZs6s5aWK|`7t94QLMQl!)aHq}zcPwoy8 z@9QOw(|H$&;tjPfFfj&aq%3|FH_@~f_XSw8@+K&f82#Hblm(jTRlu_?r6xe8wM;4H z{Ams=+7IO}d?yDvcQR{0Hltp!PbZBNMRXDuHGqVX(YwDSW9uAdFQ>=C#FX@> z_gXtiB0l6uKc-kWAqG}y7LjJ_hWgZKiZZ$sTa*!H#fR!4Sj{IqH7oqkrBz;2&f8-_ zjT(oR&BX1xNEjVE9daBslw~FtFA469De+6E@Vl+(=&DED$fU}p%BDVC3X=s9g4wZ|Pive&Om`muY@OEJt(v3rk5)h*b_d*|#p zE@VBV#qPK-@I2He?-c#xx(|xwcU_QpXh?>T+V54!Mh%Mq$>XLHD$0I~nLg#cf~CMK zJMMK|pt{T%HSbA#iz<81%=-wRZo~B-+xZ7jJMPA~Kf1lLe80enuiJ3)h_wJR*TeCd zfn7d7Y|_rOi5TD*l&V@uD(Dlyw>Hrq?be zozgeB+ntwgG)*%WigK7f1TkzT^3^Tuh&7I-a|k~ELTMIUdr{L zkjNUZR2Yh{H5pr~h4)kre=aTZHcZ+V)&+UzGeTb*u4sEk^wR+J8F*20^Q0q`37UCj zhhA~M-KUPvWS$35?-%iliKHYAAzZ0i+0Kx6?e4uWkA9KKVuqRIYg#9;&LcX|_OX_g zO~95UcyN^{;R->gr33>cn?X!jVG&tb&!IqiBik@SBk9C)MzDT>vYQv8#8fj)OKMw0 zI$O)8gSlYK=tlYo+-4Y7r%+!+YjMa(r%H=OtQ$?km2$ODx~DSrM2&`_F^

=fF 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 %3_grC^?RTjFNAn;+YprFR-?%vcP5XNj9M~!y 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�CENuhL-9p&@~5Q=$9ycLzr^aimju?=?qbRBvKvdq&xIF`-L%l z=Wa&WXQxYB*_U}sWD0M^9y9aF7~U`_Fy5$QpL*b#5;BPOjlGN!qZv_c@I^~G8nmgc z=%#9}`d6a-phn6Z6X`#N6>z(y7k;ra4C+WCsCooxbt@8^#w}H{YOsY?FmPxXl4=-| zYwVC|>}ZECg^|ZCN#?(%=dupbQ8Q|=wP;yIvuYfjTQ<-#=^j&BQgQ{^{Opd-ft)vq zqwUJRRm=iA+UqptB@6=NL5E7nBJIcp5#t3|Sb56!m^*R5iqbjOV??;o{t4hl&CqK3 zDnPBBvO{=r-*S)Reul*C!|-be>O?MGENbch*3ysB(vQ+&RES(k`{5ld;Grq!{Eu}d@F)&32bRh5fc-GN%&;ac6% zTHUuZgOQwBhLWgNmC7S$5QAsrgJ&j#XBhE*5^V8l3ntA)SmZqm zHSQ2oYibDJ?OCcE)cqy7Z#klczTemvy$LBCN#Yf~iFu7Ps};Y=gpKjw>-Oz%y~S=u zbZrwiYwd6mQur6~aU9sY3u7g6q{$c39jdA06|Ea>N{d@hmrFAx=l%Lzlt%7X{Zprq zLSdtBL!p{c+`f-|dFKZ=*rFOV3}FfN?WiCwf?a$n&LP8APM6Ep_4u} zJ`#8Sj9OO$yPvL8U(}HLyC3VUCb&1PcP>20YHjxP@hIB9De`J|c12#C8O9rGmVWNe zHeb{1zOylVPQ41)xw0ZFZU_TB2lwL#{Q;ZhoQ$+LoCYHQSE49h2jxvTdp>t(F7#+7 z?!lx9@)3^>MNTDn-ZJYH+xbPP-q;1N24~14n^n=Iwat>^k1(#RYgN52fw6?Fqn%?> zn3tQMm;2<(@s)TC#h)tW%^{2efhB0UMRBT6p5JBz!Y`S3KzUJ^y$+o2658pu_5SjG z%yvl%UC#nJ6-svCKt{8V1$Q*S*ED(Np8{2juaYq*zghS`lY zgl-E+Q0FzLe2E||2qxqM)zu#dh|(r>t%nSXv&d-KMw?nc5DowbDvF&@hkRfnfC4<0 z1xWv6#mrBe8L;<`d_j~P!*4GLY4V?K7Bv#rL|}fc+CG%PI`H=;;G51Yv%$~zo!k~Y zzbjZ^)6{yFZ~y|(LHwjG`s$`iL>&tW&2_lRq9nBCMLVym$pL9bFKddmoiKCP!kv1yaxjA4^u8~TxV*B^WH`oR33@ch(%6WTUI&!~us zL(m~Yyf0j0-LE(Ncwb&?^d39EG|GG=4Tu+dM}LUvYv3LV9pHD$#l9gtFiv}yvkBJ0 zBVpmH^v8qVc$3dJL9CmD#NFPvtedr7wD&})ZHw#Y3aySX{lw{Hn4|IaWUR+j&T@l5H% zcw&lUZg+Rf^22gSDT6_g!-IiqDS;C8`h}%L@E~V#RCd{8Fd?h8lrNCJ0(kI!uz4T0 zyHHodM4h54Z4xX ztfkcWUHELUKBx~APq1qM0uiP@#ZmG@40CjFfHq(a0Nzg^LRt{6B$qBrLz;{}4toTE z@8|3H6`?c&Ga@xYGh*)F2GI2j0Id6sMUVm%pAIRBJ@!;eE<{}72 zxCJS*5|-4isHqqa)YT-_6xCz|LR|5VsC&QqNdcm8Rd8Ww$kYVFT#1gDdzSrp{XYOE za5iuwXtC7ULR<-s=zFI9v;bAOGBgG1Y+)@)t|UjSy$j3(f`d)W1HJ>_ekcF}95xyg zm7Yj@vLo)EbN_b$J)9<5EtQ^Vd#WSho_9YI03VJM&7Nvgq&>wEf6u+25TMYX1L%VF zz_=palx>f56x;*r4*`V1qF@k_^2vBc*XQ1F?ZNdY0m@(%F>*=yWLJeeV{iEOp!%Z# zY3MO&Nb_w)cwxVnZbuYMafL+U@mo=G=Ydv^W201vq9x$QZ=eg4X8 z3;_~fsi*LpAA1=6Wq=vjyt{f1z6+O1d^khY9tvOar_39qJ>7l}z%`s8sz1e>*i*(0 z!k%Wo17HU(0QH07P5deA2IX%Jnrm>>FVsy)6w;u0DJe1v3>DZ4Nag~R0%p>f*|^y} zmOz$xmT;Ezcm*7h)nJxnmS~o2mf(6yBl`YjKmtG+FbA-M-9R5k9Y${@H$`owjwZhl zT1{ZdWeJLxPM1m-OP@3n#2UEDmE(wF`OT8T5>t<1WYNzA(1%-q>q2v{jf+=Imxe_(M>EHOhjoGd4ImTwVZ>AbP?Dh`PsX5wy@S1jO94Ouegnh- z-LO6wm9VdPRj+@kJ8S4N;UN|moX^q)zL8{9)3@mL}QdZU5C|`T_V_dtDh3yGtXp#Gfhi- z9x50Cu4_cLmWPCiL6l+&kqXqQgcWpl zw9-^RoNcVF91S|^ObxHRC@ci8{N8ztRAD4~N9JZEdq?hOq?&>?g6f>X?&Rz*~gqY(s~AL z9b0Z4A~X6rg?_se#Tb5(?)-^yhfRy1L?b)bxlkVxmn)wC3yus@UUS^oF0(a2^FE9u;x={@lhiw+r~Rj{ z@r>ZN2KAx$fER<2*r}Orjjz8kUx6@Awb2^u-l-rX8Pmtb<4QXiy-(33^wex_sJ}tx z+!`ei7&^=&VUCeI2hS=z}_#z_yyMr4U`P44K~kJdBkY9gDe+{v>`+a>Ml>3VfVqx*-} zvx;gWi>ln=GeX-X-Ue?;-TUckB8RH&-%A+v!6lAj=@}2+XeVMm-LS5S-3DSjYX;0B zQ;jQ8T4k`DT^jOE()p7!XV!CDdbaA6AN$~jvE_!*9MoLl&2f3M@v^tH)iodlo?%>*gdDI#J3=+=#G*@ zHSzYF8_f0YXtH*ko_W$JtJL}q3VyZpe0|wjx1p{Xb4^F@C)?)Kk{zeADJR4;gU44? z#E*7a$FqdYc5#}M-)*ixee^1AM30E>xQg`&nHE|ATfy>u54fG?rnYet`MhNvt;nhx zsJ4~#7nXW@D>@q8?O+@b@R>H1_;i)JA&a6ZR}Uq9KM_rYUCt9HL*F0u=i}ElRaPJq z3|YMPUG+Rd?0Sxt`kfG)BBTFbj3RL4fH;rcUKjat=I z+1JtA+ZoL3Y|-??l3XOlmOlJ4(HF00gtazQRdw-k^Fe*(&K6^I-_U4nS>Z6pDzx*` zUmH*5Sp_kixTBCK8P1~FT4PgmxFNY=p?gRKhNP^{tN-B1tZT<>;mYTT7zQqX0W%nFR!xiU#_FioG)2wajP-U`xfS97ImtmuPRCYl7TG#LfQNqp0=39Mx4{o z$H#4Iz7}3l;+ub1Y}?ObBgZLcD;G%{q;~Wg#Ln7&2|Ye@KW|8KvIUPF z>f|sIj-Uv9hlcm0|n~ zCA{S4De)`l0CAOe&=IL#lde+%&aFlBL44({)7^#e2fCuHsvG%C8Y3T48>w@}z-)Bj z0SL5ozC-%+H1@^`Y*@F5{pKNsOU^k^HC`^ezg zG4>y;>bycrZhv?<$lTWGH_jOv5H(uEZ4`7J)%D|*sWMKKu@-O(j*`{s6ik45IA?*4`LTp3maU!y7qvSP@NZh{m`CM(*F1)i+ipJ9LOq35FQmTCgiCHCf1slBwrm_YLE|;5A!%MgYC}Jc z6su=JcCs8m^(cv9D{KGr*tW998#!11pOVJb?IBh>c-_F_nx_2n>w8ONEZrIH|J@*S zmS1S1wB+=Icm1rhLqk2>=DVhlX%Eb}1}|39gaIvjGx>5KnX9^)AOXXCS67jEdgXY} zKF{`6!*9~I%an&&QtJPfaTh5ew)(t~8QmIN+OummOF2UV`r27cZpeO-!|HLGS5U`r zj3sbs)o0MQl-8noDmKr`y(LxGzhLln;qj-(4v$i~SgCa*uC}sYB*b`DIc@YuJX|P= zJB#~v250Uy9QEGV^zzw5!?P;mdt&Wf{I2BD{ZFq~SmsbCg-_ zIhNpV1V_~R3pPr(NmX^ve2&_rsWXC7e5vOg(>@WoF{_o!@QkOEsu88kXeapri65y$ z=C^gf#DSXI>b)sB)L3H&hpkh&vAeQ+W8_6B&#??q(4V&4=}i-}WcRB5IvqrG+U3T{ zd5Hx*xRvu8tbtrF-NM?d)O;IesLX#ct3+wb@h49}vye^sft1szNZB@NRq#qN0|y}u zM~j~7#P@EIO6mdjoMv5lQQ(z(WXJO~g0oHbWY+@5=it;&57;m0LFOy+6kVTiL%Cw%+OQJ6)HjBshUDwaQ#UBB z%%OSPRCuk-0TohN@mk|!@r)JqX%#5hJFUza70Ope=gT8E^^S*somi?h1v;`Vu?>uF zP;fC^W;A)1p8AXzt%zISVhl9tmylPS>ui48P`X?S_4gU9kk*Q3xJjbM-gYj>U*N1X z7_2ze9(31Yl;=uaC5`&A)?~vM1xipIx5`bjrKel4{qXo@Z18vRPk01(P=psP#+@_O zF$LAJy4<8qdisi&ep{!#sJrtak9OyRTiS{nv+QHX)ng}-@u^X(K>vJ^tzUG>y{%t% z3H9m=g{)%3y;W+i(RmYt-LG>O2L734Y%TAE8s-KNtHu8JR0Fr}W4G?U`7DO+sd?Tn zbeOtr(Tk$}5?({x1cK8QG&^N$^`D-XX!Y-#PqTfGEU8<2i8XqH!=mm1;-}P){})z0^EF9syGwi#g?co z^FyUuf;jaB&&r^v_s3rwM1ZJ7=MTtlKN-FVLt1j`7hz2@9w1^a<4=Ykq?|;Mzq|pQ zEG&V2>EX$&EU(m!_i8^kg^N7!l71`< zW6H5ENmkUBy+AINl?#ZvK`fnA^hn*CCH9Km`=tte-PWJlV|r?nj7XRq3S%pQ?)d|6 z0q0pE;tHbsDg?y5RAoM|rf1m|P&#H8dUQx6K0DtQ3T1FO1R?H}lQm=!emYK> z8AABG5Nt)n03&4ICGe*Vuk6ea!m`=A(pKGxRc9{BRLKm0s2_zG<-MC#a3N=Lxf1L(!fPSYwh|fMY0`WlIjPDL124+?} zFy1ZVhKSw6g)1U;O~CuvG%ZlcYzUU0A@Efj1PzSA>W1@f5_bsdnJjD*acBZw&hj$6 zI0IjGLEmRJbwKK~DD^-X5y8c`EN%$#juYk2 z0BXT{=K_xCf-v&)Eaw!1{TsyvpQ42&}AZRw17y1z`9)R@%9rZx~I$?Z4m^Ew$G7AT+750L^t4Dp{fmRq_@Mm|L zfeyj}8-=|P@A^?6M4(5;7noVWW+1Wf=W1a9_`7P<2QFxa@kQd&ZfXhzqx>13qia9A zNYr~|tKihbrgof{{lI_j&W5CC0Q`@%iw)=bPJP;%=BLIdGOP5b!DnBy3F17Tt&817 z+X{b0%5b|bhlf)Me!r^TX^<36tz4iKL#-S@imp~JSc<9kVq_gtN~27qaT_56aSetQ zs*%~0&J?d0yOG$Gc=RLQj}%6zR2Ug>0mBX3D0uj56fFKU9)dJX2swBY+?nN2Y1DPp zC|;B#Ow=BX8{C=ZFg1RFq%D{Lxr5^nb~GVgS0pxg6W*Eqa5;WMC>F4Z<&1fVGddS< zLfRIziR`R9ia7csenT|&Hvvos;URK7ZalAuJqkCGGr=L`C?N?OsRtk%_N$8iRUM1Z zh}VwCAT1M82+oG*#&yOs#X3}oS0(WX&4%wlIAkByC-n%KDn|a%MA7MIl@rxj{}p*rNQY z{0XPSDp+2Ct+@`{d?V;l)|x(YmTF?S7ywmTc*XhlzFqnmB>L|kldB~bPeYc4R+)xN zQZvuaz?tt(BM<+}jyKWdC%J}ovb4X}BBBxNf^nk;@)3R)_n2^+tXW>3==Xb?ILDaLIEhrRJv$j@z3kfUZV<;SR`%}fk_yT5qm(l5dhc^tC15liq)sDbn6g4_H;N1BVVCtL zWvzK~_1K#`x~S3YUBBVbjoj-=q`thZbp3cX<^9e`b9%LmznF@Vmtyzc(Kj5gW-B;G ziP(*}vT6o!A4tH65K&OdGBpQzM8p?qFbEL~MG3-NUG2VSS=t=!TP1oe8~-D~KH0~u zU|(a%;=`btiM+$)kg;kM|LKJ*XFyaoHYbxbVVcA_aLDMCIrz@HQEazR(K7y%I4}jK zh{{gRbAGt9wMj9Po?K;Mj^vnXj%)H3(aJU z%=Lf}1({{)GVD>z#+@#%n|*k+h`sYqs3^kUQU88UlJi#{7aK#(jrJIM7(BzgRtU{r zm%Q60*2`BFb%Z{P-+IBqp1%g@s!rw_wW;*mmjJe8er%zajL~%b4&n9rIo3yG*tBSI zbkvv^K(74ZB!iip9DzHb=yyQm%E>RtPAL?26%0s z+}58c2{o;KpATPx^WDz^)`h-$KdH@+*QJlT)EXj$&y|PaPd=DWl%x!WuuHc62jZE0 zwGUz@-EP83G_V>J!hfk?BYwEY&CeDu;_nS|ej8mgk ze+v6ggvAeHM%}G%pLypopDqM%hU9GBU>gp@mjMOqpC+bNd4E3@eGUY30ikcq2Q752 zV1!E*g!HO@Fp|9kiO+Q^cZhQ*PqI9s8gYmmJ*M= zkeVQHW)Juqu819}W%QV2B1o-0)ZKrq!kwwV5Z5lird{A~ATt6m!3nlPzMb$wdKSvD zfPtCYKYXJnOkI^`eOH@Rba_(iA^9_;XUX(KU{_PZtYkv z;6H0&AoOhQGT{sDJRwPu)ce|oY3enU`i5Y%8)0)*iOLNk=8Qzc07+L^6NLoF|OIYP&L1&(8a(TqzcMo zB-$SH!at-f3RGGlPW;2UMfz<8lTN?a{M0#%3$H~ku_GFV+h@!1HrO1JhaX(S_-b|z z8|=`lr%0D8@br%6211dzx>R|~RCzT^dq$lfDVB;`(dZn?nz^QTy>7o5M&bUM<_US( zahlp?4a4O#q-w`t^V9^5ugbBt%khU`j}AO(fzE(Oh)gb-eF(fQQKo0u)okUTgrA75 zJkz^Fx8HhWaD7LNpf~#2(y?;;++Cob=Tn`bnG@iC8bkLwruQ}1;sVw{@|k__Ev7xJ z%lDh?ha&y;HM}jdM|T?@$ZYN7OT?FBzUK^ya0&WHW{o+$gqIgKGl1wT);*Fw@A}Al z=ZK}8v(Zj<6s>;-`j(R#yX|VDJ)2l1KJyq0NxUue#cM8QHh!DO$F`-ZquWL(FP(!~ zB!z0kooEZ13~r*y$f9H9GDOLP4aS2>UpA~_%jAYC`FlGV5eP2wFD_K*)4sB3$htXD z`=%Q`AieH>eK?5e!{?1?a0?HG$EFg~$>VUc-ykP;2a~LQBqJpyazvi2jVXB4r*Ej}wo1B1hM^be)Xj2C^q5R^5wDwUOLi_r~Pm_`_}?55~S6@F9egRShz z*{omYUM2?u3m0&u;3@MdbP;yV9T1)EGA+H1&)AVPJ3jLy4wi^9UJSgI_dhCX>7w*T z0lx*tg3kLv=bdGOY}V<|guyJ`FrQMrTMs$w{H%U>z*p}1yan;N#5uzEj=7M4h6VCn zAG42|7O|Pp@(rCT&Udu>4@tf_^?!Eo_XoqTre&;qi(-;x%fEAUu-&coS1VSVOmb-a zyT}jKI#OvK^2XB38SDH07(Q5|Fpf2q-4hT#&~fvrj~%N;s8Gq|#%nfEGg^PtI{NE; z1YT$~q+Vp;-=n&^Ipn5}u%#_q9km%}6Rir+yy_qsV)MRqGF_Z^*4Lf)_tYZ1c1o+- z=GggrQ6JLt^$F^M5865;tXA+-@NQI=c&;-{mxkuZBh7eNd-kYKJ!5^nh$us|w~8~` zsK9zn583NcCVGfsgZTT6e${zwq2jILE3?8pP$f?Wb>o)U!#t#}4w?F6(={(;7`?~8 zhhI<=aeFWG=xNxa_|5i+zCYb6uPx)&w@lA1BbLdk9d3J;t)GsV7TyWD`ade%Z5Yy( ztxUAm2G>*(+HGxhFFXbU4O$lBCd4>{fu&bD$Jk413WB5?oiMFeZq4^Xj|zgYg<*>d zg0vX?h=r2IT<`Tf{JDvCc7Zh~-bqApf2nY{EYyvOu?b^_?}6^V#?fz8ht@snmX5<-ROlte zV1%42#8K!iSBT>@)0O>YWA&v%*|Oj;CMHi}9lHmbIMbBePPMBEu7M!1E8*oP^m04= z-m-8#Dpn=zs`WLO_`7svJ1KUAD7w^K>+5YkWri?w_||1RNf8PVbEiMD{Z%hPuZ=Yb zM(2gOJnvZH+Zw#@L2|B8;k92=!h81nslfIeYqhhb4B?+XYIm9Y3wZ{R33ZEb;Pi2c z`@O;T{Ku-!&O-LbH!#rVHVdNyO*lTj2g;lVM2{9y;XsBKsvH-@t>=HTj>c#QjA#!%`A8 z=4-^2uMrhmTi9$b=NCYK*Fpr@(VaU=Q1>EKQ!%Zy}R>*prmq=2za+*-5D9&*~z@ zKoxWim0W|620}tRMix*&+ZLvqq4L}Ce|5+j3?CubKTH*%e9ihfb zz}k2dio6^n?{S`>`X`8TA&_QoouiuDZln5Z`n%m|u02k0cc8hT>r-RHlftX+7g`|%++z48b? zHuiE2?)a=UZp&GnB~M%N4d z%uFSA)7WWF|ya~rmGRJUoHYSs1`DT>aV8&wgZ zx_;Y>{PUeM>u`^r9cvz)`i%!T`P z=yXLgDO0t8HFc+SKa%ZoL}uVCm)KFtDGJp4Svp8CUHKn2R*Ld{!W0oo6ZN2xyW^(v zJp{l1hH}cIUtQAe$Hi3UBScDG+&w$@@dUf#{E>#ai4u0xk5#_MTTa@en!R>~?mXKw ziK!gdBsUvah|`Cff(9u0O7|@9fVIOM7B9`@u>$YhkTIk2JoZ_b(Vr{i`y)kUL`1Qk zfLm%L^ujQA*{~hVS(tIPI;#ljI$gutAFX65GVGoM-K25gG^NTMLF4c z6ukG`+3UdF#h*rHtw_8a<`~)I;V<8QMXM{0{aPzAWTEVpkRQ|7qs2Yo`Z{6$V5%(j zlvGnpOHVZVp&j==z$Y$w^}^M<8dYEP zOFQnFmR+-j>RWQM{v3ny%}eN&s^#9&pKnWg|4X=j*krP!Ur1c&iX&6dB`Yx;;OP<3 zTTv@_g2){l^&>HD@Ixa02h)`U`2h z?&Q*9()HzL!M4@~iH{>Qlg=YI|0>(?kUs`|Z*m>kx-ykFqS!fMM5D3b_mR4PRpG-E zV)#O!Z1TCqRR;q8YNAd!);Svz?`}@f$8v8Vt6AZrFi6-T)V|vrNHs2oFANfQ2)%;4 zpOsIH@c%X!*Nxj*wkXP}P4$8y7I1G4%vDCwPZdiJ)&hpc;pC6Juv^I%ueTXKo~IAzFXb_~PaNm)Ti7>mhPa z`|X=}(*HBFla=NF%k13JhY=ze`JS`YJ?vB{1q%ld(pMuz)evsP>_jI0OOS7lOYA6R zF(;-RRkdk4(LE^NdW47FF`N)#GQqEreRf5m;1-v&pJ^`X72v+Mu>l_T*GlH<`b{vv ze4CkJsOJTp8y@Jr}7_fz&c!}X5L z?*^;3`f2w$#A*p=(mjiGH<`D^4$Tv{_Awn=*q-yI7`H>2W^dfBpXA9rP&<-F_3iik zIv(teQBXU=M!UtX$ejffV8Z#NgnGnF!Yq>=R5wBf1un4sDIQscE(GI8i$ zle9#MI2%4#w0sJOaAb<;UXh~WK1>ty7e8DP^A|mA z6Z4lmlqYjQ^U50K72Bq~B}#aVc*`Ay5fh-eg&_-|P&-jQRTTS>J0vF~#&`xWd?w4} zC5Y##?tY3~7;f$F4E9P!e4_S}q%cRkEie)#;Fu-~Q6|Wsqv50RqQR(hRUDF`i+`~X zWzzAf;Ym`2N-^-H?3ZJH(YjQ~<*R@vL<~}?SfQs-snSO1P^enLCt#APR{Ttnu~OrW zSv?(`CUK`~XbR7fH$_h95Sx!MMIEC^6sO3NLQe2nWJr^_i#S9Zqizh80!uInXP{^d zA2lYEE!QSZN$n4qXDxHB{#&Z1#__CymEv7RpII4MNskvvH=c<%apt?7X&nS-5EMgy zdUkPn=kdVtvhfOmS&snulW0l?@9b>6@;uA>+?wtzQbTp>H+a<7R;9|O(oj=ZVjeGO zNLWWlLtVpg`LK$)(%~lI%{6F9Rgj~~rdxeI^2vr-JPuBxez*?axqnsU&-(Ec;kidN7nC$rN|&QW<-OG9mHD#`6BXZ= z&HxBfp4kdoLj62J;x2chF@7P1N((Q-%H>8Of3s1)uPmyeZP2j9^;Z(sz>O{DE{B?0 zYo4?J{pHN>@W+7qu!a)|`1Aa)aaOarvlV`NjGl6D*wIJ;JNN6hi@(3+!K0R7W$_}t z_H$^$=ojfd{HO3L@4{A&Y|b;i`sb~b3|lqeaK`Q+e)9Ox<=fs8;{F=66H&wo&fqget_>PWnbha5P zGnrGX@SpTSZs>pL=raSfgpd@#G!6-;(?ytQC` zbrtrNRr$Vr{O~JqCT7a&m*Zq2&eg0=OKIw9o&_3ejg=LD3OWI2>Du}UZINe?K_#c> z)=|C!#fEn8GV1aKDlyp7@*=@!OK0QbW9_;uVW*YA!Y!dRksZ4EcJ*J<-Z319^TNM3 zAdj`ME)X9WvD1@tgAkHximNyR)hgiKp(|f`Ga>lzKaSm{hBe(LY;ZI!_1cX;n&1}>n^MmTwNQ1 zp+#zjVGmiI?>3!^zEQS*F9+x-t~$^Pxg||ObG554nHq7fayUYKZdj-W)lF>?rm76rtQ~QyNl@0`0n^9^m zYaW&OaQIhV!n^m^?|-zm3eC({CcSOEb>#Hb>N!~CkrgQrbdO7Y*_!+7gi0&VbPaBC z18t&bO3J+n*{T2e%W-TSz^Mo$(ARAH@F-_fkaE#HDW|9BIY8LqzqHq}^nQ6++>@MF zkK?FB7^L`UA1`VB=wUz3C~VmCclkreLN;(9PFV@NrS$>Q8_b{_0G2Ahdujk4ejfXy zNCSqa)7#w{A|JRH8TqbY6sD?km8|iLN#+q5YLpbBANN;5Nj8{1;Z~nJ2k)?*b=a2f zV)C7>wF408$o`Eg+x)Um<5C&}DP{VXuBM`-0ls3sGv4;}`v`WL-KGAAK#hR_h+y_0 zlJp;Vcn<3M5mbB^38&g2)POhAtwFbeex2}km9PQoVK=fy^!Z|XgZxzlbsM!_ZuS)t zr5-oK!f}07chzr;#J}kBEu$xmqKk|0_&j-`Hge|e>j z9e%*M4JeWe#BH>?LFrmO94(D=OAZVIp{B3;Fr4+YzPB+gwzW0YR8`twv`y1Y{!k2y zulBSs6f%it<63nttU&J7x`+0F3N|g0%?+tYmwK?Gq9V?#mg*hoEs9jUR5-Q45weN} zo1em`0CY&SmDAvE75`+0J{E0$} zqRztu1=He~gg?vlppK>m)|ZZ-8rI^A30&U?I~jpP%G#s%kVJ7NaC@hS5HOtu<@WrI zEfm06$zCzXymyxBiI#Yd-rQVTuu!u;k||Ltv}|#|=WN6GnQ>r?^nN~C4!eqRtNByg zyjW~6oTV)0Lg#kGw%~A-Qc{}py%|^B75r}6*BnX5%dTR6%TwRZEr6|#d024B?tMzi z6+V7@XX8*iaB*M$3}8nU7IqVwa5j{dra*L%Cr|Y|a)4F3|j+ zpNQg{NepRVh%Xd`P(=!}4VkO3kA}AEaonC`=71G=D$YKx@5q_p{^k>Y4YQe)=foH; z_EP!rF3}`f?IMt?#orQsFzW_=C_g$L_+-&9ML@Tsq0`Ka!D8hk~oQju+sGJ`y zDb&HdUHv<%=6SLFrCClhXMRg*`4hY^@AOzw(B8yg%L%Wws93* zmjHZBRy>AE4T=ef>rgfBDFJNbxAAq&|AIrjKd9 z`m_NKtwb-*>~^zg_Mw??Ybq*`-qFCl*yIeh?P$_C#<{7_d7VU2I`mXbRh6v#pxc$I zXcP|Qe`;CLci%c4k@~TI%bQFY*P~rg(emlsY_ZXn?P|QgNKKnKS|x`VXp23Wb0jiq z2`oEs5w$Q8wQvaV@W3Y9(ODn_?vc`L%%KBIgH`Dsq$vAC6eUqNb^P;q>x1G0$MQQV0jn5Q zo%4ic>2v;h=u^+QX64mD?loU`M;Yo_DS4tjx;^VSM~H-XF?(oXD2d*bRR{DhxUeO5 zg?4ohyF+$shk7bj(NE4N$M~kwBx#Md` z|0@faH14MQ1|sf8wfTE4)dQ5VVR7wx33A*`=M7ujBCVTOvAtE5fF#cf`DS>cBSwO5_$HO+#XndNR3GdF2(haq`sq7Z6f~ds(ZJ1T`?wp5hMC~} z*E=+1W5dL?Zbz;Zrg$b0Eb%xa(=9A<(zpf5zGuft6#u?h#{;@C^L_Xjs}F8Nn$IA+ zO0I$_Rl=IsG5Q$E7pe%8VoKoaSfJ-KCT$q`I`CDIG5vxvWcU$J5zXjUNm=@*Xk8T` zq=I!mw7Xc^K6TS_Mo+oCf}~1+7sVC#=ZJpDByE@#!Gpz^jJ4T-v16eLtW2DL1~OxG zdDX_*+RxUN)U$gi?zi1<%VevBlK?o#M)3^ittBwxvAllZ>lB(h=sGovc)^1G#1Fnf9 zQ8x1&H^zb2=G-MVKeE!4Gnmo3b8>=m6Ws$G9KH=tvx=&zom2Kss^EbwnbH$_?(7gA zR`D=c#VQi7|Je&`^v_mkB8 z%sH_6c zY@R}PiI;C6c6*EVh`~Pfkv?gjM%cfurHr$A(z{W#e4_3XEZNJ0{)`S4#CmJO`|#P# zTez9pMX`BOx!GB{nF;v}3jHK~BDQ)W4*84-{iJ=uW`B#?HJra;4haw+=!O5_K>Fl) z%CmaP3;FyV8UXRe%<)$D_fu!!6Z*}8OR-X{xD^Ts795IG zCu5&}ULF+sa zG*B0JggMm310exDaz_NhX=r81!t)d7F)ONfk7DLm;Md?IH$*rbPdFSE;UN5|2u~4y zw1;a6hch8+X(MS64kG_~g$h5efvDUN_HZ`ZLGtjTL_RE=%3aggTX%#eyiquuVosjU z%a&i^b4(4f#7pS$WOyOYj?>=Pq@o+~wI+-)7qO2$0(AXW;_01^R+Tz%0d{4aKZ@x0 zZt>i-5D`T4Z;I7Q`){qNGnbYU1J2dHXp(CpZi2=#`fxhqH5#Lm${+R;)*kyXjCj%7 z9F3|^?3QkZteWfdF^c5pTRpbER{=x;{5X(KtfJqvlx1Z>nHyMzEJf+&=rct!AWL-a z2-~Pq^2?*q0Pi; zijvW}*~3m1C?B*%zbt^YG}0lA@>j}jo+cpbNW4qBPA|fJ{CdWOz>4>Q6=}lrs_sWj zU3k8h$uR#)OY!uc&W;bBq~-D6E~03)7K3Q{7tsfz#~0*pFTYdb+Nd=v%gS?IVi#`$ z>U`S`#Z_!ymePtC9ft-_=pe0WJjMvdB*oSl9Q@8|xGR1U&`Gewj7@)OCD{F7+5KMN zF&|2G{sA+!Kd~0u!yFU3&s>0q5~`-Cx^kQ|xr zW%dvLi3*2`OPgv_ZBcljKh(!05)_aq0 z3k-r4>t9H|7|&%3I>V?w_zCA}gUGY^LF}@`kr*V^g=&Gk>#=q&)_bAec@ zPgUq@c50%>EY;K0v%HBhgiZBty7T^EDcA$ z?9psCx=e|6OQ4Y7Oit;k|EqMi042}SMrXBD8(PxLe7&9j(la2Sr zgqa8Jed5l0g&eaz?^g_;$IWD_x0+?R!gW6w7x?$&GebD>76l=XK{)!Y3X0{ChUB~8MrC+H6s&*HCrJ5ZQLq}%m;jw(;NQF7X8(?$z(*- zDcXthM>|PFlcH3tiy9pHE$p+t$u6@O2esqTv(D%<2S-&Jj!3@x*v4JaY>Pj{{D`St z2C35bRF+?BHFKla%3bZ)Sj5cd^Kwk7AzK&BHT`Ire#Ke;q2Eq|pS>O5d!Vd!ig34< zkrUi(6!(T5iwf2P)oFkAj(?a0)OyViyRFVryN7J~$>{^%;op^6aByVI)7xHSnQi|& zWj+7M>6YR=&0;a`Nxg8Bcvz9YIj8?MW*pJ-B~dVB^DE8yNG@vyLq*Q>I(s37ja9g2X7+v6obvah8nS z`Yc}J4Q>6S+<0W?edohevg2I8*zd`n9^gBZwQb1v?t>Z1lf}kl5nl;J%jcz(#D+WO z{EFo{=}VuZj%UILR|>IRbYg`#I)dK_mbh!#b$A)J-Q`S8dAZHFl+3NddPyLnoA~GZ zuq=U&4f}IFj_F;Rpu(dNy`XU9BXhoxInM}!MFHUuWSm!!A~v}M24cSnDI7zvcv1x5 z3Wp75Jip=lhEJz+HgjZf&40Q6Xf0tyS5)Sr^!h4y{}N)KJexRFaK>)_hT)y!r>1&Z zU^OjpWR^VSgkEqR=$}4I+fKrvQ%{up=P7BJG120JODvTuFsGv#;K!>{I&B`?JZ%3h zs?7P@5Z~~hr*gf^4EbA*-Fc-iw?phLw@#_y-)uU~tS@xicj!(+cMcu&yD>}urEza` zC(gDuI|TU6j0((mTlZ}5xR_no+~$3`btAiGVKZS=3-mE*$}pC)Ux_gbVlw$jGRnCa z)*-Wd>s*lv-EKm-Ud(!Ou$a^_o76Fx)UlZKZ~V{wtD{Wf*S8H*#zx(|u6Y+0bFG47 zrMCo%Z+R5EGql^R3;VWi^xm88xW=(>y^q`Tlp74T z|9|)LBuc;9{&n4Etrg|`HJ|t3*4gRa?P=lrcFDi78@r{ia2K&CiYL*|#huC%_%^l(Hfy$0bXU{VDfNdg@q}69Z{EU}w4F9FD@QYo^e!DN(RVGvizSrqG zX?;0@+AmB5Q$-U8hUFfcgwf#q^%bg8$@np?K7-xkT1qYC$Y=knRpll&gU;2O9MVXX zB+A)ihEo~hr`rA)|JhQE@rSMp;R6l#k4W~nck_!|E^P21(tldS91A(jL6ktw?=4v6 z0E~HM0Y7SK3Utp}hItB502|yAL)!GsE(wQ9qFO1wv<7auqu&&N@Bn&~LBc9-X`LiVG*)@+&DTOYR>MsKKPF^n8*-oaEA6 z$X%(*l$(Qu=zwA< z`}^}`_HF-UgQ~PcfZuDvC?Mt#`%>9iSdtkH8s8<6M(_!}6P2_H5)>;z%D1BE46B75 zU!tp-?NNK5ec8DAQ^uIoR1Y&TdS%i%g3FQ4u#v3X{{g2N?kMjNt0n@jE{5uB!#}eJ z8<9!#+dY_-KsyMP6FyLE62JdlO%N~c*3|sDr<-|WG+Cx~Z{WKHQ(#6H1;MHbYoVDR zPgAe=vdJ$xB`)7&F^g|ZykFXy%(;9HQqD&IBx8wwHyM=FmgqRqxF!#IgHZk_{D=Hg zeO=M!9rvgD3%BkBvV9)!pkdPB6N2B}t((0k&K8esSUn1;w|Mwx!+xmU@r?n;c2zta zC2|3n9gZY_QH($T9=f~h=)L3$efq`t z=h~$pMZ!{_`^SOvB`;CQX|i31RU0>i0y1TFIdfDD`rk3dbohDq+QqN>?)u32;4UEL z931a)7eFXwz-E{AR83(&r3#>DXf?)rjL(*eP6b*{su}+z5RGbEF}_hA-Mlf z!+(34I%M0&ob@Q8>K{W;J}vJ>h4Qvs+CUU$$TRoVlY}T0H}MhcYEY~1 z=z_9`vyIcJd^Ak((%X$)?)PTUE$J6A;&L1JAwsG!-&MhX{#L(g%M-wPaD^LB4mt3= zu{r#@&3w{q*=W;$U%%ZTH^bFyAlK1QwyJD&k$S{OGIDo2f^IvaVC?I*LyqN;%d0O$ zX0-oJk$fXQTjx0xrNDCDQ$0-dXU^@)QY<_No*U|4)&~Pd)R_uYX_{kq?zQFqcoM!l z7hTd7D@o$1I{8Z?{F5v)s?$N-^^96Jgz_DyeqXLch>;+s8APe6qp+gNZwbq6&Eg>C z&-nt?8L`g_&tSD+kq~D}TFR6&tlHnq--uT$qqxPK)amm@f#bwZ^R+?2`}pw%q0tt+ z%~zEN2g_8!9B#^tZLof$OUJR?NT)v0gpx%=)_KvT3G#4od4i%3b~v*+eHS&f041CW z#D|W|SCGw--{J9ETX2;R13=nP-!bB?%WkHjCcq$_arh=hxS_B+UV*fsr z^+X#ci&-Fw=aFBR{EO{FrYkZ#{F~jpS1F@~9w8asLWcO7mGFkA!*}hwBU2gMJKu0s zqH|%#%2&f>^1XQ2Lxk~lptw4VP^2E5Nxbb8<6FRlr%h6h9)EW*D6k zd&ql2(J;OMeV0N$n2p#PBi=MaX82(gJmlC$r|oK?dw{LWn@^&1gxx{({oUZpimIeu zMq(ed(Gt{46H$><(OK#82F2ILa<1C7hKcjA9L%Fj;&pYofZB^F<1H7?-X-yK!=ToCjR-;8O4DZ&RL`(4ipRj$SsCpSO&Xs%- zuxIupqW5)Nz4I99nIpOdei^V{x3Wl8L99WgsFf%}5D_}!7WFYi^wnvS?|lX)IO(~I zHmIvSF)Z2YP^ZE%#q(s&CMR+c?eSb4JcI^sL3{K-d6on{1EEnQm{0XB_>UcXG`NVA z+`Kg);nQoL;84TnH<2Snf7_U(w0uTNT6cNY;i8_wSfT?EXSHuFZFcFj(GuZpYwbT+e5|D@rNV z$s-2ecxnD=(ea1h!%2JQpA5(E?q4~yNITt}+W#s~rmkZicYA*+JQ|Go$iHMi)vF`q zRO&Bmn0QWBp22h2kH=hkv1N`@K>(LPkt2d0p@&-opc(FiOA$*~MPt%_yAy{vx1{TO z*mU{BiB7F{5+%Q_1%8F!-kHsk?FIj#+;>cMF>JY^qL_U9ny%BqN3i*ccNNxx@{|X< zzKu_>$aIaGMzUX#kqXi3aW-|*9+bdd0` zp&VL(EQt!~xb4aV$oa=6Q@6j%u8|)egch3m7Mh;gb)z_Q*wPmRH9} zQ1CBt$3CU;7rveT=z}rC0Q!Y7BMaKXEZl_19xw64MjDI1p8i;YSy+dDNE6*h$3KrY z(}9$PkW$cpk_~nt73$$wbO?^EHD+N!M#O^48^FI}{z5{ehE@20avcg9K;^$hKh$<$ zyy>G<7!n13a$2|m%=DvNdxNA=3UAR4Bajk)%10Y2!X?3DBJ@KP+ej>aM${QK)a$l3 zqR@O~iE{!t&;s+HIp~qWRu-!;3H3Sz^ax(Zl7TQEuO*Fi;@@jU-wE0dq7}BF9iBzs zbs)pOs4VzkC%Mtw?4TW9pj>N%!twZbP-osD4?kqD{u95?@`!ZY$W}|z9S7)9$TkvC z$cTPe7kyX6He;oRn)5bjR59h_4!PaJ5MU+>?T|!NmKI$F_AkTL%`s zlxQo(j?kPXZJkk^*=?QCo#zTebB+!*kqTv{SO)4$LUbQCKNY$&lPxd(8y^F26N}*M zzu4c*(F$v$%`poPqWehszd4+0mzU7-obL}w+)LdZ!wR`*eN@#R%oGD%XUY zn%r1)vxfeBo+%qR?&+l&WEn2mb(K@xNY(3pk=u;zMEBVG>X$R3xyAij*RyLqu~!Ix zV9B43`70i@A2pH-bc+(s2)b26dHUSV)ag?J@6nkP!iXwhc%%?S^#6hCq9P1YpM<03 z=%Me>AB#w$cZ4M2d(Ka>BX_unoZJHaYzYLqO^(><5_b4u0(w;~#4s{2Ru8X~yDK<#FOM2T7^aO7>>1<#b~7X+mf&5*KtW+Z;?e0) zP*8mQUHClTxx0As`S?0{BcIe>3kv+Nn_;twX$z@7aXHJ&j*yMvkXGaEhj^zQo!RaRP>=_|kcT2KrEwLp6TgOHK9&iYW zfvn=nzJ*Y1uzsuq0D_}KT*@l0;#&+&rJoy?peyYGV_^OqcnwrNV^6sR+ENf}+{hpFw`2C+Fy9d(gl8CfM%yG0$G zk%`@U6&Hs1VYhGX9C%b+K)1zm^*#1`S%D?^Biq-w!4PldIuGY?_hp!0lCSqg7-n-y z!1rjozvyx4c_!m^_h?JusC;ALjtd)wmC~nV=ya+HO5647L^^hQL-G*fcYB1C!CNOp zI`6UrIJ>WfUS6!&Tj5(|ZZeh~;EAL2zH=KB#%zu(T5Jh864A`rzu|X%Ofkg!Bj~Dw zWh2E!?VmJq?lv}DC*=A@*02HOQYv;l3;HQo!sk>p`EeVdK)S4f&mHkFYiApTTuyh2 z!1zG4zldY~!54=_X7-__#GW&*NZB zf`q035svqF@bU;QjIX`;1;ok<6o_Al$ZG+Q>}lIo?KTn(p59{h5_~DEvX!7s}yyu1LsWSig9O#z2Y&-9WL-tqep^tgL|8O{(?@MU(x4beqEw0Ik`|^+L7huq{VZe#) z-B=pkrO?2Z6@zS5;kPZT`ogJ=q!MRFYk{y!-y=Tw!uXmw6iim0Nsjk!ogqI!Gy4`h zaFcd{9{8FA7X4zzc|lEzEh{H~MY-0KHz$iC&&Hx;m*V%!Esvb=M0`5SKzUM9LSh`& zSo|2pkBY;X1wdb#FYC|-bV`t7vh`_np5q6{+R5yR?8&Lju4L|nCT??1i(c*|F6{q8 zVxv1G=qv+3K@I)JV{1-(jKd$NFLnrI*4ychEao^&_g=$TY067;xwq!NMo`UsRNMG! zPjW+JZil8DtD_86wv!?H`B5kk?6V`fK=_q;zoSB4Tf_*fWv`w3n`p0RrKn4>w7L1 z+BPFxgOAqS{SpY)^wOVfR~jti|HV1;d@5UL66XfHwu`GrV^F~Rs*=dVCwP#BWACVg z8G))Xi>!}3Z^`UWY9hfE5e{Svm{(JuZ(Q(n%uo~p%34gspmpe=A>AXCYxY6>g z7DtnVSwe^5Z5P+mxDDm(zXc2JavD5xikLqnet%gU&7;QR5q3N{wD2#T=io?!?YIr)$i0R8~vv@ zD+fZz*92Ehgv$>34bxogSM;e@1p3?hK_M&3gVp+jY*RfA?cot-hL2-QBv(!lPXlGG~z}|MzgV=T#P>BcBl*Vb`+e-H7`{wd=(vaCpAMxzLDGjjO2)g` zWBM1=TjUgOO^r+;;gm{^1Er%~72TXIuqWRUpxnFF1^+=Tk+9iy6eWy4bi6|`;Z;@U zu8wB?BmO`h?>m7PY@;IDCQc5RN<}{Esg=?nn|En&rW=eZw8S*-ncFm&bXCl>-fO;I zcKUKX=kL&5S}QSJT;5PYr6;TZZ((GD`bX1HCSM)_nrX7WUX0CEisDCZ$ z_%Vy~YQ$!1oy}J4Z*Q9^NcI<%UR-oErZ;V$`KWek2^)5=pFBtb=nrd+-Y`2ECqY#c zPy-17-@)RebHv$fnM`os`;r|v3y5j;Nz8tilq!h&kf^_`cVbjxr2RFQ(oJePH-tec z5I=d!cQAMLhDTq?#I<12;Kz?`??KX|gzj(E=-6fdavkH*I%w`662<9vqYFt&992Xe zUulW#JRC8_FVwylZ8gzss-rZu)$y{mjwjTK4Ld%C&mP$3smL6zUL!r?Xlt2NrS|YH zzY6-`67i9n8|^of-Y-%$a7Anl9IFofRFG0>zzEGgby_m63EK>0T#WGg%6Rf5DieJp zU&5dq+N%AaPSkc%S(CJJ8OnO%Uc#Uf+NqtvB(wSnlEvV&M5eCWd7@Fnv3Wyo zR8`7IeD#`Rp8QH66j!Mw_NRPGt*QRo>C{q%{K02O7lRCQ$5#y!`MHd?&3771KZ^+! zc~q`0nO#2!hQ2+PeZ-ym##;-4d$@)Wd`ZEG8-GcWGOO?){7ycT-)?Zlj!=7aN3l@r z`}OfR8=Ai18>%V$r;N3G#uhy6&rC#}@B;aB#TNS>o+*8-eQDaMAGmp40OCOG;+ob3B3~Ic5y81Is`4!{^Dm zS&2Gt3go?TW4y^0%A)Wb%bT4-G9!E|*<`|O;(TemJa{XAN_3uv5&SL)WQ<(m_9C@T zH+HrU5*@h!r#-l)V0{KDeT6a{S07e1Kl2i8(+hd(R|lTT+XSK;n}@5B)1;-UkBR! zOwG59Dc|Ld{XA&tt!C?$dSbr~V@AktF@AU;^NV`Y-Ad6S*L1S0#GXqSJ|5CoMe{PJ z;WX1S5?G7k%&lbuN&VvumO}HI2t=F=QW)h0H&jprg2rl8XH?%VUN^V`3( zC1R6`y;6wF=k4bRpTUc;oq^lK*_rdJWyV|Sk1sXL&-8jEr<>>AHU?w^N0$4%gRHan z435|vuo|pm!(-86710#16BYcfE1j3 z;$>29HZxUUVlWtxM7&G_)Ffs#)6vsikSAs~Q)tb$rBEn@^2d(g(Bhbo36ltubrJ&= z7Bm-B7jzaBS`%$~z>=|l0BWQ_6<=Yn03eD`7Sc#1H668rcm8?|4VqINWB|ki3)99J@s{=l7ui8+0Y5f@iYDO&=81pq<^VDDE=|`}= zO7y@Y&n+-k&^I+Y<#GP=AfDT%7-6L!V%sLB_kJpYVw*E6vc83P$0lJld8D$YTEq|# z9)xP6Z)F@pPj5~SuLO?^&PFNJ4^@3xurWX2;eu-?+P5?7JLU{C>F;MU>r_p!B^Xvs zuq1Hmzh+9%sw&h>4*p)SDOC-!_Q{w6ezX>Xj_Tu8#u&o;7vrVrkW_ArtMQ4Inf@u>vJ;iN_D9KoOdXs_ zhBCkO1Xrl|~5)Mk17n|QhkAfhH~htLKcfuWNcJ67)t;UdwzWZ#sE;tnlK6er8vD#p0=YdZkXRiz&3Lr>whFz+f))562`5+}FduHYV* zg+R64jY8mz2js8s*3{{e2D;(zoYAarY3gl=4`flX68`OywwPZPYf!pAk!_%7ZNcy{ zAUj5wZmKG}CzxsVVdoh``r4p#_!qdRrJkAZ$WRMBXtVcz2 zE|_hws8(p099WG~DjJ^)=^W~1;Je9R{QTm#ZBjPC>!bKiBby(~0Gqo=sET{1#$O|o z96RCfT#3lFAupu*KYuBFAr~en#UeyMh3)sGWSk^=qdR~1$viQICg@jeuN&c~)L>}t zSDG6!{{_pynPZWD>4m-q<#~0f`O2DwyK%|gB~_lXE%c2^Cvx1GhMpCWFfDVSX1Y9+-D^*W~Gp|p#}cbR(ar(btkwc(~IjH~vr7u)5}Rw-}y5BCcmTWjm|*_0j=y6#?e z7tIp20;uGE%K-6%(hs-WvoGJ;)@f-@k;I=L-7<3Vl5J0EZC-8+uglB`Z@auaXiduE zz6yCT*p}7*>=GgB(%~+0@Y+m{`x3y9^xY zaG4&q;zzhtJJQ^5BLi>Z(z2b7)sTS;y2zNy3a?ylrJ?ng=82JA$mai?|7&RVWyXo- ze&oOA9Q_E7X?deb-V9tRUcobr19eYBX2@hoptCJY)lQExpGqCyc;3{2>kGj}leWAk z<1_aIz7%18srC4$HX3uFo!s=aNJ-$q0VxP1v zgH%*PK5B0I5B_ZKOE44rXHoT1S7g1^Y{o9+Pl13#*~#jd*pAI7oA07lV>(1<8BI7# z?S$(zz3Dr8W-F#FlE1es#wj*^2ON&I*_jK{$z+{+AouhY67R2YZ9s2oWrPF9VB-cr z=fKB#Plc}S>CAH~Z}sZ*eySh6c;AxGOULkjjJI^rwUGL_WxXAWpHhebYBIu9D}U%7 zeHvTuQgcs#FFIA;VB9P~tKz<@dcpC@Lqv`4mMnBk;L!@F@kF@zm;!SBj;+bL`nz(A zI0glYTGJlBWl9%rTE*li_RV_biqNu1Lapv@uHCbFr+28HSi`0jkYbO1g2AV7WRclr zSBaf+qln0$yho`G5bD9F?9jZrj9^}(=X@S;S|a{$7;tLUmXwh)H{kN(U)}<_OP9?S zyyp}odaa$PQBt^tFIEn74LXeQU?Tv@Z6F-+>``=I`i7$2wDdMa|Fr&@l2qUU1fVIbSS&`W&dg`LLW`;u4ET-Z$#B9$A={EK!+LcwM1bLOItuyqW7taR%H~sUnASSi_^Z(dH%EYat=JC{zNl7)<(Os9FoYTS|{JEuPq}& zTIU>QG1}oB9vXkP>Y~i9H~Ki^`Z;wzS@^wpVY5r>Puv>&wIu*UT*?Hj?51u zU#!y_bIwsoyT6C`Pl!i&0@6U}Ey;R~9OvzB8i3*SvSFz!#+n4qcVl|z5uO(`HYnKi zaG!VO_&afi7X2L{Z1Fut=?|af3W{JZ66|}Dk3DD@+bBYbE57Zr7fqOV>$5GmqGhLg z?CT61zgOG{oec2R3V#CYwB658v&5*IRxV}A1``eve%;WgEC+d{4=+{t?6E3uCn&Gh z98bzz6285Ey>_U{z0)bXl~yDvwMFg?seb8l82rn4IrcD-*yQ)3ui@t=hd)<(9>%^Q zEbf@OqH9=m9iBHY;BfPy5tk>9&|n@yKmc3raTXpPmOo~av&Klb#(oWeYM-JGZc#Fj1?)Z5W6acINf!SYX;c!~?dE6xD=H$=gS9yl zEb?BYg1(iP%hkv^FG#q(e0O5kveoNs^M_Jn$JBzW_GkA9yb~*r<8RFUz_;8sI}Ehu zx)*e6I-miuhbHW9=9|BITt}tNb(NpeSDF?`yxk%9aphFPiLuRh^js$K79$=Xm3j`B zG*WHmPFumQt^{Awh#}#1{Y`2dXXp!RI7b|3YJr z+Ag;*O>SR0-O9I@EhHuu#|WJjEJ}ty83>1;eV53pZthwg?^_)2yBZJqKE7(91v{{a zYR)@(?3;wN50{l1)h7mR4xpI->vDT)%A*+=nlhek&aZbfZWC!q<7DQoy))yTh4_bD z{kR!l{QT6RpV7$mSyKS%6sHV!?aZB zSuQfWo9LR9wB*;_w?rxP5F~EgKUJh?AJC)HKQq>|pi)gxpWQ>}+MM3x9$6Eks8YeE zvmX4qt6takT1~2=o&8t)o1f&?-?zRNH{0N(&Hnind#Ja!`ucFC(7>o*cJ07DNFv;- z+@v5ye`|EZx$m>j`NtH4_WJE*y^`KZeO}QC3flc-f~!tUw2L|?ofZe<^ZeDrJaG={ zM@p;YK2^GoyY+hVE=*HO%+0u3)#CeQF)`5|_Xqw`rhaFdqHc%m+1q<#u*tRAzNj3A zo=IZ*F({9Jl#trKPI&x1bxb5hrC5YPgcx34#q2A(jMp-NZ-mYGV!P-T1a|F|p7`;_ zv@exR3QgbRsGQH7#{xJqg3y;pzK%hA0UGjI-kO_T3S4Pya^2K4c0@`^%Vm$yCc4I?P9)NG))-hGOe_)xtU0yPy4+qy8k6h zHOnNrWB11Zl!*WDrSL&gPz%G4wBlxDGMsrY%kkD6-0}3|j=xJ?LHKG&40AmJ=#qQ zwAzDo+AEvsL)k0WdaZRsgMwOr`ywn!ydA@8B0WFGTg3gYOxVp|0aJR(Gr?5fdzvoV z7_8|wRcjLp6hFkKBb}cnI3M0{rpe@v!Cr*?k=N+*`_~bQyykl>GCWh)H3x``mb{4=a-H@TV;Q$s_`2AGi@Me zUB>8%r^0t@+zkFCYEhP=SebYLz8@jc)ba=pDr9Kj-sio`P8?Yf&=O&=YK9n=i+btI zxhTomrRf*dXcNs|EqG__a4gNs{QiDHaHBCb^J%jo%kKKECz?>tj5B&oNr!RAtYr`6 z>mP>Uw71>A?-TG_uVdwYiPuzT|70V$*lndP!BX$H;qbI1`$JE*sqQvEWTvn6g5t>O z-r<%f0xI@SEVh7}AG0^|Z0QHBWyT%Fvf~Z&O#P;-Lp>Fy#?ANXmcI6(TAdvlU*jJO z*5f+iTY^J6DZ&=Y1sI=}aq}#K*qX778g*Yci)Rx$MtSM#4*$AW{rBC^zzIqIiTM2T zb$^v|=uH?3eFDCEIn?=RW7%c;EPy?1FY^5ZNd++F)6m!drAg5Hy!658YA?ax`FgL1 zN3r#VjiGK@VgUwJ&Qw5VH(0@Dv6slSMLV`Xwm;4l_9x<*7llgv86Yh^c|B!4MgEG9 zxwa$<1Ypuw$yj4RBaQ|34{S;7)&H_j_~14G9k$Mkb#-5M@CM+B)bcf)D7F#%3sY~5 zEgtwc;2r6flCK;%4nRca$+oTv7YFA6=1HV=;iTYcz$VT%D>U@D^!#IJs9N%A+rW&dT^%)hY1sQ(!ZU~?)gA_3w zd2-HHE?RQVRxidFT^YQp(8Msh(yxE7IcCIJnO&iIUEdk4Sv!}&;DV7yDS^)5B9iC+ z*;^nlU(c#J;8j|T5~@Xg`A0AeUti8dKVx`qM0!rOs_}y;nO7xmr#_YBXFQL3ytDdA z{ryK*PI{%1tArA%gfjLG zR4@leGY4nlOTWfssATD0BzZFla!~GxK|BAba0kF-qxmo2c7#WrYZO|#*J2$4arZH8;|4zx~d)0f9c1!bBxk+JN4(f zj_N_5{TNno8X8=yzAgZi!hngQ3e0Xf%d*0q919DB6iRgUh7a}s1O``(VwnIm3_*pG zz!58Y4Sv2e)ol?-rTn*<;)jEH=mV46doC&~@Gw~Qmr$<$ln#VH9O77)eNKJ8 zjBrsKs4OUkX4U{KB~r;^{828Ak{J{GWs@NjNEl2xWc`;RyFkKZ-u` zmnI6wh1A9B!u~5l1yd4L8d{|64t1L?_sEL&2-Zk(|`fYZ~;g`^qPP8D}-P=BOsC=LWJ4^LsUW)()qAj zj)KvH-@~{-rvBj+!G*A-7{<9vRrm_f2hHa&7!N@L^uh3f1xp1dfx9ld6JZ|UHNS8f zL>5pE_t7<-5&elOoe?h*2oZ~Z=l@@wt#~9eLIa2_v1NhiqRQpL>SBEM5GPO<-^bVR zA^%5ic!$K37(75ck{1yIlw%ARg7BdXWx}XpY-TRCK+kiRT3|jH;s9#u`=|+z@_np; zn)*Gu!#%_!c@ROsA%;iH^d0O-GKdf6&hX_Mkk0|a3)&O#NC=mbh@=Xpf?Qw@CBbfE zcOaJ!U`8mi=9$Rv(GIRA{`3-Ik}iiim(jO4;V%A z$d*2Y|AY&%!H7zOZGxZ2F4w?2P(%sT$M4Y#9u@FN4}T}|#DI7JKBGJ;rAGmt1R!## z&$%!ukQ@wg1hw%k{UT@M|HuWm0zT6|(xpe?J<&sku%2UJa9NQBq7TXjt05K zs+hRcfMWSd7$^rANQWiGVo3}F2g+dtP^R=26r0IQW2jv^BW9#Hgbs|nC~*dgU_4MY-vNq& zG}vz_J?$}=4*y41c#gy%$s>7s z1#ToQL@cIa?otSZJOvvtviod6qhSBlZu>t=UbVM3(2chDpGAQ$LE6)>V`xrxgp5aS_&1)AX>&V_IQ?qEKNLn=_BvSGS0a+&v+S$%Ig9hB{w!|CBVPqv_7uB=+c$THKXBg!(;KTA9|)GtBVt^fR6t!pyV zs0>ZxPXrSg(}M!L!r!D{=n^Q4=n}+&H2%bnxJZPF&4lnoWM&-GgA!p35T%F^DWUrl zBY7o8NM4Cs<_Hs((mA>Wz#rf!xv!3-kmzSBF{vpL#%)pgiz5jo5if4zfT$9b{;d1r zNUbQdnhBzGjwgZYkH7zv`JkW^55$weK~hRk{|8C}W8zTKiJnQ^Vid&kXLjV>XPuCq zKz~su@2sGcP>L@>AV}vg>4+>MpRk-L$_&ZuKuSo;2(AQ{KkdFHl2L*LkH|A%OOP$% zN#F@GB9SAg`@jiBBydD_A_NH>!BV7D3Pr+3u9^O2Vq{)3;W1Ik-y^{zDKDsyO1?tA ze7@2>6W5C)CEi#|B)J5+HY(l{+Z@9j)11JZ&>Y>`Bcj&AR?3$zgQ40*L_Pt^Jbu8SRu=JtmQ!D8v`UoL| z1D8%?SzJ%y@6nL29k9UaEz=JH>@SmrNTlm$Hy|ep2e!&I^&07vhESUMxjzgD3W_L- zu`+=`#{&Nep2L$go`CSJ7l)BGdo|8;Py6M0>#N0iaAn43vJ*Gy^wk;3%Yve^_1fhR z&T8QQkFKu_imMB@MMLo5?iSqLLa^X2!QI_mgIjPI+}+&=cXuCxI}GlR@7{Vp-j7$c zr)H|UXP;C1?4CZ;XZ2cVN4OLD)0OlES##A$vDjfi-*&kg6s%42zPCr*4ePG4+G90E z4t`j(k|6`P2QSWrVvTX}hlU+Ld8CWqHAjpQjT(3Pt4}N)q@OyP0~-}+4sj3c?Jsm) z8t{0c!$_CP_+lS2SneBa2mV1zQ&%~;Pv%9lQ@*nRX_v5llXzKW??@BjZm#$(oMVy6 zeHxQrNS4X}A`vsFi>zd&-Js3W{b{KsZ{^1TuZFr~2($BAl>S+?Pv!BivJ_7*{Q0A) zFC1+pErv^bsG?wv$ae(^FgJLV`;`Xw9fRYe(gh;*HJf55IKRc&OEHX&=~etIrfT_G zQ6+l+S|#O>F0gNGUJKul3h#f0rD2^imoy!sL%Veg6vrTdg5r@4cV)fR1;7>%? z>d7CxvbQd9U&gY!NWKTX2y_HGwH|%2A|=^=WCXGe`sH#&8g_*S*1vu5C|;TU*6%z# zIb;?x7E7(yioUT$O7dSvN;;kjY}C!gSx6CS@lTzjTw8)k^{P6u z;3AwnCOabcoH-TKrmEe)l$#j@=PpOZj_s7@hvmxbiIC8)X?@X#yQ8+~5jZLklN{eE z?GDTRoLES!aS=v)@>72*P~gZ|Op?f09{xDsO|+tt}J$9H#kTA=QXseczmoOJ}U}7)&C{K+PLdGuzgZm6iMOu|h z6PXM{&yZ{WtzmU28}xNc>-(++xTo$GA8*7%T5TFewzW}rm}KgUMU>^&-niCldf}WV zH=6sZtcr2yHPq`HzpGd-D%DTo)YMl682IEkGEf@uSkvTA-$NN!Z)?ManCQFcNUhdoK?Ao$kI3|ARy}X7mOv^ich{Af)%e`-Lk*645*&8~^X-U)l~y z+*Mo7`gJDXMwXTP*`HyX1tAUMALo(U=O7Zs&zL~^fCu=iYxN6i9r2>8C|aMBFuuwm zor*CS&|D*?p{XbQ@4&{Uui7PMJW~%S)?8kfZFe5{@ez6Bo-+BwKL^%%{Qi{kqBDCk zi0hxa65T_2oZ?;UIqusi_j(wST`lptJV5xt3Vxi%soDyCw7-;l^{`g-|5{Vt#J$c!!M8~Ny- z_D^^#{NwAm_#sS2)D%_z>ZRd*816*z;HyP86CceOGoL>W6JIrtkSoBPF`~nFHg7nI zW_1s&oHt)BMzxh}GJl*HBhTNYGlwHn*w!h_k@2M=*qB8d`)2-BCH-Z-@PZj<^AhpF z*vO&BvSnj;oFjgD;8kuH>t9)>fiqp!8Zw112@M}*KKqIE>=cJKzv&VgYikFYBi)Tx z%EYO#SWQT?9`||Ra>IT{j(?;%LvE{1GWE1SyFf#n$3x>J-|}P9_%HF7VCz@4y`kPV zUfhrQMKX(+8sXzAoMZ0j2s{djqW1Qr3VTfO?6=J_5O5L`i(dDKd15k?*yyMu`y z08RyF$-*nAHq4FWd9~;2A@uv!=IN|V!QgoQ;P~$}jUz+i%2q5ltKVtI*Scd(M!DwB z+66)qxxUdqUT_2NXQ51s=vmcw&qb$P&(%jz>T@aQmKVtp1G}r7DXy6I`5ZNMV?#g) zeq=0A?gW7yO~AX5+(QraER9jPySw~{4A#v3L<^(EB69je^9qV7{|tKD z+1ir`257y7A3PaTZ}`Au@(ZWw^l|;2`<)_N@dSgh0x_`y#`E!~XZ+}{E(Nci>vH)8 z%OH!6(OJ3Bf{dp9#O{PrxGVyxu|G`vX0r?49+cPJw5;5_b5)vP#Sz&ptF-6?&nOEp zd)lkcL{rS@`kr97c;l0x*Q+S1V7Kntt~RX7wI=u<5$kPhM0%$vH!qUy-9DHLU-PrB z8L3cjBj9k9<;LyR5(R1c{o*mNn4oKNC}vA{C`K>UvB16MHIZ0Q@C}~4)cef-_TpPV zppbHi#Gw6?IDg}4)B5vex^d)+$L-}F#qG6JY7~Aalrg!QWt8hF?emIxbFw%&pZsFW z)$Sf)*2R)R61;jLv}EF|d>7zTuujFGerZ}Yi(NE6k2g;Rm0&+ z#$uq8Y9`jPTdubb{Y9CX zzDu;XZmxqvLi1PzXl3$KC1>U79Q-reYbR$f zp?JN>9PAr3MOF8rI|PcZTpz0j3SS8ht%`w;)S+6}1-C+e8@IygNHY!K*%)7XM2sWsT2% zj6LpN;yOO|>lF|3+beruwYvF--1B500?X^8H=j_=o%ZnJ2nejB$`Fc;{p;JfN zxW>H|)AhWv+e@{7#M}EXDHng6HTO4*vkpI}_sYu-KM|>Q_qWJ|=F4Z~B0FJPXW!{T zvBOKQ!#7vf8D@tdx3x^tMII6Vqr*3aj8swka5MkVRed8C0$<*R{vmYTUxoTN30V)^ zAvf9I?47q3H-#=~uTC0A_qBhPU?e0z{z<~+n{+BG=W;%>owfNgffCbeqgB~fc=yY7 z^l+wUP$zc1qAfaA*xFO_j9rL7+u-@E^(59ScIS5#fYklA`lu8l7GY9%Lr^jT%=(m_ zHVnMjyM89_oQqq+vyLb5Z)&no#kVus#_7B;pJmm*|v4@AgH(#!cFh1_{JnvVQLO;J{LzIU=+1Udl06(&OT~36OjYX1nHZ;BNuVqYitMQ_1TI%(2S5y|{|#H@$Y+&TH@kzKQbM?xk2_fq|0? zk|1^B%eePzmxVLAmq1wgS({+VD zJLVc!FML5e;C%@@9@x^^anXCxgA$X1P?vo7r_oaJ~bV~HLuc} zA9U@)NEfJay}oV}7uV1zw=aG5)1L3tUiSU9wkO2!*kPkw-^9JZqgLu}7@h@f-1?E-rY4x?2R2 zR8EqP`32THN9|iY0A}|+OrlK$$(FkzG(UgsgI`!gn~0JRt9)apPp1Jgd$BtC1yv5W zn)ZZM2{lo%9<%cenrYdmPuBca>J$3wd9IF4G2Sgl@0_jM-5Q(oHv{q?v> z!#ZVIjfD#drKQ;P^!{RHTF&@9#}?hWlJM*k&+Yg5S2Ut^O4~%h88aXgDRGrGO)TN) zLr~F#`H%=&tb!fWeQsjYlefm~{CNC{h|AnA7gt4SN~c#((7Ew+#d6p0?~xzmM(Tyy zgG-A0YO4a)rbe&tot~@0=*QBKFW~6ipjFtUroCjHb8+a+VD=56ReyCCdQNzuGL7Uf zilG8iF|C_IETQNCE+AP*icwIQHy>Bi5>NU$k%IHI=V{L($ff8P&aQq~vQgKQ(3;(~ z5{exJTFU=#dk76 zK)h%De|ufn|F2TUq%NEX<}gJd*neMg?mO;59o0|Wj=Vl<5FI* z`_+Yebkfzud-&4TMJ5<6Dy&d#7~A#XbFPSqsB=B7x6iNb6mz1Mio?u zrWL`Jl78}j*<*USd*XE75o670KIu+1iWh3qdIfu~(p$NEa?)G*d$!W=;+O9kTOMJc zj-*b>(U&BjAERMOK4PQ8Nj^VEOOkv(8`qOw!xBD}!LVv~RQuied)Ct3d3)N@-35Ez zR$#cfmw1pu(yMIO>mcoim2uf3Cu380+g%JJ;%kgt;4>dV1FQ{0TYf=T2hGY>1L?{V zK~U4uzD0Xrdnr@$;o8cNq~*yP+iPa4`(-6h40!MY4&BKqfXt$-{95e>oX5qrq`IZ7 zw%t0jtQpa__C?=0w{vJ)nb;zf>yx$%yRj{Ic6;uq#>%qV{HSWW$iGUEJYwitN|ZSr&n2qM zafl5zCh}?DPvp5arbv{JB)Ft~N?$5zHaXHLK@eSE{b#-8?zptnJuWu~b0iy0?`~a? z5t9eGx?&%!LLXN<=^7-ups8`Nt5T&}&g`Hg;|oKJc9K8C>Y*HdU8O#Y<-nZ(?2uCo ze%+hL=uqhJ$$;CDX+gH>v|e2uA*WU&2gi~I_p_Dd)U&nLNkuu}m7^g}g#&AwTn1|* z-=y@6b9=kB)if_o@(%_aS@ltf>z$V;pG{S2Dzijssl@lWLA+X(O3g~r`JpckKasyZ z)6qiZ(N>ul8t48-l~(@a1&ve-)W9gc6DbUr20y8(y$^-Q(z8_%e1kpY zo)m$wErnNw0Z<^6wL|^(anv2m9C~gCZoQ9%_c;hvkuN^eePaUL{_-AUkww)Vvo5<{ zR^y%~TXkq)u)0@~DBbPKAJV8u&(H5J?v58osPHPJtNluOa%zRGVwjEJPWOg9>74Ia zR@fS;zA9(&om@;w24g8a^2a1ng08tSMQJm@OW#>Ws?JdpE46vz$0?!(kM1y@c%P6o zy*2=c`>`xm)k=V_-0t?})Me+#=SPN`^vh*a%OMtz7RuSrd(bQ-GL!ZzEtSVATWQiDYaW%%pq$C`Q6JuS$q6N0JRIp})N_*tH)M8V$LTv~HqQw9V%HDVWbc6K&T4B!FS_Pj_vRhRX)B-j#s(Qq(=*J#6=`L!=r_wg)d6qt#v8c&dOYJ76b49EY z?Zme%V@Any4c9ARXX2Zu=ErmVmM&qTArsm_oak>pz@|6@QlXSZ|cjMetwPJ^cGG?EHN2P+Lg`QspRC z!>&!|rS6q{@bp=QW0^Cg>J>b6qR#obCrYq?+NDo3{Mq2h(f-ly1 z5s{30I`z|>Q}b#5q5o+P>5gD#IKX~h`Z>aQoAv2*Rhlt2&Y@ImJ<;-9S&i+;mWv;G)(DXipLX(19@@3D-t~7~ zZ?k}6NtFRXHRxjJEuy5as1sTpONYXa)M!v6DC=ZB&2f+$_hW89l#X0xP>JLQy3B2e zEuqx@iu)O`Xie7vEy;VsQt;sa50dkKPozF4ge-<_XRrQU=9aEqg^StXv`0Bk%Grlg z?d14N$gvbxN+Ai-0o(|8)-#i!vXg;onFTg!i4apzctTO;y*h`aF-UY!0+1ZT-j4GRTn=8!0eCJIhQ;G z|Jaoxw8}KSxRRQh2md*%?t@Px>TY$uR}_8Ozd<^bxTZGl|5i|{`OWlZl6zB{L5om> zY`FBBwkLKD4w{llCxNQdZaFSsbl(2g0^6=%W5ky=H&?>B4f}yr5<82+oRb3tKbv;M z2j%ZJ>aIXv1grYTGB-mD?e`(^>F(&*8wST8SDy+Uw%;klfc=j z5P`-*QSh!hqqH}{2!%#mB7-`cuovJHsm@6fbsE{2x`tyu%;NAIlosisrTJ-DM9 zu2vdZBJNS{su0&$sU}1b)U;+UK`mYQT>o7y)?6Hu9C>1iVQ3nD*C8^-kph0Gl%1At zMh|x!8YzHfZF#@qu+2*-LLid=X9yTe2+7%MJ9aj(R($R1@^<_dAIY|f{CuM49;(YpvSn!@#}JA{CzdD2 z2rV^8#!mZiP`ig~Y0H|KQiGf?aLX_>EwJkv^6Ic2`j)8GC_7CKFW{Npv`$7w-Movf zW?~;yQO4gfUFU*3i+Qj+7c5_&*4FvGf&>kHC`F?W7KsFSOL63@Pi?I!{*`ho>y47L(tl}$SiE3R4u%T~EKNe!&C7+ALyTrNwtJ` zb}PTUsTHA1v)SS#+S#8)IaC@ z1S!x#>tL*a)}go$XdL8lT1PiG*UCTriaAQfu_sP8vgPeT^z^}kz4%!^#mS`nJ#m4V3v07Wvqcx} z9%2@{SZ8dp>V{FOkcKKpz%4~@>tDWEL#aJoSOh$+e&NaGLUa>njcQ@t{e#I5Xe&@Y z30jRKgQ5oUGh+_?eu0*rX;z5MoT0TPr~ih)EzEIfrTiFYItvo`N{o|Mikai?f6MCn z2-PgmjEDq#tCRDHP59I+j}Fqg&eXis$uMkekzMDzV-Aq<)(3HBr-;|gEO#iNQbN4d z|A^YwUSn?QZ5&ko^59!bX({#QvP&v&-nvjbk~Fty%cDmr2Xvkky(v1ln#0B*Z=L>V zvC93$DD7wPy5)n>R9OK1sdh{!N93QMeR4mhNN`_n#LJgus3gR*O?OM>9s$UNI;6v{ zkkNE4-Bh*K>io&8PvCCksiGjM@i&@Pz|NB~7IMcfE%d(0^CS&>@ivQBZg-=5kk>cd zQ}wHh23o9(ZLXDp=G_-_)*a^^n92C{f0Kd~x)R>6HO(!}-h z;w*uAyhZ;rnHTKs)$vn289T^`UIZTI;x(WfXDYHp6+?&Mgl#;!z@hTwyU4|9FI2OY zYiZXo2;JPz#F&M;m%IMvMYBp!`k+Pbq2o} z%C7;(ug2WR=9TP2!oni|ySy#B8S#$=I-cnXUlw+agMn;bw^W2BtDxU?F3;d|5Zby? zsJN%id3+Z%s&P~A1@uDV;?^T7clO%PHhf?oVK343_4mGynMK@|x2LP4rJ(`3OH*$<0xM|c8PyKiRe6Y> zF$tR&D?=k5bG7Wd-e5IPXQYawCsxb9Yiar-HNE2>lmSwDWf`ElIj@?=_=Lpoydeqm z-+2=g8fbZO;J2>4if$Hl>NVQaU^En+u&9=QEqfJBsyauq0V@i}>NW663q6xX*b-bU zJ2brh7UF&TrJ&fMpaN!~npOdmOR*>S>K$W^AuH8)N;fC$Ccjg?t<(E{_uW%-N){+# zTc|)%3H2`04S zx)Qd~c8(=_jWItl?ST(s!q?!ero3!5qVWzmo+QUIX(8g>F6ltF(F$4hVvl6>l{$bO(_%Z-k`b4>P_sb+(L`F`w0nIuK(G)p>NBfV(C zjjqG9sJ4;$$;n;%-hs~B3oA$YBDr0W;jXkEfv)0KdKi-Y@Ijg;;r6q_Q?%zIJ(d4o zNvB{B{ce-at6+^@SI)FW1^kUlK^crhHLV1OqGDD8)1&{+ACQVjO;D9~S{OR?*q?>D zp`|S}L8mfJ;-CnOxxb==G_BUK%d1zX%b+>O+Ljm;$I|S3ZtnrcQk=vbsOb{Hl`Ss> zN8d2l)5pgA)_h_($=SxR>o+rWwYYmdD94lQ#VX~Z@VDE*<>o0y=`JgtQDYs}XGPuV zYv%qbL7%M5Ir~UjolneBEJ1cUKd-|lk-^+oP*3*6nn&{tcq*o&bH0`#Ww68?7`i+f z8wob9_3JnoGAGjM2q1SviH`dq5*ecRsMGeTqi^KHwL3g5iqihlGh@06O&qZ9D~AQ? z_uHVU{Ibff<<88-dF*LnIeEg@jV!y#`1NWV!vJZF( z`MZHszZfU^-If+szEi*E{4=hlkBML9E}d70H=p`x_WgHGX+|dE%5$6^*Vn)-WjFwt zpWvSANuBgFt-`q%^f^xpC?&6h|4(=H5}ab?s>DsIhr3Q~PBS(0ab0VGjR|ZskKDFMSy1STFwnq2|X-?nxanIT(G>kvbp*H4{lb~}< zPnx|d?dj`JU+>Jg`_kF|b89}7uX5G!)q2eW;aCE#xj5#h zC17hKIz^lh-roCt+q{d}@`FmvL#?h~IezYPBN-dL9lORwShcn)t#IZi3Xq72d{rY6S1NAHMXWug+W4|PJOr;Cp@fJZVIb`xw!VWf0u|7&Mu8jQh0 z4AqVBXa%Vc?Nb%N4XIB9It{e{b`=BUhJQ2zX~X!?U)e%!A^CI!v_Nc=f%pS2(XTdv z4__bkKrb*p!dK8xpFm79NPAd6O<){^Fdb+(fCT3X1E_%TNDC@~eMP!zfbv6m^n~nz zc+C&chuWeBeF7uVu0G+A@Qz@pQ=3- z0sheMy1;cjzZ}*`TP_1BAX_cD0e`J1P~IRlU=v6TNdxH(n~9W34uS-hK@oq=qy~uq zkD;a@rZBGzKx9x;P*d0rC=S&DHvwS?9=KNykZ};iv>+v50j$6mkIH~y$U{UA0f)c< z#6X&_9^_Y)kP2V2$wA~GBgj;UR0I#YD-K8nxNI^|I?xm<8&*IY*a3OT1QHB*z^p}W z)d6AwlcDaRHQ-zEJz@i(fzGf3sI3yfCZH=+HJshID?MNglpT~E_LUC^7E14H=PzJX z-~;v*I;aS03(i9yvIXLj21I(r2H66|jN|atBP2irss`Nw*TWx@1Y(04v}1h9V&c^?XV)0mGn3s6qXKao?_l1D4?*e}M{Md^oOH zp@gtKx&q>$h4g?l5TE-%0)zqU^SQa8gkT?4A#=X?v2&n+gA#)f(&H>X{SDwH_ z#78I)BCHSEl`yOi>lGDLH|8T7q&|vINI(rtw=_@#TAu=B9r(GS_&}#}k6$3SzxpHw z*njC32ev?MQ-dafEr=e7S42?V7>`Vl+sHm~0hh4d3cv?wVNwuWAPM@FIw%bG_3PCq z;VsgmBcw3oYhgeRl%E!G8bX*JbQq9>bA!Ty^n2Vy~0!`vgbBD87&odckuvJnNCBYzV)#E{m& zR%18_%6~`jeKFuFL!&bF7!ECI0l9_#pl0mO8hvn_q%I`>g?G?kdAsk78&Lid$!nv3a}vs)u3AJzI^rR}Db16n zyC%7YW8akP0+Ica7fJe^`7}kVX#YDQ(pr3iB1cExL9qgBrmE%|i9LFmn(Pjv>Ba=% zA}sV8U(3s|_|wPJGJ} zzBI-N6$0Afq9wFRx1jw%{Bb6k6#2lS;R!YZ24^4}Dnr=2CqoBkilFjktWA1ji033j zNq{MuW=epmB^1N*nZS535Nu${2yv{S>Q?9L)!Xr=BZ(fC8nzC0 zB#Fj^pLTI&!3Otgj+o2VdopZA)p?K%{e!modrL|Zm44D8aKw_$4|y|C90%-1YK8RS zvhtB{+%t{?OR?T~LVmIU=h%X7oO-T!rFNa`sYoP~rXkpKPe(qr`JOy<@;Q&J|cNNhLhUxem+&8Z)g?htdFIfV|X*!<=ueGY=A z1+L0qbJ{;A?;bjYI_@L78eQpQoAkMd&B4Bc51M9^5yGJwIm`h$*9{$_AI}k8;dO=} zv)&v-<=9;v!{%_N_%O-*o!$pIhYTH#iJc{y9ylXC5+Vu>2TotV8Rb-P2x-t5<=C+2 zIQJe3T(v>?FrDGNfVe$*a^&V*@pIJIPX485W+i5%7CH3qZJ2B@kGHVY_|VgQ{w1z} z@rc!Tz1lz?krHsHaAKR@gmI>YXX?naxIeJC$CiK4in;L1Jtfr><5r32ccph8M@7^T zowW&_4%6)iS7@;!z?N?bP3Kh2n6u#zy20@BhibBw^%Azp9>YVXje7y2eecW<~IurZGcx9#CatxJOj4C z0Rvio>ef%ZQ7J^WR^!H#jQU|IH6Ij=!Zl5=LE__XRnxl@jKbk5B+nF#J*7>r%0F9d zpAL9#(Em+v4Ww&)GuPuBNVoOM^t8hHCmY5()!B*RNbR4xJMj|EPC`EA^M~h#_1{E^ z4PiE{2R3ca@Bei^QHWu82?R$TRA>|}bLdx5>K_vr(PVNESO0sNfoiDm3$E}pC$13b#8z-B}L2Xm4)e68CpQ+aR&7jZ4 z+fBZhNPxyH*JdD@p=hGatReGZ6XwNpMUg9(^)-4}p^(|wP{T|?LikH<;Jqr>iqK!= zCRC$>^W)ExOuS}jHotm5kCj_BI7r&++ggwpyUk8H5@Zxn*gi~Lk6EzFmY zk6$lsH+aGBY6JaK(SbFtG`3q}fgp3<8^2^&5t7$h+C>k`NnegspLW$nCyi$^Z;E!f zn5~4bB=aN_e{9HUdvAA`rQ~crZCxn1XwAG{)*DZNGb5(YnIRkFyhHo|lP_hgtMD6i zm$%9Yw~xHs%;5r$p?s0Ce4fZ42$0nP`FbN%wZ*UXPx$YBJ~Q?0A@)W($!@mXQeROp z0TZM5N;p#Vq0~H4dMw&$OYLYeD$TvyW1Z;Adx=zzvZUt)yUW&)a}EW~4WTbw)2=Sg zN7}#e2iE-_-%Wr&+N2-eq~GAGe^uQjq&IiEviaqNlL=qM2PXT6G4Nw$WFX(&<^7oN z!zIhVeJtm&yZ5_mE;j0A#C$sq)qU1U1TyDejqc>``3H6WN{Hv}VOP(QBQQxJNxBKK zobYu^C)cj}vH9t9zI2bpGG5O=Y1KKQt^C@ZL;ar$km&n|5NKjJr*Cr;Q;*QinT#pJnKZ9ZGn} zvlIE|5sM4>PDg%m%CP+Yg&_1$Q($;~o6@hbwYQ9EN`X2WrXRY<`01=E?;XwOUV1I^ zyR9Uf-HaBbV0+zS-_f|0*ES{Z!U55Y{;B$ix#?873_qz1}-Fo`mdg=sT+_=!EXFag_ z(z?-64e$oyYs6tUjF6gQ$)YUDgs`qrl4X|ozoyAVc-wtFKk@^aby{)f5E$KIln&-y zD4Ur7=NeQRAdEFi+52vK99tGjv|qyS?}Yq&lWn9rYegyL;v{x%$JkC1R>oDe z-X<(3#znQk(E}UwdoRtnuHf}{TA&TzIP*-NXJ|AV#watha8k`)-`Ta?vYO8ebfM>1 zJvMr6Ot_e75uMRK&pPG!z0;M4;6Fk-w@Tx-Sc+8^f#H9=TaHP%yL%>rLq)eT(FD1x zj7`iPa_sBp3@hhnFlWulR`MJ}a_dF7hpo8H9hl7>NX;FY`@GdA6xW0?=6SnxtV5%t z{sKeDN%KZww!cnW9RHxMDal4n4rO=l-TIYLiB2t8l{wVvRt#$HfU!QGSg3xRJNB242mcG ziDFW1^E?Ng-Dh6s``@RWORx+|1!T1$^`Omh@RWE;!Bjw$gWqn+UZ1=|kSLi-O%#f^ ztz!xm1*>BDz0{vU%AHw|Hq0A}>=J9*Hsxs3=qx}FbSBSM$%1_j^&%bLf2+s9==xy4 zeV?9ruBlaiE98^nDMQImXGf!1Bx3r?uSaHifRrj}(VySn(64{_*uPp69TO+E(Kwhj zQ_y%mc=V?khkb&=4qjqIIl9&NcYDMB^s1f>LGmS&eun6N{?`4R7SrDVF-?9*^8wclAji3Tdr1^N zXNl5^s02V6hs{7CYp`lHotca z7~WnI5LyRaZ>q*s5Vj4w4->UIQK^{7OykrV4PB{3k^~>>u1=hfnU+-xq@3fAA?Wn4 zng~Q)XCC8|dH7LY{{3mQZ~@*>p1fgqnNIzhO)|E(y~+b_SIMrUkqGo&mV~rTF}HfB zm$4YSFud1?f7L+vkPH4OrUCVcnV%sTyJR(Cu)D?SX4O?AJWitasP)<}+7!|QhjxAk zn8#aJ^BB*@ui$muDrD8|RjfvAxSgeh&s~6Tc{CXKy{u6^r@Iy0=#A>@9yaRZ{0>P) zwpA+jQ#vjX?q1;DWE6dnG)5QKaP17-gpgE@MDMa6qxZ)*`^Mxnu&UQJ>#ZADEL3je z1Zcs8yg(ZP?o>B!UmvZ+L-{Llv?|aL^YN#Ka(F9G(GH#vph`K5HC0T zUYE8BhyT5PF3}&7es0O-;ECO}F*aS)2E%H}70qR1o1jxiF1+bukCe9TaGTvD>lB>| zU+2sscNc6vt>MpOX{-;)Ew?y|7u&~LY{j;!*vlMc7*`tNbM*UE`ev`q+u-gKt2b#f z*(jeEh)opST4w!JA1gWFc*U)1Kwk0;*>BS`HP)%A`?*YzHez3|EMUId7Iw+%+ z-ZGWl?s}i}kZ|I==z;+Mx#f!Hg;0(1B^>DFbVdVl+MsZ|0q=JgT5w3 z7+8EgA(zQZx_{4DC4@PE&^0lkOY;)M@M*uVIBUp ztv3)!s#IWN@-Mk2L_x`fyu>Foy4U_^$T1T?dFx?=kT;Ym#3{H5URuz zO60u0HizrS7kVdD=67%4aNy4v&U6_|NCo-(GO^crcdwjHUT+TgHmGXH;8@^T)2{Na zTDod$zQL??kUhsNi4Zx(Md;+?8CP!YU~b7p9NOig3@cuoGXGH@IEUtl*&UA8L;EXD6rSE__pUMF8 z{vQOQ9NAV^Jntq=y~%?V!=x`8pF17FiI7~HNB^yG9AWXhC*?F_B3dR|V(18ck*{S% zxxAJSraJnow$$_a5fdUf3TZEEX>S_(=|Tl1ty$^UW&WHG(_nw;LC^MI~pMCNx zI{Q-K4{5((*2kd2!2n<%hZ6bG2mS)iQx0}g-B=wz>~ z+?oWMaakM$m@!$Pz)l)|9tZs?pp`?^3_#B_nQR8w{lQMcF&u0LX(10W8Ii)V?iO;e zf2$FS&7nc{%bCtX9(wXPmlv92{D-sp$9(6e(HkmF>$^7{umN4*4fGo}+j&J%0a*Ko zX)$$%@fqD~SibUO$$#zcFYMDB22~Hv2zQVV#t3)tE7V{8N1VUg(*AG-3N3o)-&6WW zNpexX;gFEFTF?>Nk!DN1-8Ke1`jHaDT&t&?|7MDgCcLxf@~}(inx31appZMhVdg!$ zGIxh4%n$PXeCC9gX_n5&e@T{Rw1k(yxdUXyksHQcd&=deo3?S zX7%_iAg2a#zbErfWA*8anaK16lR)=~Wadno%&zc5j|Pnf!n3py%i2LC67=qwv9y_{ zrq9rBSnkYJixGL@9Bm-;Jp@d3IUKz?96^5x^LvIf&c7@1s0qRAz+l_eJl`s3KAe!n1hd$?8ESYV_{8vUnP&rrYfIATC$4@`}EAzbIu&UAl;O zsZXkgkBco9wPCy<(v0GNCrj?9lRHInvliGZa>NpqmU&_9H*_U3>1&FKHg4xOY# z1cy;d3&HI}FL~(<9kIxG-XdW&9mXk7Jdg9MQ_by_)mY zZ1p_^Tr>s~rfsQuK>ui7w!gj@_YI7Fv_-Z}yL~PE|DxWFTH?TBC=d_<^#6aJ@Bb_K zqY3weLhaj|aMHJttaC9~8+U9FLUxz+SIA(p0ZPzL8E#)+RVa*TP}f7lr}EDw{--L? zfA4pb+j95j4TxT2L=7Kr>B8*(X76X_ByTrM{CLLJHzu6xY15A26srS}vyKn4Q0fRk zY>B*{E8aD{QpQA({1js~U?fzGi@e^EbNi3I)+G0C2FCR_OR9fVa}ooRg;~Gg;u*sq zBV5o|6MhB!!igu1w<9Mb*G7ZKh~V*TjIIkIP;F4_g^rkUL5_+fY5tug`1GmP;5{_Pf>;TX>m_A_58;-$95EE%%KrFMS4tp3LS= z29LqBP|lOh@3qqeR2LYTj8)DusX~*hkp}lLoKbFkdLSFv2FG^uz)dHTlMrHzq9hMZWN;MCLU*$Uv?|xf9MKtU;A>-Y6j=pB2yrwr$k*Nau`*&AtX-kCb zLrSW=tN;|?1r?oiyJxa-E<-QC@FqeTiFo_yy!$$Rl8XJ%ck{F9ZH zb+IykbIdUae04j!SRPGbpxQchC8eR#bwpB6!EPSU`MW~!W!j-?J}dLHhwze&g%*QTl-PFIt6r*IE?WQ!s3Ww!NYCIGBOlIZ}&yk-331=ClfrL{j zji}h6%b0dGJ>icb;%Q6t8BF31Z~1-kc9=M!@1k;AEyl{E=j&ucl7nt%uwjC}H1oCH z3Tf*&Q}_S?a+VjGf8yTZyR?6ck8QY{dz5LtwQ=ii5>S?_AC~)0f}Qrl!-W76Bz{w^ z$p%u$!xFKVn4*e5r*7^LBE32UXhe9fghhfOJ4=g}ggVV6YG!mq@hx4b3{2Ik>c+UA z%SCtbD%N;)^*VaIl|Ol4#z!BrWioz+3};YJDks;2v&NMIA{|Z9uMD-o)%dTJgfWN| zEFd!y%s5JKQ|shfA?+OPKe41m0czeYly&2={She(r3nKCmtS3omscT3IyrmL}K0kN=& z7`cfUrkIU4Ly)CFvcldeoEgZvYYs+`mov)Ze)=uxvZp&Pr|4gRf@9HWv`Fe ztp%XDE}Cr)?Yo0s#1&UL;QQddE4`=y|2J7S{=kUXU$Sf2gaNE>9ugAP)SM2!u;$`2 z7H0kxBio9Ty9gL2=@|rS`)~|*isCEoMLq&WNYxl66|1tI$O~f1M#C$fm6T=0IyxTX zG*zp4q?DcUGo1~T@L}anff5gF?DZtcQzIKXwnS}h9TT|>IvkUcK^4=EeVKTh3jOgH zKXe(;=S}8US7px2=Vbvbcyh?}Fn~!WYt8~IX-hX`#2DO40lJbWu{h}wD=I`|LFzAL zO{5q>vZDx}=lJ%Okm%Y?j0?a`qLef$nV7UyxQgP*`kdUXo298b=8}KS=?arv*-~(1 zi=<3&9id!Tt!V;~DCZN^A`X{TDw8Xk#Ez}_IHO<0Oh6gGQzI9C^{&8FrDbrIX^pAe zY)E#iHRmNc%EvXUBaMU{0yM)l<$)p$*)`1;;_BZaO^pFv#T=+|NS{99ILhu*bTn!{ zrcLxSBlvIb6I8jtiVfAAj*mJ{}9Xr!x3vTBK5iB0N}rmCU} ztNYV58(JqnD`KNixW|9WT55Igp<;zKEh}Kh-RN$c0y_0Cw6t*=Ezrh-Uj11dYfG(7 zpGsMeDQQ+X18!6Tk*FK`G;EJWbuaI`5NLCn5c28zPWNMS0AceGdXCL1+u}BhAa%SM? zi)@Z%TM;ZTl<0hRkD)K%aJ)6RJmUhd?h6PNN(Zdw>LbK zT~-b-?F|O??G5@jYp1ZO*$`W6JH%VP7!9G`Z}?DD=6X`YN`REyhUrQ2)RgRhzMJ9k zzSBnEERHCW)7q2mTI_N0di708X-y3+;7NlixS6ur6Lf!j1fXq4Y)L!eHCQG(bv9~n zOkEeA>s1|gbZ|H8fNlQz zO0j{oLAuNM>kaMd`<6=I*BvHU=zw-gf^S>0ea1WC!38~nXjhP1I(>J)UMV^d!9Z9C z_>S!0X6UO_Fj5aIEb^CON&%QpNhFM?Rv-K?b=Yf|j>KT}9&$9rZzU80a2=rF`5sfW zsV|n40!STE!5)xX3VrPm*QC3G0e=&~TRpGRo`ySb6dl6guV_LjPb9F!2*B`QWJn?T zKKKCSR4{6flU`_;Q^rXr?!R^pf0x`jhXkAcGID;N?<(6H(SDuoQghc18!+bEAPLY}%vR}Nd}3%`M=h*<~>URG}u@-Q61U}an%oc+~9BcZ@; zso@pVA+VF_Q?P*RtgSrqGLmCgg5EDxdS?B2Q@M;yZ-m=8_~s=GOb%Vg3LT#Q!4qp| zx#%3@>3TLiSZMm%7hWwFEnVF)z@_>~_akwoGS5;?Ey6H*3TPTzBGll#=rkk5Re{~- zg>~*BLZK~Zss#SM^GRu*GhUVXRPi}4u<5)qbM?2WT&C~K*V#Aar-lS74e%(fz%B<` z4o@)k{P=tNb1LKHa>j%Ubj5*r(~+UJ*g3}q3?-oAGkCPlV+m552l2UUB798Jw zosdXX+FWg9ky)bqR2}nzGSBOrySiqpch02xCc~^l@#%y^W%bPE`V8a1%jwDXLEvd- zxDU$^u)m@Yb^$XL{D-N;(J5M0b2(9`SBvR}6r9Z=bCWpV6*_AfZdtyfFeH5VrP#g~3|f zjCOa0V?3$SIfj;!St%od_JfP^77V*PKG()fq(R!mT~ysw?KisU40s^0H@E z+7Yawu2>SZD;_N`m|Hp{jxxf`HUH93Ufm;nS>Ej&JISWrXbR`TSG=b70Ed&zf$J2g zcRyKjzwr}4)2`_!GCbnPSYNQ+1Wrm*U9#QU3V};QCSYm;E^2G2A#Zl5c)hs}%O!lt zf@zqK%MK6{v4&%);b6*sv9^L|p<5*#<}v4r@p%NJaZ|9$0}_5Y0*9Mpx@GL=Bdfu%(u zi-eKAxjMKnjI>+^LBik^%G72dl6UOq|2BfL{69S>;{WYEbA97dDIp*3Uj@1kCcF9D zUzJu@eOvE#w;j5&!!>sKI~$OeJzJLKkg9J~D3`rjb2P!u5H%-r>F>|~8=+Y^yTI|OkVW&ZFjCc?I zwr(DalwP2^)>c@hyCX?-HA>27reKXUs##NN&oD=o-&h8;qjIbU+A)p!#W($~VeIU{ zbjTj|?TA5uA75@VxH|r7%`TonJ@?0T0viXlC0lwuih}|j!G~uoX?tyJ86;^~3aTgx ziU^XA;uy>?h;Zbnlkv2g=oynD8a_a8)R0qJiw(=Sv0cDZGNNO_f73aSSOTwBP_8Rx z;8b(x0Fak;m5g;3GSnP|lC5Dm!UC(Z1CE5OADW@LkvZhHt>r`Jj;~Mbk?-$0?KkGo zP{N4)xK&~K0<$~ak7Xx)1p|r=PJN@xR?ZZNUnu5XUF|oltJCaakJE~a%8Qg9$y8Ar zGTPdXO$xhtSKSV5YHjmv=W~o4ew^!WUYuWjc91?nncrEs7S69vKS$2#V{8urA}&Vk zvpoIxvJOU|tr(vMYvc;nF!v{Jxzh{y-hzDPakX;f!K~gX4ZBFbV)OZATTlOlS zz#CFd$5`_vssN&uL^Z&*%^C{@U-$xtTnXpQBI?OydZtJPQ`zF&zQZMq>!Za?xsna1 zn_Exh4;QE^Oh6TbJADRNk1Y0X%J z8kSol*rxnqm9W#LJvmb&cLCtz5F-;&P-E^vaojA|M{27eYc|esn#Rtn^d>0y-YWh1 zIY2u0cE6R}`vvX+#Sb;?UY;xq%kz!23u|o)T-wV-ITS_L2@kdXs;}y-b(i|Yx}@r+ z^^5E(?W%fJSsUSLZy^S`Gd6HE4^+i%91l5P*vMv9gY|5(Y>O((F)d`QEOd;|SVt=r zV&VQh(C|AY7U-m5sY0(%jZ9e3Px$X3C;D7Ub0qxQcPTIDHg@J3ghD7(@u9GBjYV{@ z9q{R2N6It5dDQavv`TaoAX~9B<7TpypKdC3!2V~o2{%+u;KL4PMfVF!9~k!XptDgkd=_$^j+GOWX|CiSu^Wl%m8_RN}z)X0~N&^UDCZYzzf{H;(S$}54k4K7X=F(7@qYCD*ucSz)jm?r zG*zS7j>=e2Y!+Okjcg?V_~?I7qn}1E{;(?~UDzA|szDajtBS3-+ld{o z%%IdO|I4+!RAi-DmRCScRg<(bhNs+%KOuqgY$D9W?t^ix8q2RgC=^`d!8qUEx(%p+ z+l4c+;tH8#cu;_14Vutad>U}w286W>}A_8fz(^t>u))`Kd0d-j@_cLxuaquj}{hzRXA)>?Juwh`wFOPe$qR>{lN5CO26BfwQ$5Zok zTcOMSFPKPZEAj6wcuQz2>~HeW8}J^h^K$>~`3o`e2rPxFDMJd5!azScp`?i)z{pjZ zo45hzQwvHeB$O0)4^|cu%80wUsRL%k#g#1oZb~0di&NS`_XVO|pA;CLXcFf#fHAaR z)V4NID|HbEy3w&ly`?C!@L*wPE6QOPYgoq!yz3lanrjlzCfbf>;0mZh2eR# z@*)WbK5WmYZ^VWp*j`U2#GPVsQLU*X%SA+86T_)@m_jdzlfSD627doIQwh*~Zjs+v z1R`3Xo$9pF!h0Th!-mSCm7F}scwIDp(1E)=5;Aj@))AJ@f=jk(o-RMGm^HhLJ*ShPtBNdFmRCCCsc`8R3Yw z49<%pv5|qx+2v>5e2<+$l6@w-hv!e;#h4ZK**lqFq&wl}T|dzAGYG zXD^iWIQ=ky7oVfBx8P4 zgA?dX@E*Tv(T|r<a7vUt4O)Z)f*}ibDQ>}+JF`SlcEVhJ_g3mYYu}GVnnZZ`Sj?iCY;C4w zkiDA%ZjU+~vu#GZadfk{*1zY5lEIqBhFu%!Tsf=;rKXfUSmBlzx`l&ji`=XQO>~Gy zMErIn5xKu|+wy$b$lul2LF6F#Za)tW?YYGJ+&EZp#CB{B<^Fax>j=}L*^dw5kiV-C zz&#Jv+nMC-fCQ)DZNYikBL4mAP_WAaZo<2QCYq`JDxlOK)N{v4@O4YEe;oqZ+7pMT zd>02C9_sNW*47h)CvTT^2NG`!)sq_W8lfX9^gqfp^Fo=wb!qjdelaZH<=YwO0P=z{@w(8S=nxGN zfia;qkX?%X%MjatcJZyfoX6U~>)1<<>sXlz_;PZiZHvaXa;r=c%HClCeQqegZh^;D z`Q~SHcCP&I8eDN#fB0vevDePBQLcuLbClb-X}3}_u9w9T247)A4`;tHLWqnHFDI==KJk^SU34%)LM4kJQq_EF zoBS3)MdlSEcknBm8$CYv$H8%>c#f_W*|a5Df?-QAyf_dyyfzcdR7r!3nE?Uy;5F(V z?S~GO1%}}iO;@0{LD6!hHZbeLi%`&kWZ08V=&#~jDz;bS$5x&PBlI96v_f|%7H|6P z`A%`5lTL$t4tUYT4ZO^Q8QJcf)Q*+vdc@M|rAxQ-HDf6BsOj`Rr$s^LdLCL!yAb&l zlHqTBMiBhmQ&$d#uwrB`O-`cuazZ5_{|oKk5%WG_KyqIWyq_+eh*b(Rv^9x0ew zm0VFcx4}OWV7=U16bH5*wCr=>JP6rFDijb(qkBTh7!6Z_Aco2%jP<8=rQqDd?Ez)S z)%$9QERIWo zZb7%(39%FJ`vT90GM7=?Cm!_M?$mMR>+BQ0%FKuTYuL}_p$qhu$tCvD@bR43#-@6r z^Uo?(@6)x68F`gvlyAn_I_zHzdjt}jq&wNs4Ugp8Gk39{5hvi@xDS-`9G2X};TkHs z{y~-h=$N$9Olp&7m({0RtLLZcL!6CmPSq&ni~y$xO$QHx%n-ZcJAmkzx04MRS7_=$ z`l^xUc^l8_h?3mvp9U*mqTy!g-P^2ab%tWyK$qzj?%LF*phH~hDu*i!7A?7TS_!lV z&N}6^53-YFUjI|^sYF9u%J-+QtkaPnOd9`EHEyP>`ct&pDhaBS#@G;h|3=T>FYE}% z?R5Wm{)aaAVb1s@w@$@mmr+Vlg8{Ml3L%({;McV$=;I7d%!h#EFb-w5o+XR)3rPMV ztONTQxlAHOc3oc65@12{b!>7awM{`)cGChbdY)|*&r4kvt5AL13=8;+;R!|?%v!&L zKJcu1@iJ|Vlyknf+Gl8`{d3xY9^Qg>ep7V8U3tbeJ^`z-p2Wzq*Sk!+_Nvb^fN85{ zqdDzRNVrwa3X7JWncfh1#KXw1IIeGQh`S*g=dVtcoEFLTCL#awQTlz?D#fr;9S-XT z4J%?2oYWen2Iu|L%_4cR+=|gZ{nGb4K_%SCrB+f$tZ0l%yh2%c)S)7GywR4LeT`CY zj9hS{Z?Qml2|+(S)pU{$h4fd(LJrs}^S6aZ@5ZqPv+iNswBf+Ah2C zkD`g=G)b>m+=et$TskMUIga6a4)kel&n5m85c3CROCcj|SO`n)q;7mv6?y)Y5Lt?n zAeluG0qVyDbQZOL$e%scp+k)b9LiJ^6_b>3?~*L!!=>Jzi7NO6wj|=VDqW^XnEXpi zHewNWQm~p@5r!tj2$YG)q5tlKNcH7~KLHeSXzEDOUbEy{?;p58nN2=~jg?mmoJ7oC z28i&;nLkiKs$te}ijCiJgqLc&Cx6Td_0@tb1#>F++AhVqf749_{YYDRtTA5i4%L6x ztmA%%E5q-8?_PaUc`wmE^nVei`)Dj9B@z!mCLdVueYylCeMH{hP7i)4Kj(JM9Ckk% zruYvlhQBg}zg9OSnR1sqU&MM|%ea8`u&1$x4bsPj<&~H}Fh5kEb90LRk?+Ag!OIOr}lVsB1@|7txS5|*qNgFa6Y9XYhl-;yZO*%Bj&?gy-hiyrfT&*9-X6} zoE%Se5F+=Cb1Z%%ag4<(*M!Q1Hbwi`l<2Kmd7@oL{ZN@M$kF3Q&tQt}f-=?lrST22zS2ncyb^j{Z$)mTWy==jWS)KoCKDweVrh=83SoT)-mv{ny z3R^YXVvEXgA9f~NjybMp#{>G7y!lQ>B4VY7?9SL^ZB??(s%h|9dsb9dc<6;{vbtI(Xj=NmHhC-$qDuid#Bt*MER_BYT+p&dzh1{_tTU zH`L4bAc(f)l-a(G&CiNyeRa6{tXu!qbIwkKJoG1D=4WbVrG(Vf4Z>|x z|1EcHQ-H#|C+B*gQp@wy;=~ZO05HKa;vifeHJz#+K3+fKLek8G%m-yPal}CUk*Xd! z-Z$bx%FLe(8in`wh{)nUBR^?Q;Ur?o14l9`6yAgpW${=lXM}ju2m+}CPcmv0-uMw2 zaYZU;xOmlwEXe~`GD{TR#1U=rDJo~Ac$bJQsRJMxHcIR75eac7DreYuxd=VU17|W# zl-7h1b@6H{XT*5h2tBC-Z!&I_*7y+xaeFFf_;_5hX0+CrkxTI_5@+i8_V5k;$?M&} zZO^{;e!`aUZjjLYeR(b2!a_I^p%Ah&!Ylhxc2l^TJQbHCg`ie(zU5SDg-^GtSltv* zaUV*OayM(Wene1+(^LwR$!WyXo@_gs+8%_30lsBaK=bgj@XB#qpg+q7e%!rHK_96< z4H0>joO4sl)Y2jH->3cA01-;Hv1SZQxwNNBNG5$0obZ=6?-_eqN8BmAUhJRwbuIR! zyh~wzpL4$9S-~vEZ?S)B2*kockUd|9U;8rY^O&-u+WNAp!mAm*eY5L&fAHWSIB4&H zQm_sxamB1Gd{`d{J1-jy;(OD!m(lNsM^3~@-TlA=K*4wt4Qc|_+XC{e#Z$o-KGk!q zEJm#jzLjJ6$Col@*(=QZsx97?dHiU4JmyK1emI+}2jq#qAxK@^P!U6pGkg-RfqphG zYZtb4UR^ES0kZXG1Sx(~v)3<2ve(xz(EYO=KeBZh9Q6ZA=7}R5EC$(;EfM+R0@JQ; zr4F~eBqnh8*OGryR~ejQ@bKu`D-H#EDAq-4Jhnt~LM8e6Tlzr-?jjLaH5s`^4bHdc zV^OI)Eq#OX%f&_ zhN^H~-8BD&`u0vkl^zZMvJYds{RMBY%PQ57{a)qbD|$OK(O)-!WSO4nUk|i>%B)3O z+#>jnkx(*VQk9iClD(Aov?Ypv1F~q-J*^f`(QpmpKc_qE01W%|zmWh9+z>S`MxULkZf!mMrYNYbk5y z!?S9-7NQCTCvequFHmV|W=q`J(#0H)MY>fu{AlPAgb8J4Ol20_T7LA>gtGEK&d^-g z$Vc-VA81(#H z$t9sZOeM#e9_6nJ)jza$%(zdk(cEw#BHnmy3=Ia#I2V6{x1zq=9 zxJkBBnXBj+b1D~Shafj%3rV8l!YC+4n!gyK4CP7|9PvczRU0*-9z$7tAQ;IOfabhb zc#3vdBuW|@`+_K&g;R5@TZ+A%=kxOn)}M}jxr{yuR3$30vsys8R1`jI4?Al*!E%8` z1l$l;s=ohb+p2e_oJLz|`)o&kh@#!4cd<%qAs~OW!u|!*05M4BZ@GD_QvjPzQ5Es1 zk@=!b=Wt|Z5|fJi_k@Pe+-Ll9jV;3-`!%C{%dS~9GdA|@RoZl-N&Hi*L5lDsG))in zA@qW?v+TYKfC-SS2=4mSl77!QN^CM9nczF0$S+2|}Q2Ln&S zhC1OAR3V$#^F{yX4*(D*PgO)UClR^)8#9Vgb>@OVgIfCEH=XKK9I4{jC|B{Rm3U4k z+2s1Pc{!3~nGyC4qfJVALXjXYUrOhPVEmrKxMGw1D(d)6TH3XTdsqa+9Va&K1U1$E zwDeiEUkQ&$qOcv)3JNNUgD7@C-N;hq5Mq>nU!KyQ7TM4PP`vk&;={E|I9e?9&-CLxxpisPuPO*iMe4d zbLR#ABO`|Gfd`pC+B1Bx3v;szG{anYm^5cR9+?4i&7m8MI{6)HdhW~nJ$=S~Hn|AV&dSPyb@`x@IaWzYw^Lr5X;U4X$D(^I^!;8Xjf`0bizH~W_=8WFUj91ny5>27uaHDwm$l#C~w zr%qq{mutG+&0ij=V4@x$Sx@GjPRb5sa2MJZvZp^R@fYBqVB~K?T76+(i0O9wfBpYg z1bt#M+5a#Z<$stA?LSNg`yVC?{tuJ&ePS}Y-SJ<{sbI_=P1z^9oeD}IBDfK)3+c%l zcKZvkAlTtsmv&$CmucxIjh%H0AU~K8?LXTO*zHf-kKq4oKl=W&{n-7q{YU`!_r&37 zt;faH4xR814O!sH!NHdMxO#m=?&F-C7s0U(-L zUN-~p%x7$p5FYuB{?ZQ=-PCKY+R{|4oL?X+AOW2tyXKGecVaWXzQS>{NtyKo^x@(< z<~vG2>CtS&f8~xWANhd^r(|YiU{fV2Gs#I)wiz`SRF7rOImVa7Npmc6D#6P6f!X5`2CZvbo^cvoe>s#fqpVo|UER0T8p^~s$^g@;$fC^e^ zCVk9?8}R#n6{l=C7h9|ZzMf}zov44|UD)RdVGba2#zP%fUJaVS1Huy=cNnHBO zG1&50N&f71 z(tc?2FUhf=e=%6atk4RnN19z%xwdj#YPVcLv!KTSHlJW=0HEx4xGGEc6(ix5T~1N; zsPoqpIZ-*0$|FkMRTQ+&Low~OjOiT)6D;VP0x@+zrZr}=LN+v9hAIlrgx8(!qw{@I z=0HKI0=fet&&ISML;gL`oMK;145vXqbIoq*GI*T6qfS*}pj&JKE)F^ z;9{_!c6aMV;~B%^E^^l~1E4QyU95bDvg*3=pRKg}jP_pXBRjgT*%?A!1C1Z;u z)tJoL_6x3PJQ7XV75z2ZN{e&8pURlZV9?EkU&K1fYxZxevi%d^z>9CGmAN|MeN@XS z9cQb!IT0r@MB{z($0I@m+P9PEM3Ym_AZKw!gJw+i8V~v{VMwG~O-Sjc=nh)YFtn+) zlyN-ObPDcn!9k*`NPTNe;GSxsC8YJncB8MstUY5jB1XH)4*eO+f=Ai%|6V1$q&DJoKWf$Q%*!z%ZXkREP=4cL zfo~!DW>14@WRC8eJ!^M+9v1I2dqiom5^7Q7knB-J_1nfI8<5}B+Ct`iqKiDH5|5uQ zA*7loJwNn1vGNQl1t;>e^pOSG*Lmz1M5fEdHN846El{Io6&EICl2@d5L1j^wD{^s+ z8CkVK4-}g3T+>o2sU8}%SShx++$IA7EwkqbqLhG7g*A?p+BSo@N9^M-==JY(^ylQ{ za>+h}GKMd3?c*)74VkwAojOQ*3Q{shjUAc*?W2=37B7?BxYmoiX}=*11BAPGHs(p00 z3TQtMXn+F9xaX}Vz8RRtb%<@{*g0*TGOr3(ExcF`6pHCjbjzmT2(CsoDWYMiJG z8ug}3Y1FjH2X~ zN=&2=9{!f1+Ss}}<0P-1G3k4}Q8yPO=b`w*4q4HG$6=dmq4>(Ql$n}hdDXFINJZg2 zk?|Oi`&!S7jzL_uproSYAFOO~9XbI;5ZURY1?l54vC?k(;diZZ?Sc|Ya+@1yV%ag9&cZy?L{e*LWjxm&+yicvS8 zr@xsFmeEyxxsD(=ubELXdy9P$Y~(vXZXyW#F4*mb$)(*O`$xF#Xrjz{Q+V#}1P6&C zQk%`SNpc`QH}R26sno*gaoaPD&6g%Omt2NHX;*%4fKt$KnSGK`psWmC%(^ zl6Z_og*j6qLHEL8#ru_XqW0e-)e9cnf$gf>f>up}n?UBS=BVrbzm)NB8$f@*FTD`3 zMB-qhz%Uenq#fh$$R%^AYJ3SqQp)GEY90tN9+ip2#|OhM8uN$5HrI&3zL}w6FM*xe zZQI-n`-pY}xXZkmHG=7B(h_K80n$LWa#r_yl`O`j(?E|I%SYS!eiY*@5M{l%_e+Oy zr^4U!-CjLyd`oz-rs4L}nP1E>&v{$#j)vVAi}+y3KGF;~)+sF3fi_^LV3(t#qcrlt zIOEi6KCkl<1XDb2E&IvknMmj1FF9uo=vGBR95{RgnYynH=bc}r31<7X87cm4iGKS! zMMv^w5Zar24njW^gY&_8DY`i3wUaO}Z_1#%+aobL>%q!z>TEVdqls8xaKk^ALD*eLZ)UW_&>3UBoIgtewiW-?O{(`dxq4bm)Ln7t6)ad?Vh^az@91 zQ(Q>)HQr#%swWKd>6J2vvvcWBQ^DpiS}T#VG!PWbj|%Hxy(~t^y!Ri{ z*KkI~r$w86Gu8otYsrpHEm>ZY%E*?CpiJR;OQGG9P?_~ND~ZdmY%FYLqz!q^{n+B; zyUg+Q<~rgRrn_I4dcF>lYmo?Km?JT|?4 zyKKmxKqQPw$@|Gu`q!L0bp%p0hk3B$!&fCq5 z(ENy$Pj-Rm{!B3&g#y95x8=C9-bGsEOnY@s(hJX9k?@JJ>PJHReD5bm*q|FoJ4@KZ znR$MRaNV4-WNqyyh6=aI^Qk!KHrH%6oXj3(CC4WsL#@#YdlaHy%wnQ&8R15$bc$WHJrZGF!9Cm@$n#w#uEO?G{WjLhAZ>L zlc!#Rfb;PEz>z`-1vd_ri|(?_&J-QS$ln=g_WTsP9y5@t6f1%5>GrH?Q08lACi1J= zs@%@`YU9My&`f|0PeEeXw4#a)S(W?Ln_HpH$T*#El zDKa`vTs4dLb9p27y4&f z4V=q|Ivn#fcFXLzN`q=`ygF|4-6p7(zb_eB643@FOYs;r<~Wq?dWlB*B^k^Et%Nv> ze`RB+D^$esK^RTZ%Sv<-d7P+lA4-i zsP<>2$ts4&Y>;=i)0r^YI_bZ;92?h+)J(*@OnI{9GX+Al2E*8n6iN0R!NWzmD3d-+ zW)6;&Wos41drB`nh*LGije2JcA!3@Awboeyk;s4)TQaa-_^f;j3JS5RIzg35OaVVI zatPLVSsC(OL^1S!>g4`Tek{H+=MuwHw<-MeMUa@~sqdtf7W1yR9Vb~NitBCWiWpEC z5>Pk@c!K(wv3-<=9~UkEi@fOHff*e8c$NshEG*PGuH;GOQi^QQDY!oVq-Di~P(j5$ zpd)3ixX@67OaUFPANkTlLOxxlene`2UlEEv3((qNEJmz9wwr8FNfGK z%t0p#8M~;!mC`yOJnU?CN?cm|;cdXEXV%pB1GCdVx>!-E>A2_0MtkP2)WR}+Q%8X{ zc6atPf*c$kY^?GHKF1Tdaf(KJgBkae4}G*IF8Ys4F}-}07ZkR5V(l4itic!z29`Yb zSz8-<2M14%4eV5+YFS+=s~OOI1anHiWBIj( zZAbP#uK@{>yJNN$eQO+V`33$d`lTjrUm7EW@U1F+vi=z$cgJmC?;>e`+RzG*uu6vn zBdea16LrCn$i{g;WvJ<-5;aTj4h#Hq(mAm?Pjn0j#hm>qyjg~f%VpXMZrUFujG6cB z!X~pkj#=okbM<_M^;CKd?Rtz6Z7~H%mhhB^m}jtcWx4Uu{3sR1jOuTeEGQ`EXI?SO zCT`o!+^b!aD7ll!NJ&4nIv--)f`N2GpH&VymlWWY@1GNYVS|jl$Mjk>L2zPrRQep> zY7x+(DDBVA!UTp}lr`2Wd&6S?VRzt>(HC1EIx05nn+Glb(n;nlZQv{Yi8m_PYu2{F zVNRVUKfb5%4t!NqEKDfS4r>lnIr@qFE&YviUV|)EUoDEzC|%UYsYtz3FGaC#d)AR@ z7mzoi$8-4)cR3!Di5L4mc<;o*cdxp(7ETWjYH6L{Na%fVt<6n&r$rGv8OAuaWPHANJ^}S<$UMAcNk9o~v^3b^f^3HHpjm<5DBEG$LBy>IeyJ{=OyKE7qe+ z&-1M#CNM1En1%;VK(m*;XPu4*sv|qF89J8!Kk?fR1vo9x;|q}{_`9QQZ(`3KMh7`q z5pE0D6C3gxt|K$h1A0rW*XP@H(N1T;UuAGt&nvB`{|*EOkOV9OCxr8a0!a)9ObbMY z78321`bJ!|QxFiR46f@LrhW34I#tBuY5E4!Vem-tGegakE__k$N%bJZ)l5 zzs~IY36N5n2N3m42Ql%Dd~J8U_4=N`vDNf@5nSCCx~gO`$oNQmRH|EQ9*L>Idc0^g zGthH55qlg}8QwV{yFy=?&`C$7CGKt!7s!TQG#uVRBRG}QL!lJO>Iv%u7c%(ML}~vz z9rm%({D!yIC#Ull)4-Lnyl(VgI@QXSl0&E?oti;E2$vf38r{+*Cf=pBMtrT&v)GhS z{Irrar)M2S<#M;JUI30QYZHU%lWnh|PWs?L8gc%Esm7R)vD<~}g6~wykdJnUrkNqk zp@uP1!!oSIMX&;=X1q-y_HVnIqU5;&kJ5gd{5F z5@z}++BGEc%pXXoSNU>(z<(XUDZ%b0gJdelVcpzns}+RmQ?we{;})v_0y$|`03%rx zjH}^u%?E<{_u0F5cTqeur4+z%MM_j?Bs$n7#a_Oh2D7(Lm48vQH;AvjGXP5s2C`PH zjK#HGe?$zDPYXWT3IZ%y`*ExT*1QAn`hqgEs{eESR47PrRBop+7wzagVJ_v$781sL z0SreDzNm}lYTznX6-I7~CKIAw@)x**e|IA{84;^qB;1s-)fyQ^jQ1sTPl3 zDEPU=X133)X41^uyy;oS27Q(`6`Ny3Z$2M^LPJa9)?ZI-r+unPyC+{vf_g%IGgsC! z*J2BAl_Y)4Uz|SM62vmJ{hguMxExBBOb3?J(f589^vU_A@T;2^Ln_qP{mjr8Iq!%k|%{WhtPbA7n-T zaI$y3c{QE3yVxGK;_r;w-GJ@nM5%?4knmv(!oS33+xu8QPz3F%={QjExj;VStM#Kh zr0?VfNAjL5z>L>C{wxQvEJ-WM_IT~G*+O?{Uj~2ZLya?joQ7l0mfleRLX$3%b-*3p z5z_HYPblXEe-@DD$~fL`f?qrSFs3aANLXtf@%<3B<7S63S%=&fzAY?!)-6qYo8HV( zUx}?GA82w3AmNOWF6L@N04&mPgTwzmC4LA&kPOZdsgGuWSwW5F50&e z_c|5|(gS`l$hu%oHl^__a1usU4@G0N?KkCK3@+JSyZ5Q7>xv=wc?c)G8ZUgxQ<)>5 zlk(J)Wi3DWfNT(5u>oGF1UWYuhTC?tCX4#e{TKvH;F0v}VD0o32PT}1A1mbL4r6-N zM8Tmv*3RymuM!pOrd?CQA<@L6BZ>4XYE0CaWf^Xg$8~N+69!3foJ%HYCgtnYYWfL1 zr&_c_o)W!BY!dLd1_GYNyU=^cgHPm|mT%7uE(L-T@0L_F^}n?^X&j?TN4%9)?c4F+ zpyq7lfGO{|6oH_Vd)ncbo+8b<|2Pj@RsDnysM^jvUxIe?pw=Qhw7RkH&ZPm5c%|G8;6)RH^=QG?(EF8=-$THzypMGS!7K7I|yOa}nFE zU>V0A_F?SS=~i|9WFEAIaE-^2c2M3Tb3q(`mQ$-|O|ipuK`dV^SK@rZU&9+SY&@>* zA7{*NdEPXwmDbBkx0Y*`b*K{c9ol;)dh&0VSbc@xJIr|R**k1aH%`~ku4<>NS=Iz^ z;ap$xVvc=^+05zMJN%670~sKP*Q=XeW4CV`_=&D3x^63kI#s6~QHD2K){o}c-TL#l z?G&$xjX%rI7>fZ4-Zz))V=DM3Ec;+43f`vp&Z`?YdKu!1t47s+Ux^_73On6;C-$tQ zT&_z|2-Rh;*k-z`^`DUKv96rKIlB!R+%?+-UH;waT8$NLC+r+dnOWOd;~NXD;mCD5 zXas|!Ui&)JQhhyn$p$OCLo3>d0jBq|OcP$skUw175he`71PsIanhg%q84ITN77qOF z?O0Y0UT-%@)}_bp&amy3+CgL`c1$Z{$D$7Q4CxPsViUoF1jJW)>O zHr?qi3LVWHJ9J&;{8;7uNag%Q<@})K{IKQxywh%pWeQg1hv7d<9=`~ekMfqa4g{fI zc37}yS7|01&eMU|q<6EwuX9uk88hED_5+YQ3*oO$g5Mx(MS7GsWbqWP;(u@O;H<%n zai!nN=f37Z{x*Buh!{`b_r~-xL@ZbfI&s%N{0m=qD~y|8D{z`+o_9eYwy-(6w;J_xRaBz{&ImgWIqcSK(HW>KJ>9VbU~)HaSEG zSCSTzirk!fo|=8Hi}T$!`ko3rt_3ez0iOdsd81=QZbK#7!0X+tXSaG*xYnzSLccPLOHr9*m`$~zKh zkm62po!qN*2Ra!^L7eO-e+N5RK~b3Or+5cBnMq-k?5A*tIN3q5m+Yr>CkB@CL2mJ0 zA^yp3R5-zOFp%^vdxt-HP4O*$DAODaWKJ27;YzU&k&X*Xm8ST~!kjHVLxF`xFC!oW zCPOxfgN84ICc`$Vor00_lcI{khT@C@mm-@&hhl@`P{u{t1-(qb28=9)Dn(v4jY{r? zLaox1KBbC6FIB#DXiK{ctcD}M<=45cl$zO#y_C1VgFm^|c0#*LVF&a61C(xlK@ojI z)8Xen13dWOzjTD~7w(J-COyheg*iKAZHT^Us!vdJRK>m`XQEOPas7LMN29=dYeTM?%Uvb8!N}-_ctM+ExZgJPG#0Y@3AwDt z%bxzmXJB0E?rY#aR6xlT*y0)u%~;jek5o|sIP+99aNvN<=zc>{uAAQzoNn>^a-3%{ zYM72K>2B}zVzM&Z_AmQT?2y9kcMo12bg^o1jovy$>NN0o-KyvqwvTMVw!D`jn9W`R z1eZnmr{sXmC0M}c_0esLBQU%A^4Gl2UBOum$~=R1%-cPAbZd6<@wQ;CU;e|3+1UL1 zn2T#z@G7ibinWum=WX*(Ix3jl#opHu%&y*R+ z#5=WcE`p+l7rGnNGY&Yvas}@nI*S|*nl?Ird~#G!x;(FT!Y%#1+kh0v=PeXe@+s*#VIn0%SIdsC^|jWx;$`oA;EO_5;A2o>-D78 zR*>cc>IaqgT?TJ-f)F;Fcv|_!u}{r^C-hH5k%Mt+txdgqL;5r}N1JC)YymIM9y{Ot z>E!9Bkc^W4C0@h3Q^Jb1z(q`6?EYBCD6?}P%*a#cjr|D;+*!GHHR~S-E%|*kWR8fh z6zwRh=|Nlorxt8r=uJnaY1lEoTX99=x%@Lp*`R0Syn&Zmh5>tcJws<#o~5@+(tvpzeA0n+WO18=RD_>1HjD^GqRSd zQ}QhNzT0K+A*(X~{aqC=gT&@s_p8S8;%pacc?}4GqkviuJT)I@r^!GzUce0rRYTFVu(BdG1fMkppCuz`#lRLNvz51&xAaHKhXEnz zQy!YG$>uCCDt+zh$t9NJ<)WZ;wSbMQEKQXSo(CXqb)g%*Cp2acA^)Fvp1NrJavRj- zTYL9A=vvIukHKq0)q^X~rodYF@v zTxM6f!j!++Hp2;eI3gS+qUIcPGW@Sp#j-HUWG>Ef@3_9el2gOw(HHp z&yo#WCT)reIbCxtu#)O-jWRd&Dga)Yu9zpwdE-wcDXoPqk&cqG{QLkdVx%vx7~Qjk z!nFgH!c4SWKas%5nkfY(eAtKH7DCFgF(Q*hm-gA4e7o2V=Jl<=;MP|D4b#kf$C~x0 z&W}qG8g#9vZ|7*imD>25~kD}spg znI&m9>1OFW={uS76nS!5ifjc{(dIOB+~~+(k-sv3B~nN?=Vi6GG-a+&k33*aLUa8? zeaku(qI~&1)^Bcvdg4hTytzKFZjeX^)cXAy+W19wp)hz%h2L@K)p*a!RUoc6=~o+H zv80LDR<^7O)cbRc9PRvBB~kqH%!-yx=ngW^6Em4K89ZJENp+ZrvITQvUy%nceHN0cZVrW z3X#p1l;VbRC#Hw{y?T1DWGLyWk-|Knz+I!%w1z6=kY7swycBP4(bycNnoU1WzL4Eb z3^Ge0nRJQbC`2kon9YRayOi*9eYkdlKW$<@hwb*OsxiYAEOK9vO!omkO!=7>03~@1_Rnu$pmo6|(+>xquUOTV;rL)G%3 zpm3b=?U={6%Io0D@x8Q6=_<3C3jbo!B8Q);m~*;&JRAxpR*3LgFqNF}y&&+kW=mHH zclhC&zFeSr(C+3{G~QmYdGH=yz^zbtP@Zdr0~#bhavERTDvhu;2Z$c=f1h)g1gL3$ zSgtt1)-*`^D`?OPsnmqEW4A9pKMZNBrJo+jRaMuP9pFc$c)=EBqXn%;T z5X037&uFrt=RYmp;plpZ;7i%i_r~7(X0Lc)$NK&tdf~w!#x8m@P8_{}#Vd=mP-?DF z9&4%CV2>fR;kPVrdN19+-*BQuzs6t2((>YG=WNYZ&cffEpW>bUO z-AY!6s%b&>NN*e3JqP8nLs}O6N>)V;D|R*Oys}wA)mU#G-o1zIOw0F;T4n`xWBR|w z^lQiTOU8Ob@$LyYj|l-;o~mZMI`Q7voX1_ZGxsZ5o*HHa4I|c^2E+0{xlNA`fq>+h zKShe4e1DIL*(!QP+0r!z3oPb~CH3Z8up1=})3nsKq5i!={d>9UgfEUQ?S{&2@|bBY zaB;c6gWhno3wy*i*IZ@RV>YMq-sua$oCVft**Hw=HJHeybQoGW1u+EI_gbq6WZg9U zG1(Gn?>Rl7@#67OC)$mO^la>_gU!GG^X2Y;(U;7%msu>d5J87otO&h=TN?7}>{{$> zg~mrbGTCA~nawdV<%mG4WA1r^ILq1==FH$S##-U#8rlcAk71*;8Y7{{zSJ+XJ8^gj zjJRYS4l0~xwUF_7aN{mJY7>3%si|K><{qYZ+*`?;MV{9w2gleh%PS};q#)q5VwyAzEOqn_bH zNOfzet1r?qp?bo=UMRPAHU0dIYyKj-I21CJC?M7??h38dG(MJ@nMoyQdwo)twD1)0 zQIX^+v4R978|3rR&oPDC2cOa=>O4biESpc^lq>);DpF%_oTTwE7V5(Z8>5}l zQf_{%h-gxG7lJ;qOL@%CO76JAZy&x$8+3Z`bMVpKR4__*?-DIhPR|Wl%E-j`d6KCAO$Lz6ZNjgMDZk5sK<{B^#l} z|BS&c5v3$5qzbCg0lOt{`q*wv!)eTXOB28 zxB8GsEnz!+RYxv~_NaheK>~?D>+ZQR*%DJQ^GpI~ig zc@91sKfTUzeyci}zumMhOTRA3)Sif`9enfkJz_2erDH|~;W z6UZ_poQ-Pp^shGCLJJvi8` zsmVicqQSw@o|*jW@%Buys8cKUrZVbGZ`p5>E{ijf1w&_gs2<80(pOX6pe&!|xg_~= z%VbW%B=YA@s#GctvtNB59dOG%X9jNH!3qpC3SK0={K)13`(021Yr!Y4SvMEucNdOf z6WdO0cmd{ z8m;dX%*uw(Un*C1s!SZ>UHZRzVbi!nT{vmh-UHJd=q!3jr!dKmhKu|l(h`I3Zod*; zl9N-Pgw7|8o03z9f^a6KqJU=NceIL7g`+_8#s*aD$YhbXs$|}HagQRDY}#xcd9w|i zWu6R6SwOV?WF^^OWpBRt8v=?udC+;y{S7>UWz*k>Y$+p5nB7}24?|>bxJA>T2C%2q zUr4iPr=A>m#Q4+*&0=BvKh@y-ui7I5?GbjO$LXOnd)tKjk7Ql0`C4rP?c=Ck*#F=| z8kIx4SHc{Dsjp=O-<^sOQi(!>0tPIKd>)FBu!|EwSDN&o;0A`5J{<$YVBFD)6p1j? z-ggQDfMp-i@6wCIFE`FZl>&YPye7-Vz%}?c8q{;P9|l5nG?W)YeT|7&g4i+Q zmk1lU8NocUBXklQJgB*E7m{`}N4%wIcUP#vekkfKe`J@uc{>l(1Z$l|;<+;iW@ObJ zeljfjQ*LXGuJ|Xv&%Lk!K8DUA&Hj+^;|o_XrV}%!+*JL^3xDwY={SdAU&#ILmORW* zRBfi|Dk#Us-Kc(V$S}PPa{Q5t{V|?uyGIICueCj-1ukG+w(jB+nJq1(pRq zD1ed$4SJ7aOjI2|S;I}dTp!B2N^;yZs1G}H800O$q6Bd)(=@)V2F*T7a;!5bfS+{& za<6Y(4|e?0G_GG1$~#ALd^Fe#mZb%DPiJfhK4WK=xPj4)SF3)VOg)*EZ2@N~WHOh= z>S|TeEDO{}oa5Z@#mwsnzDMF(^s`!zzxuTR-!D^)zazue1o6i{n};cH{d7ynr=bSC z&;lcXai19EJv1l~<|Yy3bCD5ZKp9$Si{`y0C=lsp9{dw>Z~)>tvjfGi2kG6b^u`JN zlW=eV{@Fb!kobn!p7eQ?FVeDpNbDZIF%b4&!{8_9`oL)Mi@^o5LIu*XcxcuD*gd!L zC(?{?P#0)c;F&SghTn`L;f%}}3nP_fTb54B=x8GYrO-<3#9z`IR4%2Yv@o05;qoFQwk4gV0>}@nF}>q1`{ia*!&2GlFBTgmx>3 z(SfPoW(4cjL%S!#aAGUpw?n842(vvzhIl_4ebA@Gt~E{!kl9$}5lbY!p9X^b@3^Qu z57^op3JAy_uK$~X%KkqL)LC6tGfvys| zJ}O)HP#50ck`mlMTXKB{O&{}})Byd%o|5{*v@G;Yiz(pnk0(Y*CrTq+s0L0r>>OFB z1Uo)M?X)>-tOWfS`Ub=1x)W4~rAre5Hm^RzyaW^fiH<}+jd4>_EZJ2PSVzo;t|?|& zN!%!Amv(fl3zOx~re=*9EKD6!%qBV|-f=p*@chv(ef6gL9CuEJ)#gsTSa*i{ISD~* zJLe`UY()Lq(NO^p!`%Eelb;4mcslxtdVgJ;K(X=JLgE=r&0?Klau$#O`E=+0?VG*d zx$l95#de!5Hl{d-mwfXJR{5sLP9%oJ?DGsPpIth;|MNlXZhWCOXc^vViw>O?hNp|{ z8g2^jC|e7DIezls=I>+NNto?Z=&P%nb42d>Agcs%OqgTrBa)KJ+&a7U;1wXUf{&A0 zft?Ch;dJxO)z4?FpX1U-V$=*hb+oHC+WD(px(0c~N-FZA{Ew&O^z72ZM=-Ysi@}+{ zFYaF@mA@YTR?ee?g1y~h2k-i^I26?uP8vrCoNmHwJyONmnTK1I2w}5$l7gDA4+?J2 zCS)CiL17Di=(pgE;7&bNLut=eQ(4C-;N-3n_e)_my{2WnC!!<3{qoDvia1WHfN`R? zU-&f9k!HfWaEp3kg#b@EXy_7|F28gbKHWLd$pj=v-?MTL`}98igTYQ#&CNGZd;#uC z*{hPN@g7MmxO*WAO&oA+=sJ7+7=$94D$KKh_Ybk{xkQMF@*Ek`U@hsUoVd&U*BA)-tO#R13iw!LdY0m+fPsN9fWJ%l59fj;C;|$9psO8o0CQaf}(ttPa3oL)&9wEtw!A5c_{@+fwSxxqhNzI* zs@b-DQ*f?&@+w76H5Z2g2~r=mF4WeLgr;V;j|Bscrk|ulWv&01tTaswhzQAHU=R7) zRA3yg!^A+z!&m#4yYjV7mcrp`=*L8)8#aWyBtdGut>OLSHaa#d{2myK*Qswc&W+PZ>+B@VKmYA zF7!u($I^gD7K5OClV)$kENa@d6*aC#Henv`XI6)Ik1p1;O}X^~+guijpLArW#xw#K z@Xwy9(3@cSU8_lEM`t$F{0&uqd&~P>#b&&lxrY1GXYx$w1>C27`$9{H0)%P^z`;!@ z(NsdMuyu?J#?nH<}PUJ<1>$M;G2(A=dke+Z|RzWL9QeXQZ+wI?12@85E^6i zgS*D&ZsrsaLE!gN-{SNv`8^Nx*Cb; z_UQK#nF{t)-44IStkzGJ`DVy`>`Sn@o}V^OarjoLxUlusM>0%<;}tD_(qnaCZLOcG zcE^3Rw=Hs7FCyx1PmC()Z_jBqtk048ZTlC;Us*o-+g1eN3y#!*7Hf}?@FQ%T(t3D> z8@4TO>Gw{LzCBb+*gK&IG=)lBSeG7J8x;r{qYiVSVvyqJLm?W}S4(Mkq{d@anP!bf z#bdQh^I&tkHigCdc6JuVMrxeU@F#Ab+N}0Pfc?pe-!-`vWD+vonUfbQ{*>SfH$mh& zH8ON=da2>Z!7}MJn*VpOFn8Y8Leqr~rSa-Ha?Z}}^v8a8C6p5|pEFnBbCLNkZS7zQ zqvc8R1GIL)#6nwdtxD>kjNv+ZJp*F4dEQ{NZi(-gcpE?E4HRL4Wo9h1SJjm#{PA5X z)-{HhdFwrJRrkg?yGH?I;1ZhcwVMfF z!Y{cUoetIOVoUq+b0S+$%2VCL?p0y;%bx~4D;8D!jrMxpUysxG5t?JrMVfxpQ^lsX zr3%tX@F~HYq)s^`J*1u#6ZuIe)ZZ)#Zn>l$QeQM6(L^7t3o&pO9mq)Hlug1M)TejQW*4YWQtBbTDgq`2KvCr|k06&ZcL0E~T%iK`jkwo$$RTV|!1aoe_nB zCp15B%C{y+5sbHwX6TocEF*Ee4nr(z|nGw}g&r#c4=nM)yhZ8w(dHfs-4g3e?d8X)~mU+1d_d#*X?h@w-T7cr1q zn<~Pi0dFUm%#TJL`K@PgM^RK~QUH`spGj>GxtDoQD3(Xp&e25@$1*yn5FTH=%@Xl% zjNc6H%d*srUv@c6YoR$C>PL3n7Csmf3RV>F!|#yri%11dP}`9kjn*JN+D_b+;|SV) z&{255AgRUk$;JOqoiczpl(E6njb(0&qH$or``d6)$KrlZ24dK0@ zbfZ#B#6V$QF0N$)#y5Dx`iD>rPa)g625;de+LVaU;%pLIW(A2sh3y&NWy4Z>W?p?F z>kPHcufJ}*cetAqv2AW93-X?vOKl?VlcrPG9DwQ;^~^~`3&~Pg#_TEyHVp}N#jw4p zX9alxcVj@Lx*u{OaTP+~9*vYB^rQak%e(`|Kl$i+nj>~^UQvE2Dh1=Pbc-bfHk+<> z29_w5k>(6eUOM0<10TL%3YyOx#hT!O4^uw0$x?Ivshf~N5$`P5IiEq+4Z`3TSvQZv zm)w402kzwkkz4rK*uRNjRu3VIRbwd{8d?o4N0X%&3a*iVU8olD&_}UU?uga-0Jo{t z^rrhWI>XFwz4i^8l3qNThDBwj61&WZX6rmnX~{FtDWaka@TuA5AKp7FDu&2u+}1SM z73tG|%+t2O%ZO<_A*O!d(Nttl<8!7R+7vU$NOn;xUqPn5fgJUJA;|_LI4&vg=3z}O znWv3|9^L-%CQ~kWxGw62JasJFY7KoPmA5-EV+v@z%hjvh z$N>xkY8~HOs${RkIG+{PXGgr#D4B`~ev+m~#ag#_hS8~L71v{Djv=iP&?N_FX(xnl z6h**Zo;MA*@f|qNe#bcAB5S1m3Elxj?xdaF28XsXx=L0$Y+4;bHF`sU%l+?P9{LK0 zXT9L3SHF5bQ))0Z>eb^?YSLF#y6C1l=^W~bptKT0YQ_fvhx_L;)#3)>-G&0`BLMd= zP%Te8{hicRSB-)h0RR5Ef%BtK=PLpRmu8*@z&R;%4}|b{<{Zg)Sci)SkImXeT!#9Hp6M zNl-?l+q4&l{Qt3X*WL;5pNsU*FwUNl#xF#kC6}Rg-|@^UQnkW{afK>V!#L#sI4$iC z6XJ3gC5G;%KAnURWv52fEk>(0O$)1UZkM$-8B1^C9xFrLL=^S?Va*J430|zHOnFYX z@)*IG3ga(N{;+5veX541rS#p!>Ph`en0l~%I+%LVFC?vbkewE_eOrKyYa4&(Cc6G5 zWc@!VtvA*GHvjm9))$nr>6H;wVzyRnD=#bimlthdlozm;S-$spbmlo~lnVUgA8)vZ z+%cA_om^>Ye zC8OEJwcWa~H1gZF`9;~FA=CvusP9Yj2$OK1f2GN;$ks2pv8r>Q>Rs({Lm@>@J@p;K z@NUgv#*?`pEh!9={Ie``W%_2EnD};R{X-f1ZwpeDjA@ZhdT+MG3o{e}#rmmNQiIE? zBsz?U6o@~Xv65!MQ{02hcWlUc4FVQl#Kl}#BvG3#l8mV>frC9%Z+%#tYQm~X2&iY!oa zA8JTO2vETE6JvXR0ojAR$p!V}9()4vbHdvfe#_l&IJp+4WgF1!&fbIC?|}4T9(01f zfd}muM!fkFKOR>LD$HbhCIl4%xfuo_hImE|+Oxq8I^hg-g}bq?4CelY@Lta14I!a0WsLDoH25xG&GXM}q{S z4HhEYRDitOfCT#B?SDnj>=lCfnRV~aLqEfVe2NAQ!0a=FKFei-KBoewfhXPjYjRKn z{cr)H<~Ok*pSnQPOY$Va02SOou_Pdwt0Aiq-d9)ab`J$6ko=u zolk|sCksFC^J6083<~K?*D7MxAFIIDDiVQvZgLhhJ4PoYbXHxsPow`w(2KUaR5hprI5HfF==%oDu6oboL&6!B@h1x?M3X^|n7aK4{q4!R)@y2}`}beyfl;>*8& z$$&oX?rUy?qoSfXul8YLJ{9bb^gVqBUN22gPa7dcrcb|1hURJLkAEoFnF*D zBsZutRMuqHR5$1|q}HTaawsG`Df=`bBqH=8Q6%yUk}QcNq6>;Blu@W|C^OXBKN^$v ztwYRU5-52R_Ps*TVH7ENqW8^1)L;}TdE)ooLfB#ED0pJ`?L%B)=Gv-a*>L!MuL-au zi1+nv4dtDQhF-WH!Dtu?Wc{(x@|0$=QT64WVTZ~fGEo^wJM;G8Lf~QRDLP~JZA0u} z>M1)D_I*O|VKUIRr5oe+sX~q*xY27#I>U`Ahv-585FKc>q}p|BpJ;h375 zoEg3ZksRIIM@)$=Gh5oaMk)snH1a=bYmIbxR)`+MOP2kIvWO3Tc0u9r9bBZ%XgNFS zW$NTjN{cklYOB6uHi+@=YJ^9M$O&17YR5O-w%hIteD@IH@u8Y+W|DZbqwJXNgf`vV z@t8zX7H!Ly;W2AxRdrQ=bmKWOG2IoJ&xqg*W^H|ThB4X&-Fg6G`i55{2XND+>vrdI zHF@#N`4*`(D+9pQ$(7fRZC%m2uc*44g=t3hiMnmkvh68Gc@1rm=5R>;t@O>g$BN0z zRBY$DP}NP&54x^C@#O|Zn>DW;xGktl_k?rZR&wuKT<0qyIQ)7G`E&cctIBH6l&JzZ zd@`lpoyW3*9G`~i%U?r=57ECR@!Yvqdkio+3vBBjs(yQ%Dpobg=85AhE=q3t zRjc#vq#MRvJv&}fa!isy^$l<>n_qL&+w0X)=WE3ZErYqQX>n%&)YnSD$r(2E;y94P zQ@X(JvcVxAG8B#&8IZHjY=$zO5Nng;QC?TP~)Cv<7##57mkS9 z-N}0rH-?9-33YB%)Hq}s=zutzme7&FBGTbMvE<7s9Xqjp77@2#ojR+XWaK7X8E&OE|%w{nfq?yHm_ z-$_F7E@;#>gNap`%#*FwgxU)VDSsWm8k3+ML$u*`P>}%)>bN0Br>Rv0qgEPIn8sp=cUxQX9Uz*>r2dRRS zP9)X#z2zF_#~i1)vbQ`_*w1l(Qg1Eu55Y zOz3^0JuFt_);lRix&~#B;t+sp;p+4TG9>5KLqamfqMvK;;s*-~;`3I8d=_ktLO+)_ zVXh`_=6r^+%>uEl$6V}7Nw70b5sO{&v_$gvrffF2PLpV!M~MLgvGuhAdK28aY!&;q z?K^xGMUDX{^^#0NK#S7OY@hh57rS%%_r@2y{iR~i1$yV)Y=W-FG*~%J>%CZ;o@p`# z-~E$|Mf?Nw6r+nH&>k3F(X4K=q3#N?b^MB9nMkaI3eO2yv?4UVhJh%hY+2|p1X0(sDUTcN8P8gx@RPE<8dEl42Q`mhZ+Ht1p2tQayipcJH%hHVBQ1izmBth zjZ-hiki!ZB8#uL)&squfQ*=Vi&2%+6!>mF_=;MmE$Nd@iq3PkKYvyhn3z*mZx)<~| z$5l+%=Xr@z^GW;4(AK%XSxefexskDv&C3mp?=EOic6l8$LO>7M052t+j{U2 zJiLiQ`E5^rR>ebAQ~m_3jET^ySW`ijbLCcM;#B8q7uJRgvb1f8_l+p;jQGfG``ETb z`;e`y9Q##jy_ViG6>POjcS6#$C`NJVMmPOCj^?`!^WgS(?WUqFERca7X9hjusY=!Q z_|`@grAM2$a3@hev2%cb{d@eH173{vfT?lgS_f9IsW}T9;s5ZXB3uPKmk@Tmq*Gw* zrTWkGk2P6fi0fq|Fwy#NG9}PXg0=dsv`4Q%->;|Crk**4hg|A>Q^csUtP>&M{nMK@ zuyS%98OL-r`e8EIIQoHk|4hzd_0WT3F`Z@f>xa}@dQ@S}YLG`#n?fvKsu9~3Y5*Vk zu*rxYZ2RI=HRNs`skI9~2ZULV`}XX|^s0X07_am20ufJ6@7Pg0B_FnD%NZjEc6O(O zPZjQ*FBZnz!6e3LP= z;&7JM+M>#7XS%Y(Y6nl;^Zz&rA(cw|rDKWd^JL-w zICn4JL5mcY#K_ZYSF(Z4RwDjYtZSUGuVs*6qKmlU2t!EZyqu&dxg}UZb8D+`v&*ph z&4y@ND+pi|iWSJRuaoo--!v!{nU_u_%F_!7fVE51f-(;KU<_UuVhuDWH4^xk75JD_ zZdor^5^YMR+5j0|{iLniyx>bi{^e5{J8#HjdwHbm%j;AqL)LJMeMeoUqXGO1N1vRiFfk^faB|=cTCSrEI!t{AJ-tjykbzVq04{ zxk{j`Lay*{>>no~RDt*!_UBMNE>TOCS_vf9RNu~=lrzWBPlyV%JP~KEA#Vt5bbZ;z zuy5DuFKh-H1G%OBRv+{zBL0LNdOY}GsBZAa=o*|zkR9`FE7RR>IfrrM=ubzSkM?w?MBuHpLa zvTX%&-$Da#W$&nnC)N<^izzjVdg`Bo(Mt653rPdUT865I?eq;a4NLn2GB-?$KB09% zlRX>h@xR)mSGcmP(l2ba`ZfAn=!uh*h!=SRL=Qh`qjPOwgtht`>5b@&R4fNXEUTWN zDaFq|V9zLTkP-oM*?)m6Yy8r0Q=Y1!Jp!cN;ikC|t12eRl@J~S0$3W3 zlbP>V{D4Y3P&TS>wi)j9u zIOb-0pkio!lVy$POa@bcsFV?v8p(u{~i=Jne;tG+ht) zU4DokHn0b>3;j+o#E%*H2JsRwfedpOnna8Sj3gB%n@AK5kWV6xd=DcLhJB$GF+_f` z5eb00YYFKEy>ktD7XV^Iyhuzi!`@9N8KDBTNC&7U8pHy`lJ>&hGe`yyUkF74u`=nz(fdMs24MlPl&sUkY3z7tB`kIATz{^+=LPA-CEKBD$t2Eka}WI z>{BEuFzh{*d&;Zh# zdmP)$HLh0lm`%gC#2TW>(SDvHwwRQFb}_)nIzJ; z{VF@7gQh1+(~-^p1Gu2kVx@niO%5@*ns=DU@`7$z;nG&tw!^QbVY9<$Q(3pgx2I{g z#cx(NU*p11wnLJ&os*Ec^hn#Fc`Kd~$&O^hwh)r#p8`w!P<9MuL$(M^d!d0YV)(&} za>PXgU3`(~!ZHO)1FwQ4&I@rwk|w5tB*}|lK{|Cn6InzM>_Rh@OcPm55bnY=wMZjX z^i6c7m};VtDkg|@;h1tzNf7BG{Kg$pyhuk#G#wJ(WL6KFSY^jV7qBTpWkvCCobZjW z!oG37ilTTI{1l-IR_QkEQ9X^PWS5=;b#ANdye8HB+^cwbT9j&od}Nx!lixx~+;w7J z^)EqtFY4T0#i>Us;4QeLNn?2#hw(oa!(5qrXA zhKLKB%=k7ivTcYMBvULekD*Q-)5>2v$wEE}$ZH#|boix)Yn zOHtEpQ2+sKA8JKLd*H9_hD*eDI3J&EAIL>tP0$a7eI?^+E>jGIdy`1gmK9%h)hQg_ ziVM{9(Ni)|sV6}3M+}q$8U4iN7~vS#_b^3|qM5XLHUJo_V*ccRrt+-PV&stHSiYn} zFo?%ru;l<*3vU6r$%8HOV$eFHEa3o29=J@Z=SlLP;u^FzCptT2u(6S{i@8X@nHJ@H zWVZ2a#*pdDIkGw_Ycb$q!F%rbn=Y^BE&YGW%c$K+iDhiV@4h>h$qfmrioooPQw(!w zqf`W@Rjc!Z%`>GfR>^6tF8ek#cIWC_gs?jJ?!sW~kW(`BuY9&t=+Cvs^{?3YkA|eW zxsb1Ty~8g`s!y#cdC=!T^TdyVmG!TxW&qCn^*Y`cGyClxC3`;1m(qFDmt5ROA(fsW z_9ycu-d7VX&eI;g(NMGVI7fRbA%&X3nEg4L3FPEbRdXwd*QKofceb`$WwyZ}LaAXp zk#u=ya!Kp#TbN`W|1hROm7Ut;H7aPYe4QWw+ZP^0rw2S(?=HoU4tZx`Fu$UC@ZKSY zLA>lQT8Pd7crbliG~+t?8#*w*x^K%O!(gbzXFQDaG8RPV48@N``5R2I_wH}YB*P$I z_LmmK^VYXzo8m`tsej%<9a)fG zQ8U6spjZwfLG%h>d8FuRB!fF|0)rZspj;F0&?JN49VCMQD$uz!*lHAG_d;l|8l9lX zsrN{dL0mnQeY{i<>07P%m_C24Z~zP& z7hqWi>)w~jQcKzFoR(#&L^Nm-*U@_% z**r-K%shu8N)hgN+kEw@grt#vq%G$96!zP?$*pg=hpU&ezk%Q^(Q9S54?L+$hkBF} zE?tv2LbZtpeWy#sKh(bhIP6FVI{GchK% zZQHhOPtr*yp4hf++qN;WjgJ1D?|fDNy|?OCJypBbyWPEe@BQ{#>semW=i}+T*9W7O zcaYUD|Ac)ZB$(SDjiHVCn?(7v+3Lu9+hi_+{=Ldl9Uv#C!Vk{db<6C8PPt0%XR>SD|M}yV4q;`IDIkDrDGuFd(r!wAlZ4 z62aGD)pb1ee(6)hvq4|Vd%V@qddj=a_GRn2gHw_)D~iLOjf~7+*yt!@Lo)g7N96W) zHVv9DT;3$P$h76v)yceazUl$`>JoCzLw;#xcDp+W3-E5m!&NLLqV{Gl>&FaAm%H~q zJuaZ@_Q#HyvSd=E`*SWS;(sdQZ<#Nwzc&`Mj>f%uQdinLVML4mquDU0f5-9F*zQ(; zb-zZ=EyTu&MJ5_WR_S_(T-6N!Cbe!d?2pIrC5akF|DWkN*$bqn$78{P>{vJgh+$X(>L?&8rT)i1@Y@znOq8Wjn>LK>5#8#@6IiZ&sgpk z8?GCTA~p4zA&szWsbXspCKn71>p8Z}S=SKQo z^z099;f8^fW4JI%Wz(gJ$V#F1kwhkCy77sIV*k=Sq~k^D#539B>bMi=KtF}- zd3x5|ZmpspupmWWx$X(z2X3k#^i0f^Gw9%pm38cXFlW1Q`b0ftMxSE-3KG=$n&DRn z`~JYx34UMrRbdVI0hQ{9dyIVQ3}Pj}mo^1)&3M0N5O()57j!EY@gv-StnE4eP4tDYSvTPI_0{1)e)WqR+Xr>s zce_`CpR3z3kyk@@Nxr-&$!qZwY@~~U_piWo*~=ld5gBvCsq9QYVR_o)#SlWjH7g%& zzlaHcqIy%kh4d);MgwW~u4`rO{9b*kb{8_JPwIMKJXZ~nFWy_mvVpKc;)F9vy$PN4 z7C-@B=J6N0aD2IGe7WK65@E_)Bw^-+lS{eH1Ks}dK{A}ajJ&`NQjP;eBvPnH!mh8s0L zLuej~{y?b-Won9oqmno#1|4-$9`SnVK4oj_*ql@r8c9+v@pdUXW$=QUNF$EQuOcnj zMX6Gaq%XIsvC{lNE9TM^(LpDbi6SFUYPFoaxNwZp5@MW1mGa!$MwRmXCNE-jVkabw zU&@Th;hqb#0*zvO+QB2LVLDOai=`St_ZD*rten5BtgoJ2+S$*aUU<9g?4|Afo%OBD zo70&u|Jjr#&0c%30HWy-5ac1gcDLo-3gXGXA7)n9%_!RN<_8AWcW!PT-tAZqPZdXx z9_@@qhUO9N%gZNM-5^G7=_$$o2TOE$^c%`Xgy7n$D%CFX;s-2rr^HA?y2xOW^lT+OsgsB*f_f zEkM9#XBVbDviW$LEunpRdv&JK*40Ib8hqyk%e)6Qp+uZ#UK^QrCogZ${?)~$4MkE_ zm!2|et?W+=BO6;ie}D1fVd;x?$EL`Qt@#7H+5W?t3(j;R*RYcgya#tT5-NpHqzsI) zcil{ly2Al(r=(y#eR*^52?p-oFCQ&?qWJdj3;%MXGj}@%kSvahvvdK;ZFe+F`BS=+ za%dtObnQfhlT$6W2*YPcm-i&Ie@g#;l$qMmS0bQbTSA=^^)Y*TX_PcqudiR7IW&h+ z&aXc0SCBuvors+WyI|wRo@>LWby6wpO|(_g@Vq*xrK38US94D`ygI2R;<{RWyw`-u znBAFGG(A8b{bsy~GnX^tlQ<_Hod>;10+6uT-r{&1r5;hH4v)_lW+NpYWGHmTIMdB> z*d|*_0VHUN=U0zL(~lr+2I;#zh?gP4$kMdmk_71L2 zG$4R^9)%1vCuGgVrjn=9XisDKeh}*8>2N~2M|*xFW?gIBBq$=bz1(_WAonX-oj}+u z^?ZGBSz5n%e1gGh_UgNU$TmAeG+ z*g!t3Efc+G5H}4^_~5Vq^73l$yhNI9r8SRk6xvmA;WKY4I}Oe#rOgi#oN`(d-p%nh zGKnxKV6Pcu(7Ig{hX(712ag5Jisj>OQnN%8l=`wTv6y?jR)&TgMMgvRdo(n%S8ddh zKQ`y?9_|`=%(P#K{KUmY4CSa-fAJx;YP}3|U|~Vk!Nx^4Y^o9c#i%zyEB5%4{CycyyU>tL5sH)r?4-XUE)K56Bi}J&cgmq8L^+WgH0+DM0Bn4 z;sQe#RP0L36Y%I0maxLyV~0Q)V3#Ff;O$O|y5hKjMTj682(Fkr4|X~&zp1NpV7<*% zqiZ0?!NOJSIc!nmX*5n76w4YsC=MKC79w{Sl+xQ^^UC}E+m;K=IOIWhJt_ps9BBr_ z#0-&+6h5bcW&|r*%IQ|wWd?G1W`r9bA2uYP+`^Ddx3td%pKM2>S{|p3!!pHTukh{819g}^M^m`IvC~nZW!l(<1|x~o z4jP_3uCVTbhg4gQ(%8dAKm;{1DJ^P`7mDjJ86x)%A=i;9x1FfAy?1WY!fklebZ?X3 zw*_fKP>OQUEEfFsLE))h(^#_yswi`Qtbm7)jSGI#QG{S~qdg-R7d`?|c?9j}T^ycr z4I6I7XcVNR*0J(F1$(ifz07Eq*(1~@!prES5T&j0#h75eHrgB@6Zr=VUeLh{F`GqgZ09hoCq1%N&vz zuQKcpdZcc?MnmtPqKZN)YvWZ4@+V+MmC_b!>Gso zHc|}KF<~KIj=539$gv1|d))7aO^wJ}o&)f?QBI0cb(S?wB!u2SS&a(}kHj~Dh6d#V zq+Lnl6F4E@ySbdS$LFwi+$adh5QC(eEK_)d0#czN%yYF?V?H8*s?4NIJ4nQ+ap|(c zEzlNE(n?GXx;ELU<6S<~TT0hO@)M7L>E`*0)_aNERvmYf6*QU$3Q&8fApXjl$--^W zLztY-Kt84_*H4#9f%9G1?e}!?p>M*4!zU3OLQMS0_?L}MSVZ6|8+$q=%nd1AU>I`g zQ#Lh|7`w5G7WGq)QE1)BNE$aVjS+KQSe5HCZlP(WkvgluUW~_fpnZs9BvI7Tn}tgm z;qP|c!#_oyzwpY)Oeo~8;jj@DC*w1sFwTX>%ykjSf>jYGbIxc=qY4T?tHMREnW$c+ z%gDplI`)Z(xsOqk32`ssM4+3Prc;U5@+zXVPqkH?jKh4`EJW?%$gqkog+NPpDV83) zm1Zr4$xRwe^41I-Ex{5Eg)XS@NWun6M;!a|OPVT)Q{+uEI~=B}j$W!l2?@Z1eyU>0 zb>nhkG)x4<*P-~fhZ8Jgv%2*G4<;cLj?F*Su`0fzpc^JpdCfFJnqmV3kpT&32TJrU z17hq|#e&hD9ES#W9?Is_U2=9M4%+y-MHEDlkU&KUA*E(Q1-!GRjg-8yZhz?wOv;!R zXlRn&8%LCZK+&Uz;|{{vt`rGHGy<=^2*+gAFsn3tv;C*%flAOoWkbpRQe-1kNYr{p zy}1i96Tk)$5nAxi`ic}wb%Zq!c(w6fYbiYsA0rzZZWt6a_i!LeENUk=0>p4h9@SY( zf~#k`wBxVIw7EScp77;CX%DJJE!~c|>JqABy%>EtT0SiO#OmWcYemNFaMx0cLt47a zd?R0Ku9D*dBXDZ3lH+_MVQNf6V4Z;Gc45PO0YUh7p$oMxohi6qt@MeSmyQn}-?@@k zB42Wy!s^UmGx(_c4tHBZRDx()UCJ}N8&x`BUsiX_48rA$c3=8L9kVrIGBH4URR~9b zr?{nwZNl}2_c@EM3z>gp5c!|Cv1@V1CfLar3osUc#&h&f+L*#UQolNBoPFCgR2M33 zRD>9&{XO$OqcE3is#Y^&A- zg*L@D$eDkxB&ehF_s}!#p|SX-f3%ata<@K1E_mZ$uqzBt@sKn&;^JyK$Yq}6hc#j& zk8V{G=dYi+Z}crtP?{i~*&HK>>m2mp`E?Ww)M4jfwrGw;4>_TZ7qTGcbXiznN0^av z7}1^JsFtc91nzI(T~SGRQVyrZK!}6o)^J=U4Tuf5?xC6diFd^-%u7{WRL<CIz9lreca8?9FYsfl)spsSoZ`yn{NCNHEa~QN_u4M- zbmjDrM%CE7R4%O)dHk$0pw3g1aIGhSj9)JS34HSl`ZK0k-G5($)#R%DhZ0G^M z!Ir*9lA2G(fVo1HV4(5Rs*&%%mWh8FR_|)tu?rV`sr^irJ%} zE`dCH2;W!{eFP9{m>&FnA*wIV@i-X>Zbn_|UNxsW>DXF8|JUsD?=HQ(0JbMV= zc#&-c5N22x#=R}7FZVGwDM)U{UGjc2=PLHtTX36V_9@6uAnymn`(F`$1Q1G?ANsv9 z>O03V1t~~!MqcuMJ|{c&*j$jGVs<*nPcTm(;yq5J8v%q7=7(`_jrz`Y%uWiDow1j^ zU(eZ&J$4uDrkK47`Vh$Dhj@<_@kaomg?*sko1?yS9@CS8q-XRc@0WABV~_0x{V8U* zgFXcF{2|`sMLrQgSYaO+_x6ry%xV*@BENEMQ7Z$Rq#M9-BnrW~|M8&F%BIBsJ1J|; zx=Bx|JN7bbmv!J$(t8jl<+#5QGRK=^>3zn7sHT)u`t3VOJXRl&byKn=;Qu>eO+pCj-}# z`$okYFah0-C@(GvDJgf4q#v>RvKA*2N;UgEtR5#@Yvwj2M;0;aE_ev1F)i0Y3@(_x z?><5Ub328$pFMWqD1Gma$S=61PcwdRC)MQ&jj&{I5h@Enx@uvz3GUkZ0#VW+*Ya~d z{Mg_p7X%##LJ^jd63SJ;tsR zh&|5vKw)M_3vwjc7Ks<(J!`}pZJZ^lnNHPY6lOUwxPKjp3|Bq6SG}}X!vbVO#js@p z9CC~V?7A-3h6L5}C=R~{%bj}~n6j!MIRkZEDRgg@)JAP-v^C}9GK{6BQnU77LiSzfB-{|r;_55o*njWKeunS6B930N z#9f3;ajK233pwpqOAO(W5v}%jhV0v!VMUNO7syG_RifoNSLQvLbB=wV%Ntu1jnMjK zj}}3#9-u%D|N4M>^Nhd)FT=wNl~o9twJ~7`J~O8#P+X^TzydonN1jtCD4=+6btX#}M;1b6%$`?&Y(Ste9Y6$_Np078QO;2kc) zJ!so52N8j1QyI6U2ksaT`*{7U5HD2DmP>#Rqd+jGKod=pwe$N$00=<W2o)-@w&!( zA8qlzT4S`kmD&)`^OXd4S+{cya#s|#j$?TSSY89JM+-7wL8i>Zv<^B3HsRtHv>%>Wx>)2{r zz{C|c$U46!;w)B=sYYA61Z!ZulV+HL2-%uSy`nl=<*&PM+d>j$2jCXMj;_5ld3ni)uV3=T3BlSF5w_gA>5Xr{VB)k*QfnJ<@Nfav5TX% zqi7wC*Xnc=rZfL9`duX=lQqy@)i46= z88h!nBXTvnFdgb0|oB!IXQAbOjaHAz4Ki+zQc2t=f0ziqqKlEV~pWH`} zw!5JZ_%Ikdl4tF?_r&(>Y;eslLS(2v5g7c92jML1zEYn_!ED!ODYU^1= z&`bXE$&38f#iq*6Ga#&5^cl;DvOfF4Kr&rGKTb^exciEGQ^P+FxXdWMYJ2z-h+)XZ zWTyI#s-{~J-l%5`3%}TlUp7>?AfuMcRalc^dCE7x;9FGHUUC7Aw^~B(6p+?JRm~bz zqwxF@IXD8o#|sVDh%_f0#GQ-z`$7r<5h!RIpRY04rL$a+N~BbAB86$~RX}6-pcJ4p zn}Abpe%d=Xz!SM!jp5H&ucAa*#+)KeYxrVCrLCrm`9WnYYX#~2@1(b0IFm|d5z*yE z0_-&`Kr=}d*4P5L%%Y!c*+sYMljl~0!gZFO`>!@6`sfNdQy6HA%$lSNJr9I;HsF6t zXE%q{_JmFM4)(Nj0ob^bSz?VaE{=U+c2O#jee%8uq3?x(Bm?;~f0t((cd8QRhz(ee zyxXzUjXD+j+31k3#zK9n?ZlmiC_6CB<4}l1CPV1 z3y~+hn&HJ8luvYpon<`Ij(3Z1GWkqaoFF7aD>!j7H<)$U5DYfEc zG^|7D5Bpl|g*~nkW6*jUTOq=WJAQ`UgrBwOu~a%N)r?mxP#))@3$D06*s`gT-kg3= zxQ@6qZ4V&Xwqv4D#WLetVz_g()b}W#gTG>}NZsQx3BQY_q8q4dq1-*>OglZ~yujM} zIz)!SH(}pIP7X`SHhI)%?6bJUVqvM(7j=~kx(h~gxrZ4CC(-UqjKXyupq>xKo)66a zyX~mj*KY8rGuUP2f9_8*^Y0!?b}OKDaRp~vJzHh0LPiUb^x_RKdl~*AFRv#ItgB3%!>$r`REBtRF!8~!G9z3x(q3Gt} zp2n{U<=Z;;HtM+Ow|(8gC7#$;tGgwwzNMvZ>N!_~Opl-FaeZ#w&MO2Hrpp@NKiG*( zA8Duzli&w$VmSJ;(LU=m7;xI0e_wW(V8qRXUP9oouHg|e(imDlZ1FWa#ajGzrPZ33 zYiPV}`UvNl8p5eF;>;h$Jdq(Fg(=uG;Qsf)K!qi0naufchVyn7M19Z z1B{^>}4E<70T4u&R@aon_F-L!wy zCs(No!#4<5&KEAsu4U*e!=)$c&K2YlM^f0Rha`?(tA}-qtlPq@(*|B(_PgPc9ADcZ zPaoV=G}@cl5pY%nFoY+nlh6z?oWYqelAt?V9_-36jMk0st6%?$kNI(i<3%C1uZn+s z-LdAO$DGN~wRC$HW>O^barW`^^I`sb?Z67MUCNf<-;ckhJKR3Jy1wwj-k`H9%)>kVzboL;9rZCtcJjaV z4t{JR&!vX@(K*$Bg&d3A=1-tEq+Mo+(Qa|0dPDDPM|pQCXe_{dXlk*SKAy4qOt5^M zUQv3S*35c`uV|^R+3QL|vN!n2bp7e0mcb8xMBnrB%i&`v9RHbq2R|G=0)zZ3=4CP(23RfF z05gQqm(IM6Ki}Y9IA|U58f~bJ3S$TBm~9HcMpxRIh|tkxitNgfdN^Vv{U6$q*hwjT z&NxTuhZv!}q~R;T&}1_%yL{%oGUs)r?cVxUk2?8vqxN+vccF*|1dutP1{>xEYN)mX zSTiA_VMa{z_77%RGN`6MaE37hb@x`F1q`4DW{3e$`+SGlv;=@?VZOp_abUq5eK!OL zRDl7@Ki*+@-{in|_3qi$bWSoSx%xE03<&_?7z?Js96tcd-v?a3*QO?NY85Oh+X>OI zcgrQg*Mzrj*)px1_|-#PLXuy0GIDj@v)AklAyX=W>;LFk|K0)K!(DsczHe#|R?YBR zJ*CI|jcn(_5@E~sdsQLhvsh0jObZtH6FI|k(Pv!m`&WiBYYRzKZ_u|cvH;}o9xzbb zAblneb=;sQtpM&hY#y+Ue?0_{mlp=t7oTK7?!}BA+b)P*+yPhLcf7%#w-}!JzS{Ag z|E6yNc_{_{2KdI0-h&K&P4eyS%O>x+k0rKlmxbg&WQPy7MIP!>8HK9&T{^Z-5jV)5 zMK>rLdgloI8Sxjo87{78i2oeE3x?yPB&Px(&kD?A|bM##5Yf zlX??_^v`-BPJ)e3(E&BX|xP~@d_iBXobr@NT$4{h+;S z;T!hcXYEhP!I*va;*M+xr44zXrN~RwhrLO%pbj} zhkX9Ms6tYvf}$#RSwi8&p!hw<94Bq4j@9R8o=LMdX)tMCXAXLP)r@A6&DgT(h1|4h z1dB~Xp;SRMk>q%~(~Li2+uXwS@6B3{lm*6uaFGO1W>0&Mb`Tzz+hTRlFx22vWC>|Q zRr&Y8Qq(4dEogF1YBfB~C!&IB8$(?%@l_OmvTkU$Lh|3S&dt!{ckuhAq2^-L?_TAu z4;<`oozjPbiOnE`d$x5Sdye?ntUB$pwCci3PEWHd%5pEoLne~ng$iu zD!_y+fg50g@l*3bo+S6WgGkoH?p?gknXk{80C>~}BhUV`@h1;2?5<}%PF8yX%(U#M zfQOth^7syN+NbD7oy;e6O*7F7&xdR3CgLg44f*Tt_WwtPd=iCJ^-BEh8&TZNEzuU`D-x zaCzwPLtEaxTNvKFcAq;f&c=*{PYCU+#mStA6A4pBt|^d6cEm`g@D$ z7kb5R`W<#Xe);FswWvilBq+cWL>h^g9pJ0Cg+)(*QeMFv9u3>kT`^5 zQXkRhv}?p&?LK$l6)Zo%kMx}QP2@TC8h%&3&mOo5+=lfBe2|_Ky@@`jUnB482M80D zKt%2Q6hX;@WrUz0N&<-gp>QE;fzgHCgz-jcLwh8@|9MY(AMQ@d;Wf++;sBw7P(Wy? zu;4J@u&)3p6ezS1KnQ9G$|Kpi_)0cI#$OR^K?!nv0c=TZQEXXkVQgt^acp@Bq5@QM z01_#_2uF$o%&tP8NFQmRA#fB(1?-2l1eO9_grJDx|B8-~%aF9d&cliWoM2jkJVJcA z0S=_Oe-%V1$rAu(05eoG6e-wxSZ5e#SaFm?lrb1_v@zH_SPY<4V5owqhJc2|HEJ{w zzH|vW4e~6&N!kp&`SORRgR^sEKp{+ZE}P1jfS_1LVju#5gh?pmt^Y zG=cT7wjv;*%hRG(L06fhlz9gPjZhH6J-L%bo?5>=C06I_#6 z6Xn3Yi`171Y=>Egbw^8sc>-LLZHTvIUw_*b>=Oot!o~my$#}#(GOi(ZCHs_t#jw+W zEHWN(kF0C3UC}Uq4{`P6h!4ChO*X>h6~j_F__Wa`94V;NILVYJ`NxmRJ?K%RAyx0)H$ zX{S!vo)9mEznP|*T-TQQK}=a4)`6*6i?maEx;s&xMb_a|*3!mveA&S3vis2qEq{J` zt6Ro#KKsmldD%d2DTDVZ5S*gMu&WF~R9Mi^&&^P)ivM;-U*~u#BbJSo0H6}9 zSD(_PMp|ZSHvB_j-yEgtNlf8js;KCSnCD>d3#U+w#xe4Jz!@hQ2nvJCm7R&7cDRlW z_!;p@*|A!mHxbw%G!&DYUP$fjTzPNw6geS)MMtTcC^9Yuc^No?@2*GwFYfofY4U2> z9Pi(S%ZXITmte0Px$J!LIh$X{#6nv^k5-oqtlgya`6U$$wDj6ot_h3+ za$1&VL>Lnz{9p+mBlZ0}ysT-^0Ywv0rpaXVSNdNFvw5adF%S2?rNhD5Ku z9V?sbT6s}o#~+^&OkeW%WSrWI<%^kb#IAjEdOs@ZW@byomy?%i0-~7L z83(m--O+~{BcgTjRx?*66m{+SN7G0)G%)ddb9zK)Z7KB?GIvYwXlV*|s43;g#^#(& zG_#632vcK&tH$dTNX=DUZCmB_sXB2Z9$3p~h(2FaocGtR&tt8hIe1|^b?nrqYyJ|a=0o3(fUUOK2JAxprn6rB|~IIL$(hnY0XTW>Uwu zhEL+LI5Nk0qM^0VSv9MyyvrySPdB)#9oJr{YK)-oz!CQ_M-n=zfwLlFmXRNK-}6wu zi(WRQhUUd`+`EXTSGn7j)7n|>lgKAo$GNSYt;U*LPAaix{QlZu@_v1|gf_Wpa5iki z`|oIZ$w+Hi0LT~=T(u>@bbMD5-8x2Eb49()?05mOp7^$UyyU#mT~jbLEGg(N-2A?Ld=55N6FBHX`lm zc4$;&98b<1(YA5h!Ru&7?G>@u9m%%Qy=!ipv%yv1?;Q?Erq*Lyybhrl`M2j{-Y1u% zMS17ve~Nm4f@cbAzlOR@(GD{@!S-ElyG|{c8)qONwII4SA`+fcnHk&DYft_tTCF3E zRX)Y5&UQ)l8C<|rld-iF=Qp@5q!n+k8?;bw!ngG`eVI$j-$ZpD zmyA0#PolTwT%#RD8qSzQt>-j!C|=UmBy`HNLBRKdJE64x*=YO$I-TR^0gcG2SVq*S`eG_0Xih&S4=*zZOLzDD5c8 zaLa6A^KM|Xjc@;@i!pwkC96JqZd>!x*Yfp!QF8fHb-Tp=>~IKZEAdx?H#gu-du>nE z$dY;|?(Kk5z`BJXYCvNTw6%8M(i+$-4_N~R1at~%fygE4-`mnN--C?KRJ_aXwWAyP z^l7go@vkcHX+`>lV%&R$wr)#M)WL?g*lc;NE1v4Xth`oO9~;=xl-h98Wn=Q1Be6QV zZb6WQKSYe!Rie)j4LvhHMUvJlrSIx`8f`H1j1eqN{&dN)*Y=uP!c?U8rm`0YBP<-Y zMExq^d}daP6J3SFPkN7(rk17}$EF$ApJXV*8G1{d9Q+{0QdE(~XVgeTp)`Snv-6FV z#8~`jzqk=?jC#PxqS>feB1z%0V}W)lr6{8)9lJi{HItMTHYPxuQBKuADqXJrU`|%? zIMs0A>T)g}U&Nq$Ant4Yy0tZKA>-lgh;2eQLlp?ux7$$ccBldi#cDf+7a zpSNh}94d$?fao8x0W=-pB{1uYrS*ppzYwwEPeXtqjG?~}Dp4v!97FV9p%ej*1P5$G zIHIV(f+NH-Br+8HfLjH z2l8F~K2IP#3>JzS$`W7+wTiTYq(WVtgJ8QIpP$3eh0DzmEo)zCT566;hs5qfUgy;O^l0LDwa)4CDZ30XG!=%Q3B}Kh_$@@lVEu>9 zYrL)Z%40H!9c@>iG_Z&mg#{W_FhY#j!chXE5*}6X>~yZp(whj6p<^kiFpK8Fi0XIY z7R`fUDZTW&#_6;Yu{5{_?#LV;4Wf}HgS2o%E}boZ(xbU0hqNS3lmS(0;a7HPl#`{g zChqW@N0O3;l&K|{G_(~oQF}ueoh_<#Xe~=>Ar%e5lu{boVqsx@La!3Jv?h&dJxkR4 z292!w2~3ic#+WHpOrcK_oCa51p-@t|2K6B&8O@}DCAoCH2DParo3yh=+W4Fz&7^TD z!nzW-Rwt@wxhjB%<9dyU9giPVveGklL5np`t6WgY+Li8tCo9SiiXzg#3L!G zrXiuwlqNGL^N-E495{C2yzUy#>5+t=*riR<)a=wC!pxMr<*(K?$O^p?NGwY%XS%oZ zIW^~AT(#<*z()KRDY&-qMb{0DWy|IE20RVj=~(*(yS{=MyCIbsHsYs7?Z4e?cV*W~COJIv&=WT|N5|N_B!ICu6O27!g8G`L9*y6GAeXTUvb^`76 zzoIEaO(#HnA;R1M1qn*CWE`L-a241J^aQ@F5g>N|l4*&^CZ$^L^lR&j4>e{Cf3e~j>){52j3o*i-TT1og@JO&ZKtp9NPu_Ce} zSOabV-H!w$0Bc7+SNIb9zr;&;ZU{I2mE4-wexx7*q;`56)N{WY5`(8u*$@IG?{8nC z#0pAHzCpa9ct7DcZYVd>bBz_nntul3{n4QW;OSu8m~0qs_~#HSH#N|GMLmQN>2Tf* zU!t%9GLRSj@#jid4RpU;ATPut!-}vWMZX*{6O0@7(P5?EVBX+M49)~gNAl*dfwIB1 zAwO4Hp;>WRu~|V_vHW^pw)>J!YF2B+d*p&9f4lY{_Q{1#2JwQi{a}M``o@O!D6zt` zBDCVOLc9XDVzfeHC~W|5Xx@X_I|ZZ-$%NDf(}v>)cVj!3S>c3~9ox{JJdc^J_f>R0 zw2mn=FE!7{ET&^OpD`GGrZ1D^w8E>fO65HIg=7lp^>1KdyIsd|PhPR@{s&8qyNZxZ zJd=Go!=_q))vTm)qJ^94bU%dJ{oKnboamzTui3*HX{;PtDSF*MP1rNL=-4E2Q&D{9 z2QqT_s|5*RDrd9rVwqMovxpGo28wgADoFwkuuE;|2f0WsjyNCP9fG=>Iy&<@9boqy zFOS~Zfj7q3)gNI&-XsFz5nyaowPTfS0Vbe;#Ol0iuM;b{8R_L7VOjdhdEcmirJdXT zMhmTGHlG8r`DqDGvAcx8S3P*)icx?y!*QYYPE%3xQttjtCIJSAIX@X-U!a01nW)HIkoM~d7@H#5$2@b8G^v>Lh6In zgNRyPzB!jl?XLytfX36L$<=AF)n1%Wq6O$2_nw_CGsu#gj3?SL$P{d?^ql0KZ}iBb z)k_X}!iTaMV^A4lFk!|PuxmJj4rke%2{#R=^5Mbm{&>Spk?4IwJ)#RzwJVSwhxr_1 zBs8s0G<1?oWEr*F$oKxbQUHCI4OcJt0S7Wf1&Pam#us5x=K0}3!=(4afA0SY@bmro zaE$+ejrY^$08vy{I(Dr8oSOXzlO3xienp>1>aTQOFo~Jv6h1nB{7JkudrhH4&b)E$ z>=3U+d!DjzBFM*Q4)Vx4`FH09H+b{$$6w#Qr1U+2+%%TMs8h9>(+FW`HMe9B$_BJhZ>@19isrJEroJWXFJIrq=teaYUy(jg8psPz!*N`4qxR8W>2zS<1Eu(m zyMkMdgfq>(V$!n*Pve6pWx{8f0B4~9pCbB&P0W*GB-LHUd~0!9V9(=+OhWQT!9s+v zFPvw#=7C{=D%-7^vxIgG-T+Z||KDx#9mdeNo-N~Sj>9YLgBS+FtA>XbMQkZ&N<}Rd z2txl7~?X%el#x%WLdLxpwj4TR!7TIeDa91WE zk|U%wa~hQQ!75EW@^d_4_ep*1SHvy6M&2D7j8K9g!(lOo^Rhor&m6RSx~qq!8y(}i z-J3@!AG2JJwf@}WHV)nPZ#f6%#^_Oeyo4be}Az+KG`Zw z0T!hqpff@lR$?g4nfs2E7Kcg z24}~j>|i`V)k5XN7(K0mAn0lgb)B}T zitY;`be;F`QjD==h608q8hlVs5xNkfH#NHNMz2F`R7YV>%;?D^^KrqtvaSCYh^=0h z>{7L{rn!d*`jP*XeLhQF87VqH4LAxUIrS5=t2qcD4WC4gQlb0D9g`;Qtz42bOsfH~ zhs4t{aOp?M<>kavcb$UU!iPIjvHsujbylFDy`}Iw1W2!YdxwzRYmz5=;YB}`cXmo` z9T)`nc0`GL;W%3A`U%cyov)2z{aNvK=AocpCGd5~P%A=%*xg!!d`*$`h;QwG2WhYG z81RP$C5J;i_4h(^%?WP3%z(!6J7o6#;gI+?p`g*oko4$KJD{NTuNc`i0sxG{0TEI6mY|@o-l%S` z3OVxIntKI1zI0kUs>HqDI5-$Og4Svz2o@e8-~E`Nt1(|f`+E!6I9j>~daXqQRX8|u z`w8&roEh1NZ@yfl6v4H z@y+fc?NwTK2Z`S`3GDEZ>Zh!dQm^C=h<2hsk}LEKdR!P>06t}N#-r5DpS_w;y?$X< zb8k>Pb;daO0q8PJV1UYam^Z#P@iyc`A7EBiGI9ZwiSfT^u0OjF}8 z2+ukI52X|D9{|q+C(%f9=nj$M5;IJ1{nr40(?B3c=-3lO*t>qUmk_#xqPR2+(@XJ{ zl}iH=6RyKg4AIU-0U>$|;2|Gd3j(|?Rsqn*k-}r(br>DPnaR8UGf2T&5yC(U5zWqo zmK2~{u))`~<->J^Q34IWhLZYKm23<*7!YZv4r4Ydblot*ib9m~H5AIk&>b8_HB6zu zn^k~`q~IOR*m7(l%99MhL~Q5|r=l8;kb_IR5Q92q;E`yRD2$-&5pajn6GjhUN-GGH z^z{wgnGks>?sMT0X>5HpSMRIs6=u#)1s^rReV z_%L_z`$-v$zrA?E%c7s`Z#efIT`t(+Ut}5i0GtM^woTJg7D@wXuo?=7Z5 zu8bwZFc(cf`4x7M?eAVM`_mKH2amh*M20)89^|>ncYbV##J&|2ybxgeLG*4!&p!Wi z!{^JB^prLM!K~jHpSiK5WMMjl%8yi!o9y8qcL-1TN1323nm7|Pt1owf99fIq~HaQVCgZ^iW9Cf;YtI>9A zy1~r-d0OX6N?a{r(wnrBJ17hO+Gs6x=dk&iGx=r#tfcH}t}NP$V(p@74Q0!UD)|}d z&$QY$@(3Q`Yp)VU5!v!Y>;v*%SiYx=yarbCSi)}fP~A|&Y9zr54xZ@^VN3IXcbjl^ z{qWmne_v&kx6fUmP^-HT_1C{~Ykxkp@LhN*Ue|=sd|OTXkP~Dc_g6?>HI#(Wjq}rW(F?uwTfZ=&toyhv9Ttziw$$dX(EVbJ+-l(0>!GIMX(@ zwjt=iynTeqS|h)|$dGmA*Q<4^)SfWl_{~%&eaha8)y*kk^b~sN44qkpc+nu3d_o?2 zC^%qv!gT7m6*?y-jxUW5e0mdT*EnAy0bLiwM3D<(mn{1HI%EVN)om#3P2t> z1oCVOGe2gM2E*x7JgTd>WC1X|d@fVq8j#|VDNh^llvF{)_Pu{INU#A!yqm=oXZvww z5kcz#iEXT}@*j;zaoNYePb}BSZ__3G1P@6c`9qqBw^Lr-Gf%1W+`?|<{ojYb7t8;h z68}`|3-lEaoq33x5|6yK4}7ouUVK5B7mIrInOh)EAX)t}MXdPi0{y7_>)Qf>oS?!l zBHHN>sOKEsOy9qM1mp@nb$q&cG6{()8w+Ex4tIc;Y`lR)tri)ig$sni(9v7WVc?Cw@0~?hYp_Jf0pkVfXl+WlfA+*t7`lWYxqaH zB3JC${U$)q2%yvtE3t#HbP}{VX>@jE;0TX6x&W>nBaIMxBLuMTJ%mqUcD^ahNX~Rf zGcEB}KWj_?#*^8oLJi9i0gO0yofXR0IiCv=d&j z+9jr>l|@llRPjP+_9ctdDqCijNpaR3<<8?EtWQwM=piPft-9pMEA#RFhu5I&%2bTo z>ZN?aBA7&Vc@+0M4HJtHfek$TQ7VqtCwQY{EYBuImi`skAM~mD4Ay$l!KVkv zLdNkf=FjhK^9=i>Gn3534Gr{t%XYMldBj<0^afF+!5fP{FXiT-eR-P?JDTj%`>?wq zy1_PhHzqvha?lp+uh_KgoEPC==Kuf8E}%I!ZOV{CKum=GzhxJg|5tWlAoIUNGw6fn z_s@HPUx06xw*bJeXrRA^#10c2^Ou5>s~=cgvaHakUIXi1gL)_fUuzB3RZctIY9H1= z>|O2ZmsUD;nDqZL+81|Zy>)Whn~jb=%?du)m__Zan7J?UkPjB_dZqz)-96e^CdzlI zcO+#luQ~ska?+ylkC2(xVHv@j-gNQ_FNK39$cm;d+ZC+TmD0oxCy{V2%ZOSJ(Zt^|l{j zAgc`n83Cj_Mg*+Rx)Rr7MUcYZB%vhe$ZMlS=)-@6^8iLAD}JDoI6{O&O3o%&`~XV; z!$nxbgCrXMT9AXq7HlbN<3YU)rb*GY$}#zE!V(n}j#T0O68Li4-vHumiTQ`_Y~jWd z_|m^JJ@~@WBr1qwvn1|wM3xe$z2I@Y%hb7Lx!3YD^D-sZ9Fx_#wYfv<4wUZsMzZCX z5U9L}O&Niw1Bq>alv3hbqUutVkKv_sB}*I0sz@B!!>uKBq_=qh3kfX&iS`AvvSfA? zwJ{)imD+5j=J=Lq5DcJMd4M3XEdiuU#-X%CA?5P7B?H7yc24d{6#gP6{p+3xGA1J|zR%8`#bkMw91##*Dweb%zd{T*FWu&r;+HSQqPio=x&oN$7oF0Q z>5*UIhA&8V2od_t6n5+>t?$#7HdGXOx(X>es>*JyUQ79DI%1fwPHK7^DjQpC=hoT^ z<#zFh8E~B;Pr$fXO`tI(HGr)jI|F;%A@`|Z%7-C^8}R=W5e&>`^bK_ggWqN|V7 z>S?fc_sQQ4VNPUdlPA9K+8AiS9lX#=-8K3-a)`_)t6(H1W2uj^TJPFVgb0o6>uIXV z@Ic?ZI?);!FRhlPmu&|E(>)?-BB}o|?%Rm4iH6IUr8w+|ScUr;I-*`v3ru(qrHrq& z7Zuo4O>v*`PCTRPImY?!lI7*qc|Z?sFk0VxsmAUndjnCACPQwUHr za8jqRtl9eE<)Es#>mB!>iDEc&7Rn}IP-x_+6r1yeh zQaRwv)f+jRf^h>8epM1L>fu1v=`TwI5!NRrK4p14NjDrH+NdIr{!x6sW- z&?ZTI?oMwAntxBrAe5y?wlb4rqRs!;QFgK16BS<0y_%Ws)&PZ@vU3O?$x~j#)NnQM z$khx9E=S)YeVn0V;Gd68);gk_fDz}Z0ozc?KGLt9TD-NsH^QFO|s#mrT5co90VrmBm2ih>OuHHZFJ<#$RmgkY1ot0a2a zQ7~BRPkg^>EM?jpmdW6$#mSJZ+KPz6tT9z%<&+WoYK|PcCkg>DP8IEI`W_n1^2tdl zT2Z97q_u_1ryTaC+K%)eT#pbyI8!Y`_ctnTh!@e>!u$yUkEZehjM%r7K58I)=(lfM z4NsLqrQzqggffW7g(^R>nxG(UburY+urh=l z*{7sPX;-Qd*m30B{2R(q&#i2&;n*2qHPZ{*-0?MG zM6$EMDCS?0xq%JLm@N1!xwZQjJM#E2ydoO_P>wV85jf^AL8c`W*JsnJWWCKEM9g(FRL49?wN8NY^T@%re-C$Ngxekx-1| zmZ*eRGEvOYFAqeQ3{LzvB&SPV^+T9;sbO7rqd`VydHXDPbmyl@WWrID$;`CG9(B=( z@>tSM|43XRBngr=R z3=8XXOtU_fcyjs*ky;F$Y^(wU^5%UDyj=?Gfe|y)OvP-0Hl{Xga4`~cU*))LrO@gS zmbSi1sv!z|^5$Cq)jd&VTnif=d?!bi|u~FVhAYHB%ole0D5M|J2Ss({GJ$;6X^kl~^ z6{aSqrjHygOJycdAOj<9VLwuw^=z276|BH$XCY}8jI#u``~AHG6I$JnLf>-w(4-MO z)F&}VZC0i%qk2Zv-iK3@#;vkc_Zb@O10Eu(%t>e9zSAFUoR+=?w0D(QoPYs8ssbcQ}Z<%d0 zqL+-f9VLM~>Xk=&fj!neC!&Wd_nhnC>q7abh>J7jF14;J>J6HWr^E}7R{5tdG$XNG zS+TqM-rgiRyGp*mCg1z3BX5{r&T7iacp+Z7t$d43z|yA19OWl+#V3r=4eybQkqw4D zqMYmM=qH<1u@koajacuFz{$HMn--p&P;~vihpQ{nCq)5Y{7*2MDY0z=D30gK0;RoD zrHp?k$><-PEQ&{v&=J`NlsPG7jSe#A$Cpd!2!Fyv&PzNWZ~pKViB-9620(_ys_eEN z;32`?A0$jhNPLAIPAS1BxoruU{OcYAio7fvx4n6^(bLYH+^-)nj$qXsOyvU)LVB0R zc7yb9u40F;Cndclx2*vi*B4{*S!~0De&mdAU-Fm^Y2XVp6MrkyeD6y(I0^mUNdBBi zHgexguE?=uDt)yCvk22>Qz~%J$SB6P2-9j~DWKg(-#>^p8!t0r_Vj2m^8RzFw~1Il zFTBFG#5Of{Qas|K+${9v5o~4kCzePa!&)L!WE&k&9LE&|(j=QuOcH;73{LD!1r?Gp zsMDg@t1I7Y{RfIAE3waZnw4B3!+B@xm<77x>Ilfri9ez5I2j??6;rslB%hoSLU^&n zC(5M@KalKz`jTJo^NKbHYh3z-PxKLJ)lG7R6uvS0X#((=V`Y^ozjch`kw|c%Y?J5` zclq}+PJ&_&jx7o{ozYrTMMgw4{)&V6dl!AiZ*>!Wh~pOCN~zt=D^QCt!aIZ2rc(31EmD-&LkY;nf(4Heb*tf_#R#iJ8?f8 zbN+N*ZPHoA412gmo74am2BMn5)= zz`klRTZeSuYS^EoT?($pzvE-`&8G|AW=j7m!47l&k8QHC_6X( z%S>BlUa~89;WyU6;esHCzHgUUKu@S(nF2AxT<#jSPceN2Xl?NPUptjUE2p6xYE&WS z;yz?~6gN}yO2CXUD*a;lq=bZWU%9|UX`x*nUBgb_URhfS%A|cd1GodP+C) z(~HZ~_>f@ks9@NuaNBGDkRWhWFyhs??R95JFmKde=v`9xoq9KCey^G2BZ}dJ?t1d* zdXn@bkl};mn(^qGk@O>i;e+P7`sliv^dp4fgW}r$=-Qt2BZlFF;rim}`hxT$fZ>Dq zn&{}7i1Z_z;e+~m#rbLS?}tvx$JZxDm#6B#A6h9NFi-X_PZxhb^in>)JQ2A(cg+R(&{YG>iK`L`2~UGOokvG#rR*c8dP-eVPDYj*7!~t8-hqX z%kx%)ik&j4m)9~{Q;`P0aO0)%7YA{({BvPCXo()1>s`e|#NtXSteF8phm=t|PAD=c zaRg#f^ST+lWTG8yah%pUZB4F4L|RMQo3q4t9lFHjUItFd{~{R99E;i6TuD11!4#YT z_jY)=hB*VBcDJg722itPr;tp(579czC(*@JnuecRB@a}g7I0fh^Pzgn6g;DqN{|QW zp_ZBy*zk!q452}LXLr&%n*8=>pniniw%PvpLS~0A4b`oE>Bgilx-N#8gQ-^cBkYYv$+20W&W2}fZq@)WblgP3#Es=5E1 zH?J|yv`&`l!vCG$1`EG->DMOd;S=u_&8$uRJYNFY?4@Ft=L#Q*a+q~Jl6l*C@39}eb7-U zWcQT|B$LL7Lv((%+4&b?!%)E(@-?5pSOkvHDsk5Zq0zxuRP8~GAMi30=D$x&D1xnP>XARsYhrYEIzO^ft)IbAe$1b6{ zUK_?EX@q6`xe}5)e)cDjMSrVUr7TrwzXoRnTdb-v-6FMU(-t7UWrL2Cv35#KA?!t4`WUJrf?21i76))JKUnty;}Vx{izAA2Ou(6tRSK z>s~F)iQ+jd@oG?XqXk_sB#(0T@e|My4VH3E?7E%ocOo7E73n0M6a$V);?nyc&>5Cx zoxluYShD0;wNYozsKAz}6zh78l*gjjB$6)LC%xZ8^7)c~*!r9Izb9MbUsl(1y@$Lf zPnI9X;5$OcTD0mkb)eGEsDz67n6@5ful=6ktgC?c%JxiJmErpE#1tH7P_n#-<@n}T zK+=Kz9na-euWPX0q@hX<0r2*w+;Vg6flOpapkAJ22 zV25N<5*PgUwtFz!Ef_Jm}Z8( zjcMfSob_aR8y4;kc56=H^BBF`xw><^R$jMG(S_^W*~xmh@{PM$o-Up2w#axTk|^eQ%^+<*OKAqt~lqbdvsZ;#u$R`&A}` z$HXCnrx>0G;g`w$&IzZYUGDPsLmcB>4@f@yd!EUq_yc_3D$84wATt}-QRZpy$ipXw zkV9@pv-BGwr+|W1g((qF%10YW%AAWEGV37!o|{+Fzs^)gl~0lSjV-dbjU5M zFxlePaqRUguVq-SPZ2IovHmA^^lt0?|HPKzxNZn6u3Ye_O5j`2{x5bBwuju;$>Gk4 zAY1jo0}9{z-6i!Z;#>L2AvADi8f72%#y4kj>4xe#pPjSnFL&wzB31<5(906xJxv3T zQ!OplQPnAl%~pvok|ShEEMR3uW;YfiJEONV0-iB4Bv#3OnQ5kkcjSFrfKyNstFEE> zxlMsL=7e{ZeWpiyK}XPrr4)B|n+|AGg>;WH_q9PhQQZ!i9C}|j{&#+E)amur;qUO) zNYoof=cf(+&$_>vEk#BIsMuHD-MEQ?z&WgN$DhVvo@7als zP$+ObAnggqUmK1xJOsCU7opxjIX|U$9bJo)?dPu(hsT7Vq?Vtt&R3fIf<$An&W2^m#YG!5>LcpQ{w!%LMyUQ z4F#*q^rm@n*KP{$V9vxzi4k-9_EoI&YZAyJ*0?*j&rMPWKRF|T4Sus)R3}8H`WKiR z=+U_;ti9~ql*iF&e+q1aer9D|FMt=%^k8taQ&=TFc?dbxfz7`2vu37~eDW6EOsA8H zl{IVHF~|2f&tTptX@z{-TAOuuRsSxEl)U%k3_qF%(~_v~YCPj|kwKabXW}+blJ(_7 zmaZ-b@~|2F~c)jE2Nmo$$ZWvd-tN_KXGIV|mo!Ctdv?NI@Zd63;Ohn#6l zORgnf=lDkLveER@)vNBiUgBQRQ0&>o4RXU?klkH-_A~K^gtoxpaH+2LlSY+~U!UOI zzDx#oGIdryC?lH|#xvN_c{LpDh$S{ik$ieOWt$+mwK7yoa)$%Mx$sY<0J1&iV3K?i zE154wF1uAMn|{*+z$YJMZe4xpP3_TDx9jM7t%B>Z4l~KS>4D65@c=)$5PyItO{h*e zsVA0w(R0J^?h7?3-`N*L6bP4n@q`?2jsue}d|Em(G#2lqlC<@GE5ckrJ+SStlBOJj zg#5n7%BvDR?m65HIqo^lEEZdRyrazn$cjVh(4Elo0-2(9133TL4tHX(?}!Ah^<-D8 z{&zg5(TQ7*RWZ=n_Z(@WE8}Kx=VbPQUhVl1y-P5;t&8UDwgDB*DYPStk{BWJwi?ua zk)hjs_eS&J_8MaEuK3{gZQ3Km!TGE=v+6760gVZD6_DYDx9OAQZmBzX;q`^xBZ|M4 ze@`i(OL}>KE1GNi-6#8>$)ebYp~nQxoAkMeS}Au{M_Dx+O0& z`Yp-qWi&$8784rq!N)J=d(LjUd!TP zo2|o|xx*S3_J#iOU^}2X`oVVVs*3FL1{m#DjZ-s?>>MujQS#E7{8?4RYICe}bZ6gm zN@MP7&kugTMXY?)!_)PvabC!=X*sdyfEmQcr)+%(UmO5J7OAV#(k7el-hCN5g{Rad z>#F08(=#5}ZaGe@&1+=Fp1c^vS; zz4zS-&}OB&>=i-ux~cWt;wvq&fu3_O)1f)$79+yj9g>v|&BeJDs-kVh)i!6aluO6Raw0Tv^VB3s zQHe-$_%t?kZp&;`^oDC^+KXNO@&{!6Pgh zn%`+@4fb?2G~sB=7v0?&Cr03ovC!gh5h7b8_9SR26(-?m2Sv16vjlMh3X`Nl8g3!D zl?xE0kr#!d`-oZK9r>oPy`@pSUw%B^i(bz4l)Sk#7dq>S_QLKYKr?VcY3&N!JYkaE zG5@WAko-ml>t8@fhO{F4i?{hfm8CK62t}7wPm4JEx z7c8VXhO|qym_1P$UYc;j1%>dexo+HYjwfzvP!uWa9N|t7WAHf`_f_$_kWRUW^QaiZ z!JgvUET1$M`pNN!AmOgHM#zf@flCo)PTDaRf81~B<1fr(l$hE>KYcpHe4+{n=}M4U zlvdO;e&@iQ*Z25vv`m_6p5NRGZqKy9TCWDNpU-{_bp8u$9~e5T;N0s%Tuljjfp@5e zeo*xR`NTuJmB+0Zo?m42_^`Gt1bFec*q@P}E7Jkn>5C56p^m>RY#<$bp{_mL2|3Tq zx~2y=uNX(2i}$`^w-CWTV7k8y3tVzI<{0*Nviv*r{j$m!_(JZ`{qWL+IvvNo>ocVx3IBSCXbPkx{`rU{*ii*;>Ib^6>o=?-0HU=D&C==u?%D zc6Rcxw8^&mK|Wk;zC*71^{)60Zl3ji%&dTXYM~$U;=s25&K#Li28Xx#8IpHES0> zZ4dA=BXZQY@AYvuanAUi;@^(GTHnhLyXtk1`XD>PH0(pM3^;&0H{PYqH_z22pInjQ zMWlACi0e#m<-gGgG#8M*Ivo%3z&u|69%_Bs&wjtP?D_0~o4|cs zf2TH{TR-&U>;>c)2V=+z3>JOq2SU(k!ADvxImj!RgTIXfQPV|9*&@X(FimfhMe*p` z4j&~Vb<}icA%buX70?iQzUj`^k+vUxH*F~uqSP2%#myHgH=O$9O_{Krp%8iM#9@%m z_=7A^Y|&vv|E-44Gh2TvjS6j8^xJ98y<{e=#Fa+feCcR4AZ$zhEpC) zhu+xE#BGN_f+f)h4H*Q=4ClBRD=iI#$f`h5^?sl=Sajj8B+}DEt7WnesO)J3_SA5u zrE5dNT>Bn*z8HsT+mw1J7u_&q$qrsa2s#fEdg#xEMR7*Hr#kfX0D4XJ<<58-OkrZ* zk|BD+!`KE3O`b{w5jKUj&d3@~m}59q_W;!m!PYg0NTAgWUY32r#+t*ZY>iuDy6110 zK8TS5!J;d!1){Oqt5FjT*;ph8=k|tRx0*vQjayQ>=TdRZyX$d_$Y4?PI}otj0K8Fi zNR+%iuy}b*U

nY+k6ZqzI7+>LA>|_tXsJ{0=ivZ@B)4P!_S%+iT6raEhCs$>Im1 zRIpHxfdUWW$YLA}zcs4Ufz~8K9A>n?D5)WsN`noCIi-`-_}l{_a^fUh6wMG!roo1T zxz`WO`kWafHEDrpF>A_CY@#vYCt+r zV*@=pU&nm>TZx#gJ&A5;5yqt34S498Qy`t7nS^`zAX4voYz}?K?CF>oPd*P6gKS{; zr3?rW$5eZCkj8|)h;BGd!;XO0d;diDB4~6djV7;j1te9iqYQDUet2KlI>0jhE+hVS(0k z`39HwBE3&WFS{1X;(FG{Lt^=)3jx=d3RSRswhp^6(&9ySv81sWcx2)kJl8z=q(Oag zu($*soG2GxwmW}zAjhmCiVGMV4b7f8k{Nm?#udeMtZz!RJM3bJi3@xgq0jXOB+B>4 zY10#MJA2``Cf`fbXcj@f!|eEXYY|*pM`wHEL{n#j<47)W$r&bS&KC2lW{HBpB_ z3XN_dZe0s&#i`u|ogV)5r45Zx^}VN*)IL;w;QW{ZV*-3SN(9U+u^;y z(L}N_KI&#~OxUGOyAgCDX~xLnm9P{#)@5=}S}&LeIfO5<|APfKfx94@Xaw1MC-jDN z2w!raibXtuJ7lcZB!<+9FAZ%dQ(~Wtg))IVc&yY!j?{@Kjddtfa-WXHJb^oOtkqVMs?}pM(Xg`AYh+P|r6lMSo(cBTs^75erXZ5W~-n=kM{6;`Y%`u4RIl5Uw4= z2{Xifr-Ar%+Pm^4=E}I*e6<~$t`XymfBljJ_xMj0c8_E`?-syf#`TPI#l&-e!4}75 zBAJjEj7R*|)N=W;94V@`-FhnXo5(ItV@L9UK4(7k%VNk{6Q-<)ZQ|cNnf0ROS%6Ea z7t&g!vnp|oDmAYVc@q4HKra%Xcd}N(;ic{G3sO$52l-suROmvYh|hcGU*iPOZE(-! z?7npyC-2&9@%ZA=Y)yqo{ywePFlYv_;_5`yL$AFtm5gKj)=sa7-sA{xGmZL3G1F85 zUL+eyW-Y4fs@mhuK#+Sk(YNRN)~v!-3L1U-^K5+a3mgA#!khQrPU82SG}+q~na3KW zq@5my=hcc+r_ucN{-IKX|}0cl5Ai9dR3iIL;4yi zHVH>Ui3i%Nf;vr}+PvGLSO7;Qsgj9NWk%X(Ru-QK0%u3!Y%tT*5vOW2b7oZX; zGAV?z4OzkM9nJ8g|LrZQvR@nJIr1G1xZw6SKa)PB*y}ALsb9G~?^=Za-_mr5y(-r+ z-xZhnD31JMsQy77C6{)e`w+ez!3CwPy_363M-EG;C6ZAu)!OIfzh?(zxuqiZ z(H4Qo^KT9oAzyC}L0aw-GcyyC+aG%`5@rudmRpS=(m@%eB&>lJ1+tVB&izKqS zY+>QKW0}|E8VfZF7X0-mgX6J6noz3|m35VT$zM~OeNh_L7;(3goiMAmV&1xl76rw) z+=g)-R94WmtBBEi*OXwDCaK6xiqqa~j!_ri7=LnFg_(M>8G7@JnR@c6dTJJ#dK%dT zd3EPfQU&?%dcnX3OminL8d9llK;CkrBPNga8|30tTd8l>^~{84nQlrwH$mh34>=@e zp_93iCYJ5P%&_jpZsAKv-4W8l(Bnw@s+DQ*yI0blvNj5-f`uFK5KTTfOi-BV=U@1F}Tk-ls$ zzyF;Eoux-XU)?rS>(gkz=CSmJF>h}H{ngr7HP zzf<8sz+ar=pvLaX5R7pGw;#%M!YX>3iAjKmGYc>2!W0>=N%|C(ex{DV&b< zj^lz}$-r02>aBn~E%h!VNwn}<_!^cCw?Fusyb=X_#Z|j9H`ZzY3^BAH54_otAN=Yd zL=aFVq)0Gf~+zzumq?DfJLuOZ3ckP%3X zC4Q2+_5iV29<3>H7IZ)bR|*H9Ft8|Qh#o@}4lwE7_qon#N0$xt*P5k)2wpi3CW-D^ zjkHIZYg45!f-fgAZzwcrM5R|RThsD5#Y-Ag{6+X9)6-63(jx2;sBG0I?$oLPb3?;o z(j~|31=*h1@H-hd%Xzk-H-1gu& zt_i1?CEG5)B^H74RfB0fdEX65$+W|z{J`x`ew*+5vEho9Il%-B)8H2BuAtg4%L)aY zmHnhB!v6DU87ft)3=oNkq}rM&t-{3hxFXHBr*gBujH0V5$!6A6EUA;`?Chbseq1Z% z(YpxkP_w^;DE;J%4+~AFsCt5IFBha&j7}t#ZglmO>Vw694z^ijOGx`*B?u1K1?oHXyLEB?4=f<8c9!l+oktJvO~Zf zGW>1RA0*_^41#YF-$rp44)5QLCR@kGk88ogPijHNPjE+b(AkFKqIUdrBDyNt{5+Nd zVb5@dxk*pH4&TuTvb^K~ly3@!vu+ZHvtKp=kb{~NG+^x+ufA_qfJiqpK^~VSAl^U( z09G$~_+ZZt-~wu0b6dBkU8)1m-7Wk9;)420Z?ltp9k!zy^b+up@(6Jm03d=A(AXC4 z36=83eslb|msjpNw%gMW7yemNq0o5swFqhGQ z4XEtDk7k$jfDQOA+3l5HHwkabM~3hVm<`ga&dnFHE}~a|5ON?<{G;I|DL@e3S7v*# zS6G!kDIA-Bwy}qNOEf-*1@^vTiJ>$wSAnHaP~E7zJouu!t}!L?u+%_4A(5)PpjU9 zSLK%--d(?WL+dFNIl1aDns8unQ@XO*2VwYH+>Ie+TN*$x>5i7sNbZi7kw^`jEW$Ph zW;AzOQUk2pQhR4DP1`(ZRkke?Q74Ek6MzhZdOf=`YfSzwDr&sln;U2c+d{XJx;nB% z_PAw_{Ve+}IF1$eCU9qe$Ehy(-}D%%SR>Q+0BDT_o!haQ>KqreX5{TSA4Yf?7~&d5 z$oFV{TeAw4v9{i?ez-IAZzstJs3x1OGJj0B z@+s2FDV;YjyTh>>SbJ`<2DAl@pV}WMhyEm@-6Q@}e(h-2{*0u-`k=mN(la)ko0hOv zur4K39B*3QuD+_|KHNC$rysKUdH zp|4KK^wy*WuKkxtuL*C*xAaOM*>&Xt$D}kB*)0aounL|9^Y!l6mlFuV@0Tet859{T z%Ji0`1^P53O=nH5iMai8WA%*5JAi4TN$>O;1M5Fs4HfD6j8lSDC-sT?sS)HJJ?oNB!9nv(grb{ z5ps}rt4pjXR8+buYqhuPEsx(#+f}8w8h3`Zk6U(5Wucr0N6_a2dvynZt{9WQ2An>s z;8D9u9*C+pqRY3XyR*4tw@pXIuZ->;J0sT)JD1zzT2p=g8FAeIxS?8K<%{5qkJ;{S zt{@Oz9I3^lH^%3UT!FnrdhM?4#KW;(T?`sCHoqyo5L2FQYs{D@FKd{lx3;x#m|Ol3 zw2*DL)Sa$!F|)`TP_;hrtHKa`Oh=ftrsLk3>*rGAJ@dpeW#yn#Yy1g24xP@7b@;dS zCwrHzN5J<4J;&y(Ruz{U|7cHL{lv_^=H?V0^Ds*I7_471Z5A7j=X_Le=6vpseC67P z02?cX%U`r62y<;wez<6DtQh+}c(rd*Sb4Nl5dfQV<}0G#IyJ4gcJ`}zZ4h(v!Xbo0zln}RHKiFhTg%JEK zrKN-63(qn8zT^=XplVrJ`Ue$7Pm#_350UWyHQj6NtG2&W6zqxOeca3*%*;NU>sRDA z*BRTW+N2{AEZcqH_?nI4a-XOpr_(fMJvcehVaIq@)|l!oU!=TC!ociiVc8FyPoatR?(~uH`xBxOXybP!T@&5+UZTVib5c=sB+|cbP~b+zhkc=%m~B^WAJnpdb%#tl#cfj? z!9#3M2fTI2ay3GTFh>gMlY+{+a?o$)TqlTl-md)t<5(yh)|f&gnv3xO^XqM|EHu4r z-#c9nw1EZn029)oSmlXbJ3wDHa5R#HOgTS~<^KcfWsi9+fY{k)_agjW_+p4WoL)(^ zTL0?dPQ2Af{0`15@h``g5(u-Z0=Ae#v1NH0gc-PuI8UE1%aLF^YLzf|A|fa`^1;`ST0pXkr8kglCN{Zkg6hCZZWOshNj&B zREp(1W@oz~o>!Gr-Z(Jr`$pu-SgZQ6T*KuyTO0;{K-F&DKCB6pCqLYABn(HU-72Yb zseX)KLe#pvk06fJaH8CZy$K6h#>1le3vx^5u&|Yg z^pj2>hQ7ZZuGci%E5L~rf|1d*5%Xa?@lLjCGbHp&#KY(-kCOl7kA#VbyI7HqtW~od zG8;)-1R=VWTL{`&;GL_2efy^Nxx@Y_dX`xThQF5J{5ntCuZ3xG)!a9B6 zIe&~G@p!u!ji!jos)c(6@te(t8i5sL@S0(2|Hb2wuJBLCL7sY3oWxB>wm(^>ecLcM`ulm~}in*x?_osT8PXd;sUv1%K*uxxCJ# zwsNm1XF+G=wL`C5VLl%jVcOK1%f_e<4`m`*u;;pT-h*e8Yb0(rE7E6$b6oxu&}{k#dl6G~YVdMmh*-U{+AUku2}CnTsa} z%Q&ipjXMU_{+zAGz-EXc*1!PmAvBQ^hf82YMbCRk`t@>SA$((CEb3}FAj=ks@H2D>K zpYt6+ZYx=;Kf!dPyFC3YFOg#9E+_reJw9kGdY<<@{3AR*WZHfG4M-*|1qSIwuGHjC zQz7zJ+484}j`9a=xK#hk2{D&MRxFcR(dT5#5}gwaxzeWK${DBTyUd*()SM9H)+Ni% zzLIt5do-_P5Gb((t>9|=NbKpZUj+-b0Ero>+SGc&?D_dlrWCCZY-{~|O+{y@+bB;i zK(Fu6Z|4pi408vQAvKs=)Sc`T_UXcE^X7JUceNGzp6uz;MU(N-hC!D4J0aTF>NEh& z{VR1SRqbtS9%ux|;zYbHOIEg$*EVZBC8g4peRH9xcr?Iac-UG^9j1t#p+8eWlDjUB_q zonOverSXwV-do-ikA)1x-)dvchEB zfGc-L`D=yJ_WZ(rma!t}82iajS%&rJy6)}>+lu)0B#Oogamz-AvtzGrm&n-XK*XWIO; zVq)9=X2+aJcQ%d*BJTHP+g~$f(oe{HtI1Jp= zA_%NK90xYu4vBDcFAMI^{87Ue;#OfuIuixB^4~?YMe3ox)vQ$V-ZWUI6zUx}ZrPnK zzNLxu)+{$T)Ej#A29C6ed|R=^G>rCUA-Z90Yv_$=c{kYKXb@!&qgJf4F(aMcGx0k? zF^-5dD@}0fZjCRoG| z@-@tE9xHOS4#ZW{mO` z_S(=E@IHKg1b%HH&ARCsvavL36QZg!loW__e+HpB`tvo{8Y(ms2$*6x&>qBQamhHV z^L?`a(idT~V|v3&)2Q;kZcu=ORJw8Y&$;4j4vt4G2Z~ z^+yl)0EMDn2LhvD`w69qAW&tAzM;wxK{?U6e04N<5#nV8k#?mI;sz)&oS=5q4`%wa z<+@>bneWno{|y%b*`mei2Bw$ zOd2el0;U9wVFW>as2|Mr=gYmpfaRk4pn{n0cz{mSA1H4M+rNPIHTEO&*BffLu>vXG0X&9M1IWQtt(UX}91=Ael!EB8dK zXbC>yWX#AdPuD)XY5D}Jz9SW9m}vV1*My_Z=8-T%VBLo}J3zy#?4JKbrwJ#mZP~W8 zZFyCH>_oezwh6v4ytGqp)!k+WXYIOv5_yZi1HT$ENP-0y`~KtGIg7nxwI0K&9oz48 z@Xhcuz4+jzhYs=4*YT#VW7PiVMfhjc<%huCTo_Jam=3a~LHy?YDHb3jec{&IovGA) z-{>2gKeOyL+O*@po(#B^LN1PQ1iLO?CP-FMJLH3;ryjgb5xH|Qt-5yxF*z%pth5EI zyOoAM9=Y@Xrc`PBBZEDx(3))6_+hlINnxOMk}cCbyrR~udHnUFS+t@PXMGoARbyQfrMY92 z@UHt*3x~VPZGeWF>9pFo*3f~|9x~Ij1U0qWf1*=AVRJa0R~_|)F7q$lMhn% zDSBFxbxi?Fzu@2^K|uby#ruq!NNzLbN)@cieQ*Q^Morz&j zjSucnw;X-e8n`Y~s_8CYUOey-sK?<3tH~nkDaO{9rO#9UGNsU+FeCDei1{kP&5cLH zjfcN#Y_1&&FhSN0k4hWlh;921ntA`%{A0qGOlU%EU#IRo)7!9#>pIKU!QVfAMrlq? zqj&?UB({4P!xpU99C9@d2`s2H1klw<@<0ov@yJpqQc1zo)%Fu}i zFN5w5cuzMjh2#%1geAKUs_j+*m5KLXMj*mH}?ZK?2Wb zgR;PVhrGMNF5bX5Q?MRM5H+r$6sntm@5Xk#Q0t$fe5M;b<0+sYpMTxO`mat9v$ekW z8ta?k5XcYtaIh=dW&fJK55)Ye#nO#!N^NKw{x~9#wi1=K7T6to~=i=@Jg;1#w!&2Tk|+RU60Q6?q~x&znN3= z>dxW(iL>$8QCU{(e&YMwwNqRNU9g^D7`DLI;VkxKDcna3xMw@tm@JjNv`@sVv~zw> zAKhR4rnk=aqhrakS}(i7(IH&m>zX;f;pG3EWv(qlKb&bvwfP)4;?9WO^>uLd7ed|? zFWxK-g82V-F=8RB^$-{!AS(Ya4kwQPO+w5Vz#0>-;0v8o$+cozZEirr8Dof!lUZQX zZ#6Pe%1I{W@Lhn``%cAylSn!zrkuU$Bf8K#+{*;E1vJur^3_yBR zx9E`uMG);@0>D~Sx5$wKg%i3@_PBufF7;m$z;l%UuOl%EQuLRMaawU9>c9AaxhQ{; zBRPssvcF0cM(8hD<9(6-Vn=!ud+0AbfZM3IUq@1C38KRi!wTZm2NU<+Klyw}^2d~@ z(xpiN{uGcDVv$&A__F4BfPHaEG<+FzEPyD5gt#OozL+^9z(sr%GxL`@1wcle1~XIC zoRDG*Vn@`SyGKM*NAakrvPsd8KfaF8)N`$O14zhsXFqt}0s`D;+7#2SA`m z6(1C@jJ%Sf5-rY>PLYn4Mh3h`4M$NKZ*|s5pW0HuccxLP$`!|t`%@rBE@SFQo1+7u zBZ;Js$S9D-QD_#W&Dj7n6f@$g;%R6)vgY^zPQbA^3i+aFajG;Sz>|Vl9EEyOrZ`5L z2S7r>5Lr#t7(IURB`%#a5t`d)wvd%5CfC*5Ni0W73oF7#1{gONa%-d8mLrZ}?rU@I ztLmGivlln_)Kqmf)O6K0l+a4J1n!l@j`bMJh2wC3OP=sU^t=qE;}!=K%~ajiOP&P~g{>8C&Gp1oyfTU3%dG3j01TG&XA zS5bj9%kHSNuj<+A&IkO-U@-X~Bb!Ktq!^v{mtI$Y(v$l=x|XrJ%0RZDq)VsiVKkmm zC(2oZGx=0GUDbSL%>LT_2WFFBJ*&q=`|9w}S8>(OybQ5w&YEXWhspwB$E%B@3(>2# z#B8Alf+>1LjxzR8ph~eWhmTg2Lw`~3W|sECJatWHN61+jfI%*hF6YNm$m$`Ykb(*q zY2+rch11enqY0%3D2q|4<3>|i*T3zQAgwjmDufRkBaST8KjCChzH$-R7484k?(Qt0 z!eH285s_~bQ9w-o!Kh8{D1$J&RkI_5QlvKE9wE0OX~m8mJ#=xQ?7?V=n!t<%SdFQP zl@x{=D|8NJt(z#ZcQQeuF)M|!oEF;1m{SfJ>hdR#Q=?Dx32m4Bs@ty-)x8SM`>{Ym8uT6I;u1+*%K-(fWScJuwN9poycOcFTJ zqqY*`vig(S3rvi9!5jGSn$m$ic0B(QKh|os%w}O3tZgM2l2VV}R5MlO)1<2lDb!2d zqS1|L*lXPU;PO~Eim-Qwc7BP%ui{p&LuBnnqsXSQ>4$^d-{G zUdS|AI(+yYJA)`w-gkTi4o+$qd>+<#SYtmi>D(R5DYJ?xhsU^)wJbhZBC_*`9*K!T zj#1}_#MKy+%<9^I1fqA|@|+UpuI$;$BT2#WHnRWGhkBSyXvd9^B{$$?b_o)-fF#)P zI9_Z`U8w##Q!&OxS#bP!z?mPK5k9PJwzA4;9@G(-p%CfsFTBwzPnv7l*AgYmXJ1ZS zwQOBw%4K=)TAf}B-EcHq;3Q_zE-Ihk>YlfwOH7Zrrm5x!vz@;~5;apMDekT6X~vm` zl->kq`aT7d4$$^B!o;06Uw-YBo4~wusTL(HbZW;EuDvoMj7Hq+gEsU!s!h15mmUY#ixjb6(sC|%umhXY7;1my z<)BXFFk}|>tI7CQ0f@?@2_cl0eO5th&t|sFri%;|fPT}O2QuyJ22^A<2 zZ2nlbWq-%o;K-OvkR+M31V$$SI0WSFR5|g`mmtzsR_BZ1QvrQj4m!5Oli2Bu#EHo> zza`C%1+he?PRb)AL{&n|mNb=Rin-0}-8Vca+v>h6wGk&wuYXrUmEhXCqS8EY9tP@) zKvQK`v5zz9otq2HxC}H*Zg_@TwG>@{pCYi@Le3k?ap3Vrxt;S2y@X50NE92xOYD(4 zfRr`lfHk>Q`CimPPvXFu725EO$2-}H&4_4*nm2FdSvO8%9XEWCX0YE-C?i|XNldGn z?-*Qi=e4G8?`kx`6i{_ zoO_^(KriiHk7VN>@&xghkS@)qMPxLAKq*WlGft9I3DYj&*k!2u-re2Kf&1pC7|Kkv z^5We`%MnI0bytFi>yHYQHFek#+crZbgN0499lS8FB=S*^UWH3NH-3}d2XWqTY&(T4 zn?uajs~;QDh+7Tlo53q|cu}B((5g_uVy0@z*FX3py{Kuv#0BHemI$)d<*XdlFbNMy z4Cus-wf6Bu*??7*fnD&FHyuh$bF@-y!uzKaKdOQ&ocjC{ofH4pj?c<-*?kOEP!TA> zIB!~T`>tjwCZW97rXN{CQx&q~jV@XEC4y*(87_Wi9tGC7QYW!hOy)P(P1rA!LRUOu znB;cL4~khj_F!eoI$>}R+PNmIDigrd3|sdhC3%qW6>em7>0fTyb4qSuGh0L;U}(g_ z@ZurwvyHI+#A8~zH<7;KsdfJ`^6q@8(+}*MEV<%!z8&T5+AO)^%(#gotVKT`0 zpF0_rX+m`z!0?V4DeHM}uWb8H*yv_yCxiTLSrTwn{x0+S^jBKGbg*o=DD|URJc8R> zmC*8MdEuqgyvO|uBhdbt zZ}K=L`4Cs?Ek#Dj$v^nTv4sPBGH31PxOvq7$mf#T%I6#aNt?yZ&l*tS!%q@RGpzjs zHEi;XHTt&!3y;R-2l?8jafK%W%beG6S8DMd?DYX03)+h z4xQLX%E5<}*iQ^XlU+W8_t6qCeJpm+PMc{2?cUZ|)kf#-5ekc@VIEx6z?;)TDpApB z$7knlgJkCO!Mjps`zx$Gb^%!}qw!i$%9V-y{<=S>R+L%UBZBCG`=s5t?k&bW<4drF07?X-)--+%Sb4Sy}; z?2~sA0wPj(h_+~qYLWB#Iu&{aT?+Z;3ts;DI}DLjq2D?(9-0OOuPQh3F+5yGw5Ry9 zo<(rER|G>@8M0IIFXN$b9b9qi(2vp*n_5^&-Oqo>Xy@$Y1(<$fiJpzq8iu2UVBf35G7Y@EuOGCFXXG*ri&_>bd$>bu(~0CT!-9LfSI$wh z>(2LD@S}Y(Kg4cs>|2YV6L3M8-iiUw7rog9=R1IOhNp#P%ZpseC~_Y=f_eJBQp?0) zH68L~`6__mZpJntg5toU={$AU>QD4QnOAUfU8l2XZ-e(LmN|PpN?wy4&yvRNz2~)M zE#FT|`G}CzfC2A&d#82~(uvmW?s=>Gvkl}vm6 z?cWTP6xRxIOdfH$HiMfIO3#h%xUTNSJ#OdIX{l4`t<(0m(k%t$k<+8=q+o7RhHZYJ=3vI&56lTKkEyB z?g*Ad^(JJpBlqZWDlyvKURhS+Zt#diACEc{_Bo^&h_yEVO?w(;wAoMq8Cz0e{){O( zyq`DGNF|wlqL%Aa#cHm7$ihmg@3Ts3A7j%$(7+uPlkzI_-Yx81gp$YMc{;6$`aLwk zf>u<;xU;gbzSCUY+|yE2mQ5jNSTqW8uvOpO)KgYeWuif&p9{Yhc{dNuk(k=p ziPXkbCZMKpRB=FW;jA5oglyv@E+TUB)D};$hJutG-bk z*5E1nPeBlqDW1Fot6)pJm5oPb72+x|yZ&bO3Fm=~qhFNGvUAgqKU;Mfd)TYAORK1= z^ois`R)NQ>U`U-%A=h#`kWTe%{uFE)u|ZahHLiWOq$pU==;$;Cv|qwZ0=kuDlMfbp zwbwALY}8cLpg!W53$kym(Ptc4&-KbhI_j>j+eGJ0pBT%TZ7pV&SSuEzT+6g@l?>w% z9WF=eJ3iW&$xR)MmWlzJ59s+)vSQ^rekzMlaeW&)?=`S*>LqsaW+6A;1ip-X7G2_6^j^!F1+hnE8d)GF)h= z@pib4_j}}8%1#>`*Jek)V~Hl1K^0{YHzS?3bDb+)P0e(z5RpPA?@acD zV{ldJIW}Hvuh=m1%Q5ZyC_1z(#6i;P?G-y4ZWn=`fbP*B);x3nzZCjHwlcmNl{$l8 zSTD1jl$*B{1!C4uWXK|YkBh~MR5({ZE8mI+lo!1vhfUR#m|})XgU#d7l?p{49rdo^ zAtrpS2wKV=<_@o#q`9@2l4H|fF%q(_-@DkJaMEMK)V7$Jv3QPnqH*Gc>*9EI7wyhW z8vbysP{i9jwA8aUwbft64^O@2jGzOEbk^cPSm$dk3>N3u=U*P3a-G$OL`K=jh$#v9 zLs4x*I6~aX<1p8E6X~uA@qHw9$7-e+^ORNwNrl(b6j$*;PusMYj>>#ZqlVgWBe>cm zdMy>^WrDxuzdz6PW7g^0$Ghc!`8}O!lShYtC?bJGQNV-@+OZ$YMT3N1$f z2vSf+%2PB_0&KpzWSL^-EEFOX( z7=tfj+(&$t)|DI(6R9tIi%?m0^F^pnB73C zKts0tB1XWipoF#s@Dl{8(!wrZuMh(nTQbHKj~eWtFWfu1lWS*+?Yb(PfWJJL0XwV{ z_NWyBdAq@<+H)?D9$p@(?YcYJ<3f-gMvq#~ow}mMSa}hHwj~7NuPf5O;wl@0b)lP9 z-dDVT)o5IzA$vd;7BEY4E?bI=84xI^FAztRGm$ON*Lsri+VTMMf;&YGqF5^;LdQ4J zAs?k5>BJR&eivW$g}!JoUx&Ylf_$WUJPQ72_lWhM+RxN+8^}lZN2G6>21-Y5kdIy$ zx9Fyi)xo~pce!Hzr)YZ}-{vU2Ne1pG3K1uya4T>ruP!X$1TvlDe3=GocZ2Jz0^kGy zdNQwDzqY-qywEm&{Wsd;iwf|I+Lqey%7=P@czF|X-4Q#gkC;$MNJJ%}oZLMwp2YTU zd&d2zk?Kkf(m*mo_D3FCgEATeJ@)gk`cs08@O$CGmf^3#P9|VY;1*slF&HKM3*7Dp zNdmj@dI`ZK;kPio3Hz@hq{d(oU<6(u9vD5G6ecisU!gyN#yT@`wq%R>VtXX9=e6-n*#au-*UV`f+CQD zzP+&x*IrD1pZF$E0?8 zOv_lvPPGBd6YCYstjRj;l@%{8Z^FJm5MoFy7!i*IK`?fIzn>D11YR(DUld3YE(M)n z;>`%+4IhJ6GWMnbQH9e&E17r`0v+&oQM~DgwxDnOLGk?~NVnevY{> zpl&BYjKB?~Imo;zkYoQn-Ukfm2I&^En|8<#@^%Kq67p=~Z3Hx8Bl^Z{(vH<0yN~9~ zH-z1viWCu2g|~~!JLt^ioU)JSj6C!TJ%+CcL5p7tQ)}ie1cC~`48djZh66){qka>L z-2V;?#drK>IPHw-%rW!>NR7k-V>s$e;LSG_0nx^~jj%oHEZ__~6!Dc@--g+qaYh9p zglj?7nR;`92*OdJg>v>OgA>fbbig8fq3`YK`(_~tW?*k1CY}&Fm?~W9`v=!h8N_G! zzFLTq8Q2}jfoF)=9l!tB-)8~#>hH4xqxM^|zexd`@Pr7#MB#HVLJ9l#AuPsVrG8v? ze{|3Y(kDI`Bb)`MH+Fw2q|O-3(yzttj}2NuGJ^JJ8d`%ingb#C^RT~Z0kiRX@!J#j z^@5!&z}&zs{9b6VVmJ?klR20f*oEH<3pNbDh3?JYhYcn*2a^LM@B_brRl-T3cZWfT z{YtEFJV09fKm@Q&cs^uc+Wu*9z7-e-h>ITx5B?fL0U4OO-v`|{3cBofVtu0l=^^zY zzo87>LiLS-Ui(Q|-^f8yNI^(%@I(1fL8GA4ek0a5YLGDA2Q5eoDG2$ECA<&vBW?dS z_;UvI+%L@fR>Zzqld*mc<;hVE<%jnKb;^1L{lt-jm^0=q3PUmqat5L! zC43_paVB?0A1VqNV->{lCK@^np=A|B_r@4X4k=^pMh3MaIl&61?q7#^8GB0sO~bvQ z@<~317D&TM5Ic}_XetENq#dR`b)OsP z87>fvYSE6_9<%QVBnj7os5AG*2HA$ML6DAu_WPw+l-0Z4POWu>>fS`VK@ci2ROb z=TI9qRJxaERHxXba<{zfr|fNa(L?8Id*P-Gw!H|Td*gZx#OmOB96GZlk?qV$NUDWZ zJ}D&n&5mjTIq9Dwrt)1GMU3y;v2zLxozx$qXjiI96FR8^qWDI%W4IIvI;ldUI9IGm zHabL=cnO{VT!|(Z=*EhOLS3OI8|Y{Yi6UGvChzEIi*kZp5hkPP+C=!^k6XXi+bG9a zDQYT?p{{-@TZP+@$DVXv;(XW^Y?Ie2H~+c9rYtGnM7r`%nx+U8ZNncU{m)u;scgD? zF;X@j^zd#eu8+7AaHALOdJdrxb2R{*D!_{;6gDvhlqqdI^2_PxYq=V*L>ivZ8+Kll z=4Mma9w13ATR)%Rv>=yP6t*tJu|eAKR!AhMX5oHv+L)0$q-kuvCO!?|$adkHJqay8 zKMl6O-u1zDZlj{;dvuYiVi5~5J_HQQ>}_ZU^o8~AITZ9JIC2G$x-ELeOBi_xfuZ%v zZ%b=RZx0p!&9+wPP6ID!MSk-azU73JML(P3F%KhA-R%63w zJx~_KHyHhG=#B>x^~=9L7IYs!CaGix!}3H~MyltHGW0UEGK}!(h*Y)b%dQ+!J(AfM z0-6#%O1rn-nepju56(oEcWK2WuAyb83!lhsNmO3pxa!ISf=JC@&wpY)w?HN4}vAvJ_GbYPBmBw}t@F{V9tq z2)F2E6w_-9@h0}YuI@r&rtm6-jTAm zvi+n?huXFyvJN-tKBsL*q-r}8xaUE}g712d)ZvrpdHbj5p|fV_uZ$KKu-Gn2V+{eM z<(OG}ky!JGK?rq$qBG$DU1%Ph?Q9Nr7~Ql)Y_H`4maycHeqjlG=GC*p9EuD@H!-O0%Z<4>rAh z?a^D{%Y7=oBj1GWmHx?_gJRZiA0DeU_jSt-+;4qvbxemZqwjc-_!=2f%zgBZ_jl{z z2lgt^s0_S(8Fshy-;Y4E{?`#!uc#~|LQo(8BGLEEt>j8!YBoT&M57-XG#cu^WC{nu zhw|rKic^?^P?Ma&J@9J8CT)!lf;liE*6!vvZyHugF4HR1dLgAsrXOUcdBv2_5Qcen zFSEX~T6rQo`^%IN-r0m6htIvRE)g>-A7L%d2qnmycn5A5K!Ozd@oU+0W7>M!JyNno z<4rn}l&c;*6Z>5#en}~(c_L5hqeOz$cEva;=`wQ~v%5efZ~51z3NLv=rRxPugFceyK?Ys~0Vxy3>t}1E@gv_E}9)3s~sp)Dh$>1G$tQw-K zcISQX%_8VI8TYYRF?zQcwJv4hzWz4ThMmaX=a&Dw2*C#qDoN8=ZZsY`VLV=VlE8KyaGYUavb z^&b|)7C?L1zM_0|*s6$kXAeV(4>XD>ok@HUd5e59zZT)APjd5q-#Gn?{gZkwE%nwE zVta-l96TQp5s~rZ4L0b;h#hBOD^AA9QT`voR%j?Jah|N(Iie{9WxJ{%cNMJeh!O1F z8Y*3{tfSs}w)xh`5t&_^SK$_N=$Yq|agAyfIf;=N;o%6A)KL3ffb39eTKUhxu^4hb zDW<)v;zzRLRo*^MzIEH@ChfsI!n1YVv;9?E4hQ(EBo>7;f!ix;d#DqOB8^o&?ZMp> zxeW3tr}4jXI)$1gG|l+@Lq$j*9o!X1i(aR#Q)>rRjCr4fLMN)E`0q1@z3f9G`F(aM z{EBxm5wRw35LHSxjl7fDMM#hT)}d!uTk^0lx$Zpj%9$ue#IGR`qRWY;QP&DR(QFM> z?0zvxEu%=z&~ny2-+MTMB1A*^NDGzTA0;9Z{#jOK7Gc%3B_{X}O%vIaa?ca1&y?h2 zN{gIa2s*NBo~CFlddkLo*^WjhE>bGcwy`g|PD}`0x$`E@l#sIHMdUL3#PiiE>6l{o zRvp~U9z^7-wx@-0JQGe4Edo{T%KQcjdx-yPY~poISr8PH>Y7WK`{p-JZ`#37sGcXr zq%AGk30FutP>VbjDCxnBkkjpx!R>jWFv1DrEf{$$6fef#&G5Bs)8G9n>Gw-~XY1Xs zFIY4w^rV}iQn@V7q_TxQhyBM{HZRBgZZ6T(CLz}n;<9wSeWQlba4}zbzL5@m=Lz@<%s+Ghg%DG z^Sz9iuV%qsg#{_*Eu-j?4InL)1=f|uGKZpiQi!IsfU?b4GV!nU=AVS9Tmv^w{X;P#3~H7#_bG!W?38N{SNk@NH4A5ZU$pq02M)d`?XsdylB&|{XqGZcGYTRrq8lQo zHjcDYxQ8XF*PdsDs{bg-_Qz+E>L)BKduovm3Sfmtns@x_ngt(^a*`S-1!mX#i26GG zoM>BI&v6TM;Y9IYD>O6>R*}o6kUG)}_tGy;ECf|+TRnXS$U28}X8CtXb9`)j=Z`t{ z3|6&0I(&@{mdS+`aNjmpy@Srigb!<+(RTqvmc$8dbT52ue*^w2Q2#|wZEF`7Fl>MS zUhturK_TiCc23*t`Sr}*-q-BF!{S4|%P}6GNp_WRU=nEDDL(!Wzcv55rx(Vm3e44r z(?a03x(MYn+>%!RlLr{P!u2SJYB7^4qG&P|b;*DDz*BfM{;W2S7Evqp^h4_Lhm_u< ze>QR*l-L|pMOk^x`wtF$CCP_N2M2HB2kC`-cpbbqmrpMH#Ki@kTSbDko8U^&on zPb=GJsLL;Z7z;||%ZSM@TVBr1ny$Z;OHQQs5*6krZQ19H*bNAktQE$g28j-y?#4m} zmHH*K0eL1Mm1K1EL>XMaKV^30w#JT5y9cz2MGLMbiTQtoxJ9N>%(+Md#&o(E3B=R6 zfBdZ)h$94~&Hm3fJ&#QOdghD7{L-lolv<&I%BhDCj|KgJywED8X3vf>vd*`tTA{gt z6PJ|(&+um1+ohA4dxzdW5TF@JFg_^L_MmV*L{jc$~cS!r`!<2}`$mZ*|U<}r3 z8afTcx%b(u6US}t>p)H8lNHsLl4si7%o)$OH{pYe;$Ux%WJ2mLpGem}gY z8)kxfIp^lIz@oVxe&$HGC^ofqQ|M@0%h$_g3#M&>y{;eJ8m#Tu$Gow=5X4+U~5lZ+io0 zUW-<`eOR3sJ`!bnUQam_K4`L**50gin6_|}&$Vtuf{1TF40qaB`cB63oi1+$fK5yZ zd>{2oUi}x6?*hil&9}iSOTExv&0iGl9q{J^G3$qO?t5GGsdgy#n2Crf&fKsefCVS3SmZ>oD1Y7c`-WkZx${{eE#ES z|BL2J4V=Q3WkBftSz2IdsIaZ|^TGg(W~!#~Qq$sj5wyo){~i<&m6pHnzt3ciZ57$x zPwQ7$ZH(tWpU^nrSL@H&2hpm3wB*6G0zDiWJdQJ7rC^Q}#oJBh#>y6)7oVN}+s)-T z;iWF_w-)(VeCGy@r6yp16Re=tDTnc4S}**N(XG2L+nrUFF77}GuG4G`yvLzt5L<{a z=Y{`Q;7Q|6QLsxHqOr0nv;B)x;biyJsKX*Evu zxbgY_LufxwU9)^xAs|kY|Ia~Sj{heJJfjb9tS^C|7jS!>YG21GlU=27%cnt;jIQkSzFxg`-XKEfiC;|dPwR>esoGdbyW|H9ov%$S$9(yHq zw<Rz&FJ^uNf{HZ{j2M_*$ToI$K$d_rPreVPt-JENlIkvF%f3o2|wLT*fDVQ^;=z89pTw!*@FkA$3G7Gcfp};lU*!MuPh#`jJAxn#WjZq4}p~( zkrILPOWX$!+?Dqv#|MVrUYKuO1AcHH;XtQ~2LbvWxsum%ci{%XUm%g+s4C|s^gl(7 z5-|K@WfRoSpVfVT%POg!|DgY=P-0d7z?hm>w0KViMhv`1B~j7Gw5xKev9mKouZ><^ zYaSVVR&)EBt+GKWsFHxEva!X%y1vWN-q_<;p8WQ=QVQ!2)4DE2)#e}* zlfuHW!+vQg=%Q6yEC5+svGO_6#kj)0+|E9llSis@Gs`xO#Wto{eU|nR#djDi?&<~= zFivS%V!gYrYt&I_A)zK_Hxu3JT&2 zMlI2|of_j2BX!i?na#tZcqP}V<-~Hn*T!l^^*1i_lDNXA@)J zIEFLC`QMDP)KgVt&EvwwSE!`*xFLK}EGz0>om7knN$kD{#23k9rJ(M>5Rh#$O;k7D`Xdh`!%V^sm@knKiTr1I;Fn& zL`E2LwVnO(tZAIKrE@P|aiR7_H+zFy^kbm3Gt+Mjny6(h(Wc|7WV6F&9zjz`f|BMV zX2MT}?-m-(9c7eRyz+lI<18w`F#W{M{gguDUzM-or zo?R)Ol(sUA0VCH)71v;G!CR}$Bsw*-INvC`dw^z;oVF4NXq8q|gHASO=i{ToVx#_J zMt}jp-cMDT(2kfO12kY~cJb@p9#l!O(){J(<|GG5nW@4y} z`-{wyqQK`l@ry5V4;L++x3&0$ArTgur4gLsR4?oRPNO_B76>8ka}m z$s9T~RMUVn?2Dby=TO9kwg{?@?Du3E=A`+l#@MYptG?A}T)ZsbIz7#$ISVnN|5P}9 zqM&T9*Q%=SbVdgdL(i1=!WvhY0m2ERz|&@m;QDtH4XR}MUktIuds(k;N*7V8N<7^t zOe~J8sVAGC4+SLY{8CptT5#57mr_upQmym;r?zYDQ_WSV{aw|Aa;+lTiWNISekS_s zJT5JKie7k!m$D@W0bV0zj`-ggIkF0HwfA9OnyS{aiTUcN=3<8+{>)($nVUl-KC5L3!plLy8i$y&+JCF8T-6aCx)cOMnW_iQ zc5-6$e|5aS{BL3D1XnFrt4(}FFOX?WA|9t?M28*`rb%Xi*;EP*DKjS5T|QESN~w=_ z67hC2$L=f+#WBB<$d$zsa{13q z6UJRNkNJ-y7;U=4txWS4+6C#OrWhktXS;VL+`F5TRszr2fUB5+SuWm1r zNpwI>C5xNB`6QHUHF`E?Ig+@zUTTc1yI@?xRZWa&>sc^vPcM8>Zu8AjQtHNZR9*KH z7e=?*34X8~NKLPM+|thm9-wo0 zmHDjz`4vf{$2JfFsA-D)y^w^kLu~wf|H`zfP=_jVT#Niyt70Vv6*i-9t<c#P14 zvc+?5-Cw(?4g{tC_?eW67rIToUIE>#XI@*>TQzEIGo=J_hFyhKr&$?I4t&U%<^rQn z2bu*DvF5}U9Z*o|m{Qvla?VM^wUQ?8?-Z7$5_2&trU+d^SAD4j3Wc+>42kU$D?n_4 z;nBiO3pYq46OvtC#pNFom0l#ng^y2;vvQndxxQA}rxtwh8&%1vUyah9Nxs9md2Nfp zJT$bV+1wAPJ-#Lzx68jY?)3RDv)Q=fQDn_)G98I0& zPE__j9g#t15wugadjE^AcL1*Bi~fCM+qP}n=ESybJDFf&+n!`5woZ(RZ96%!lbhfF z-dpuv)q7Q|dv~qfU8l}Dd++Mi{aN4jJmr1s;VuJs!SZBE@sI_)d+Fx#^OfzsLc8#G zlRPqNN+;MqDNnj0#byheX6Gi~fE&V`=c!*t5$)EivVY=!?P2B%6h=>5 zTD|Ml0r9G9a>xlLiCwhVq!yvRaEZ<0UDx&sD`ND5LW>5#iY?PLzpBg=OkubQ;9ME6 znH|ubWjikQJ?b5Zh^)r+{;VU|>^^Uawn++3JF@!}ma!jj#p;z)_~?`mPMPyp=UwJF z2qk2m9m&PnMJ*>ZC**L`HV{67ED<_-QnwKH7{duscM$dgjA9x$iXRo>?H~mh5)t1alYCFg6 z9h1PC2c>jU>U7tXEHfnOdt`+&8-2`o>QnH`>*7ML)GAPk75SRiGSIMtCyUo*Hee0j zzITCe{6Ml(fCq}Qtg4?_%@1FdKx2e!2#lPw+3@iqKXF*uU@~Cb3i~Z-PzSio`QvYC z{i$+NG}*1sT12L6%E=kQCE16I1rMZhFAn&^Lsy9OmoKkw{~t`H2`^UXK=*j_0{P8| zjR4Zf<9YYp3$1PthZI9l=g6a_k=<8&lhmr&6!t$b?_obRn>4SLjr zEn`?-a!+dZGt~OqvKNvm?93wj%Ify~R(D-%kl7mvO@oN5!zuaAl4}qzZKoItH{t_= zr^AK*D(4KO2j2SII=5%>h_kZtweg!VwjpH*D(5Ct3j%_tW3D>#TKPY$4X`|K?%5ow zHZR56Mk{ObC3*i=v!kXO!=nXc4=;f6Ako^wdUH!#*p?bCljJp%Mh^G=BeHGBQ90Ev zQ(fdNQMZmKo!ISWb*JBY%2m2TC?tCKia?W;FC94H($XG)TXBj##3%C3>bk=N{6JZm zQJ-tZ!=9R$ufIJY?BiWT!ovW8%GC;>Q~Q&5E^GLdw7J?-M$-fFz8TrmzVc#og_}cW zi*h1F#*rx0d=x@fe>T6_;3JO^BaqTQkpZW))k)sn?Ctftd<(<_0x2c)ej(;JbO(TAaVISR_+AtG;-EcT3WC7|b$y8izX-@%?-*O#e+00pg7qq;Gye^iJ zfjCL2R&waYSGW*(ZQ%k-79ak?rq}nv;P|$*&+}vpWleN(eWufkL1n<+RF`!OA6u>w zSCh<Cb$GH)u`{pi6O6wwbM#YvxI1CABI7}-o24gq5gGyqc&hYa9eL@0_n)lgh*+l7WeR2yDTv-E87oZHHM{`Xy0D- z7GIBK`*Jl)!~oOz2Y6wBDgf0eH2ulu$9EUd5}S}EBP{!GehhYkwkJa{ih^AhsV1Bs zce{k$8p~r)p*)UR_PlBGQB+|OpNq_?&y3uH&z))+Aqqi{dIP_~j{C3HFBkO#ocp(fnnWBD%`;g9^#u}1{xoiIe?FkOFgLEv~1#~CI=w| zEm7IC0|q@^{Ffx!nX>0FyV+<#^cN_Wy(LqNJ2VNGntk_uZllPKj>@DfrIu!LDUr2b zBU>zS_AU2djeItT-|D7+d%Xnp`)7OVx=R}65$nw1?9v0<-rmgN&DVsq^!!vPpKytP zsGf>Ml~t)LUCy-J;qc?5Y8mR5?^-UO{Ar}0XQ$Pwie_dmV|g(CTk?-6Z-2gViZ=Rc z_s7X)vTximeyP$i?Ll(gSgP7kqZD7uVP`s>LmoNJ`?@sp6m3~Q5?FmXN+BSH8hL%g z^Q?4pr=P`UYo-V5)a_3zF|DVMm(z&qgoz@~uj7CNL)t*}+Ev&m*R(0Y-k6aUk+Ln9>Ta6pQri2gB!=+0}K52H@QvE)mF1M^RmXoWC))c6!_k^P*5l z^#B2MdiQPf1U+m2qW#J+_eE`poj`G%7J~c}ZgeT;Sa_=^gWtk@#>St3;XB z$+^a>FQd8t@^k*Szo2=K$tR<^zWqCkd5=vGCfk?eC%Ji#Lk~LJHs#XOWD@CJK(${6 z-)ohN+30)4i|FY4%saNn{dJ;Cj*H*u`)C`Td7ynD8rv0DAR!wOI}tLj^87OKFX4zu zWk%EnfppXcg$c3TvMq{xy{*JU@Qj<{o8!d8Rxr|i4e;X6&1dOR?{#l%5BI1bJmT=$ z!k75%@nCID%TbJ(X*eD76RJcn44g>da!V5c(W>cNs8A;k5?zoBU;c7ZnkzP!i}DvMwOWc$ueMN_ z`^!)YYtNWkj^2Y5L$ph)ue+fAgUcFf_<_Y{HKyh>noBO3MQ}!)TiN4idrLl3p5|rZR^WU#aoHD`lGVN7eW?eQo z;F2byg9TQ`KoJzXl(=mWA~5tZ;2L#ooRYiY zbwoNcrS-r$K2qV0D~dH1x!HBM?`cOEW1IuKrq?xUZkoX5Z@X?CtE~pF%ARH+7gL7d z<+>sauYZ&sL?<|Hgp-ng=e2D9->jchEWC z5qF$ypY{5vZJyWrwr7D}A-xs5DIv(%rm1Zo6l!9X(EeeBdSCfAA&Z7uYis;x__X78wNT z-x?W&=${Z71pcmv_=WUrh`0^y-y2B`5~u<|1{JQ|l@2Ce1e*0F*gZe>DO*3w?o@ER za{$@#0HsIuF9X0ANTA+-$ZyT=Q}FgOP&h<*1{l@%H3#es5uO8%^c7e?t0x_!B0YKsBO>PX zrAK!62_e3Pfa4*7Sy}U-^OWwQ_K|Z6z-*M`L z=vVHN?ZD#Y!|2!U%J!vj3P5^SM^=C;F9Q*F&=98~m=?boUN*!G@aZKW!A?6~KD2-l z;0;vE+8Y!ohIozKB?E{J$*}gO1%l!Up*)iyGJ^|g159=f@#-Mz=A0qgbOD@w^c)0` zb&EjKK32qK&}F+e&^A?o5s2fQGrMzaq+W=Y?X${`2A(0Je`X{y^k;G8_fKPi*a}Kq zwClOUiFXBJShK6N7rbxy5*n`u<(Ul82;p5E(Fn}H zDv}wzM<1XCVpO$T6C6~!TN6@03rq-UwR_gx`TlG8cFsBd!GX%0->mpF$Gh7OAzlxx zcSWQVRF5Q}6>PhFcRl2K2AJ2^I|DT6>sqD+*flk3eHM`rO+cmpy!Pm<` z@IGYQ|7c&%cNky^ULeA=3*t8;3X3QV`=0tAJuU^91{1E>Jq|IN0TKs)RqhId_Ezp@ z1RE^@3qrn%cYDEli@#~|@2U1p{#rjf^?lDW#+_cfXW~95yJx~3FV1%&;2Yj2^&g=x z^`0-4k}vq@ZM;vIXEVegu=lDkMABP?gh)hVbpX~MEr5`5ZzOo%cLFzvl`Rj1fEa*0 zMB2ui1BioY1)8wv%=NvrxP^?^cndh^N8W|NbLhk9m+r#$p>ygZ2*~~i`&xU`0XYzr zq4SG&(RQ-%m>~1ZcG-4Z5vQT@OLp7)?l=U9y@e6AK$vHMVmlw4T`=B%BQrpl7lELC z(6-McI~I6CI6Sqxhka>ybzt$|O3AL24Nw{;upGd!LnnB$T& zymQSr?M+<0tI=1(>5l{4#rq@!W^lY)>~J9xgKpIAa`qA88NzQ=?RxZ`b9RBY$pfUp zh|6{z1!nb{-V%O?8ZI#OXFlxU(RIs`=-}5lp&jK-u0~xWs6e{@Ic#6&$!?>lpLIeg z6p|SM?GwGQc9McWs~3L`$6iK#fsBy!SyBoK+QQc-6e1VPw`vE#joHtji8)7eqqj*+ zz=X*giH;r2xeVW+eAUnp??gZu0glhXhhaOJ@P;)>_ka>uFZibtk7Xz?9zWlQ4P)M? z0;q0V=b|r^NpGc5UiP~&UP}M-%tsT*V6EbWtl+h0kOf&8{k(vkbHN(99~-7^IT;b{ zAgR-NfgEbrjAtGxz~1RY>NqT*8pfH|`NSMhW=wt8Q43@W*yh39_`!!r87o(tk|0-_ zVn5MOWSp1%-l=xrUg16LXfuxIh_5Mb1c!(%3K)7*0XPNz!^`Kbjr_#GBLYJ-`}U*= zSs_m2X#zyx5PK02*B^@_w_n~l2E7H=d7y(|3+(ygj?0-szXbOEbA%7RABc@Z4kO!- zrQQ>TNFLPNWqL_zB_!uqHpE5Nvi~T^}JqGG`sfVX~ z-*xd1{*34maGFJ8b&V#j*7m`PE7498aEf<|!U;&jX{IpFxC8Ur0$~+jA!b4cD_HgC zlr>m@BCJNT@>T)FL!!u*E4*EjKpb9pCv-RG`*g7M!@9D~wt!iTyqWy`0Q zxt95J9aOHVg>S!YH74sGg(J>xv!ukjbm-4+6vqnBaco6v(3o1MQ(7cA%uH?2e($Dh zdRcx^MIHn_;h&Pax*s)}b>g5?ynn~w7By;kQW2B;0bZ&SFU$?1!SQ4@xLIJ**())L z4fegx?Ohcpxmf(eCT$cu$cC3lYFA0kj2$F!`k5yXQx+Le997 z94kzow9xNJSZdJkAf{x_AYzGc?T)~;NWLL~%gTmcp*eroRV)r5!ow00V0cK9c&?Zy_)UzwxhIGLFT`A_qg>5w~A|k6eWA#+mEl)J+St zHLT2gE`1Mk_b{#-1-!K@P6ueVVGA{ek^#msbTnn+TBUx@)FL$>=Z($4ON8R z!fyZXWna8+2+T+g^@bdV4Zq!Mfo@7Pd+(SujWp_*sq(Ea6RRGQ+%$)cKUcF!{WYUU zo8%;mIAbvx)ADG_VoKHYeOHwvB`*}%^X(59Sf=F|Tj@1;Ql)j?h1XA?!2M`37jy0B z_{Q}N+r$;L!Kks-A_>!uQ>qV4dLY3qf9_ERuCITdbB;7_WB&{b?>jd3NBii32{a-b z)|TIW0+)#PAo1^3U>JHJ(XaU(mbN|e(^W0+Lnu$wAT)=%OkAnWMq z@4y``#LbyJomctixuaCSq>V1>5LQGm#Hp)sN_2?SVgH4PEV7i<1;Dgyr$xYJoyDq#8KDJ5XR_3Z18*3}?O3V2j`M zKV(eLz|lMqN7myY$<93-n-}tIUNxy1Gs= z6JGZE?Kj1uIC&Hzj9mcX<%Z8SOH!Bq#}4QYFlfGSy=kRhS! z%bf1(cDnsYXA+`IIq6c5W*HQz5jqha$Zm{0vj`eM`}a-Hr?auf3Tg@ggt{=<3A|i^ zJ=Jla-G>|VoqRHhmP=?F(jrxX{K(oZjxZb5WQ_d#&VqliOGkj?xD(th55{MCL<>K< zg4GgB&>fkbV)CzlFTz`(*M6W-j5akZ#teb^p`NE{=CsWY9jj@y78S&G9ygF@3Oj|j zvV1QE$5cAD&`Tul5h=$1nu>L{Q%7OggR0JA%d9Cbv42k2-LFivJ z+xH?fHxV@yP<;+Nha9moxj%W+vId?wFWpVcZk91I-hZ+-?Qk(Kk^bb)%VdsDd8Tb+ z&vZCzy`v@+JzfTehp10iI)o;#b1KhxNEE?fqh@Y*3(GOq=Rte9_j2o>%K9e^poGvD z4QkLTKp?cj?=9Myi{0b}EH9tJ!6x5eLS5aGANp~9IEtn9bG7X%;T-Kc&Gv~&FV4~r zLI%g8q--wlhZ>h|wSCi%RqLuI)K4b!);EdKf7F4VZ#->;p^yS~-5UXxKa>*#<%Uhv z?3EgR`N1BzEM=HkVPfSmgO!*F*I0v3UBl$o4ix7V4}4Qf#27-?;$+KjKWQF?suf97 zCdbTim=ybc#{p$k{~f8j2pMD+kinZBnkzl+RK&QyU_9Kwr7#1OxT(vRQaN+2?N;Qt zsDIy4lgSiD^S^JSgI>R7Ly1;_W|Yq;QD&5{At5$EEp5qh0@Bae*00o8u6SWRpNQ=A z0)Nm=yxoRRXD|=H!3~)kB~d+L&~j&#uK+w_8s1YE(wURenMo&VzCUcMduA5B)QGMj z%QDNNrH*^$_%LevgtRbdO(zQ1>AgU%ltz5 z3r9RpnB1I^es+2J1=<`xyt=39sLur+^^vC=K;Rdu_KVs>*CoIx@PIj;*EWP6Bp`qc z;MG*FTdu~aUX?ypWbJHIou|sC!+9-)(z1c|D7CK6zM{UbpMOhKqxoJH;KAkZ5kLBr zM_vB*Zy6)I=zpxA)mBCJ#a2qrh*$LNc|3Y5+tvt>ht^ElIO->pKB$L%mhsoj5$ zmf?7DK&*9Xz38EtY~Cwx^v0n6*NDCwk+7Z5}T_ zkI2@Q2p`q$xn9zzBOfzPttzw+2%vva5N)RbFVtt=a4$i*^lZ|8H;r@Uf3uuy$?+bZ z>U)F?r>1&y)TB0v!-+?#zU5Owsa}IS%lgdWh9|Avr`uP)5}||a5q(xzLeX3PkhJ={a?`c`{<(@*KQM?6UpfC=^0989@uxH7MZo80aYAuXTAA9t2WK5pfH z-~si&_hILhw^j?Fv!PebFeg~k>sN4Ve13Wh6{SZ7UaSw*sh&T<7YLKEec+lF3#(6P z49QKKR#9i9ua>lAdc`Wx{hemy3{2V5;qjX0UOT0Je`L~)>^^b$t_e)^WAx*8$CqNM zPZQOl;N^v8OB&xgu*#fhX~-4a0d~u%&mPe4{E=+jMbMR^H6SmMhVuMlKjqK%)igS3 zP{`;bc8pk163vq`iv0T!S)3haoyVu_+Bt&T7*1ET=D;v8rEA>(*Z;PzJgMo8DCa)y z#IhLh;fcsesXh^k0;}cypyjIDjX|9&5s#m!=snLqI;32CH~KDpN-l+V6;r~}!u0C8 zzkYmc*Xmw6cn$zqKdcZ5rqV3a2&b?M>4~RE2&SBK2>;>S+>MXT8e%*XtSg;Dx9{`C zwADqRo0*pPD*08?YtW_AVak=k>Bp?N7>p}5S5mP12n>kVYX5S|h_Okawh8+%vo>-# zKFZ!4o0`yXU)_chOhCc?-Ov-Ti; z_d$L4VSV?B{y$eTe+WNXUFLUxSQCW;9H$-YhUc9qhbQ@h@BN5|C2j0dVzo*DzK#7? zf3}!~?4s&=@E-)%H~+P)J^nr>xi z#>l=!?=ojq+)90ysd8RMZ5{I9Lyt8vB`7LriYchv) z%PzKsh7e$grsjpJ=Fr)LgCdPw%~&kbkAe{R3P`GR{T?Sl&)gQw5C{kbNxyIJHH9MXTYOhmIxa2uyP z^)pakiZ}Yd1evDCfA{@fXQ&upsOV>?05Gf@r?Wp5>BK)1XC9)t{dPzv-r1rU`@uCq zDmwS6g-_$sNh!_g&g~Q~JWQ7Ig-f`U z<{bgntc_T3!_0Gyel0_Ss@~d8d-?U_qxO73U-(q6UXeR>R*N^_Q0M)!%;~N9wBc5O zU`TznnCjO$`V%bJavy&J|{#xpmzi>j#5cLd^&pP+?n0VOyYKTd-kUkm8?e>lt(!*I?=6UZ97K9S(zP zFOOKInUj_c1nh@8eqVdX>qowN{dW$KR*j)kEum&*q3EgU-=UU$JL%2GYhSm@tq_fm zaH>CuoY2ooAMI3VqS=-ytD1~@OZtazEAL#)F}~c*u_eyN-_whF9NUpts`6;}A97UF z&r0*wgydPctg46*2FBr_dTW|P=A-X}F^fbCTf-^*;B_tbe~OYP{!16=S7pox7uV={ zN12rHf>^+$_k3N#T%h}0+dzo+{Vm%s;$7+LJ&*tP4nWrTLDqlo&2~!yb#gs-@2;N* zp!o>KlyI&+#af!Zm?3|0B{VGJHYDi7Y3Bh3T)A5_)3Q897%-4L>~5Lffkf{>p?6@& zD6)U$B>@JFBHSc{5^rGAlp22gg3eOi78$OU=lZQdbS<`u`pE9vo4woH9@;oJ3QW)} zr8UYIr_l@w`Axp2CkitjRKQxjY&o51g`8-6Ds}XpLhUmq|oGe+1Fk{G3BS z4cpE!#5Jt%5h|#aZ!CU;rlv1UolDcjgK=@=4YWnAbI-h7$ZWgXwBaiF^|&VGy%9K9 zX-wX<8XNU3`6RTKa9gGgZ^VYE%4CR zsVBEWG)3-q5;j{YwsU>fy?{VOBm3h_1B5`7c8LEnoLi1cKq$jHu~8xa2}zgkTLx3_ z#+Jqqd`L^=rg9XS2yAE(dBf{>8?I_huYEnj#OkUcTL}N#q2AklI9RU{fy$SbY*AuR z;iIqG+&%%u?$@u|%rKEi-g{ydd2k2}a1am}kUlq2)dw?(`vC+H5WDZ%W%wW$Ny3N)`iw4*Fedq6qFFWMu6M!fwqd?pvAiI#Un9h5m5k( zVPyK#XDh=3iR^dX{j}xB{dl#C`9Fu2TTD3?jT1wo)Efcs{C8_#(_K$oZ(Kg__54?$ z!F-Mm)ZV+|`2GjsXwNgC!~klD0yKXqAa6f5gb|v*B#^V8Tj?3A$8F#V2;QFnA&mO2 z0EF+ahv-FpR{}!!7eEA|zW?e21(jA2GbUp}*M_Nu-~!_h3G0(pk=r5Djx^Q@J%q7D zVNhmCF~;hLgK!LG3&n)hB%`6OB&npxRAh-Vwg_#9xPz&NsfIm5uiZP)Jk)G-safYi zhEAIbv99szw60*rxN*RKkRl@u3gC!aIoS`sbNizpPL?lscjHb?JOM)$3@&_72-W$$ zENKP}ZlA_R`tSba#)#%>jw%*)Dm9@u;=#Lufm(N&lsZ!#66JjqiIkBZ#r}P5ZF?J0 z{P5W#6{N?`#nTZ9&aI9X2Nh8CN0{KIS@Mr41igtolI2($;-%h;SatOWFAbo2xQ@%I zrWe$sHL7b$s68FrW+5_|xYL?WJ{VHCd}w=Z4fSRT+TUzS=20I>^G7z#M-JH55sSw3 zzHtwmz!>~1UfN1mQ6h0Y+G@HCR~YAmkGPpl-)#zntVv;aKmJW?tBL>bZ&5LVcsf0v z%JSNXE(a3@2fL=RW4qcXE_*?#(3d+0X~tG5O7!Mb>eOtg(#)1qU_^)Y9v@hewVt25 z9y7Y{z!(7ow>c#1ZY+u{rE3h{TDyN@CjKN$2~2Sh3IOI0Is`3Dn3 z0&Q;eeN$glXsT(vJc3Mov~I9!*q<&%jO;6n6y*M12=bOtXoCK=DatVi6A?%E!I@$) zB4n#Z`0HlNpV|(lGC%jrcvZAoX`#zZ$N48?S*u>?h`J*Y-%++1hX}=dxEK(3)M1spRm6Lc76&gc^vmrhGHG*y<#7MQb5)?0IW=oNV1!cGX z$5H!d90F_(*))rz5neMd$sl`}_qi=nB9049p1D$M<`sH`HZwFPQIN4#U}pWV*yy#_ zq$U#B_0(vWbB*2Sy4~;<{`#mZ%sX3W-pUaeWQt^)2NH`{5AO^Wue*^E4_(oEDZm1T zJn%)Ky+gls^~~{CGy;|8rjultTo>l91ot3>5H2cK6#M30>#xb08GN-=JVP-w0C8nG6}ETN~Xya`C43 zhm#t&`&YMCDe9cpIGl>29PkUoQeP>Bi)N?(bx~G-26xOZFe^q{sbNs#M19UE{0yu=DIA>@NOk`CX&K5BWUhX@c_6 zmQEFR<9K;>(m3%B`<_(QvuEHr4o%(wD#U*jP0?YMT&T{XCYuk5Gs! z?0IoKVw*C{G_u8fby>Xgs+KM6z%>_t(`Jg;lD0R&kuh@DS`e3O2e;PgW3V3%3Di0B z@;3c!!c}+IN<+6*rni`|#s7W4I%?=R$Rf;xVfNBmf#Ig(unFgC*8=9YKRwQ@!Fh#| zT&bw^T}W?3pma|5ua|xJd%4hb?_{rPqASw~+8EXzl8L7k!zw95d*JGWykp7*m#kyS z1=pT+`(<31@y#<@kfE%)p)7eCkH9Sq?|OYh4uxN>;24hGU)IJLy+}v`K z9vx+cz!;ZE^epp)8H!5n&GEg^Uoca4dAdt}+NWHh&=;x!84(fCCnMh(p6* zk;r*McW6S*^qmO^l*J1aok9B}AikgWU4+W-sO@#-?!bl8!`6|ttwApLHB%f>VQ+x7 zCKvPTJ0ow%HxN1ZhnWj1ERmZtlAf!2$NdnJJy1p$kOvaQK@hwc;J2p7)|4T1dK5q)jxX;UUky%s-#ceLg)g#@++Rq& z^+d&$D|AT*;x&4ES{Ff&vKgQvwgq|6IZw^3p}yc;304lMhhZo1G!_z^6@eBM;D^LB z3f<@Y2xNcNtMV6qWuyzTy9cN1#r)t(+l~)ZIdlpOlsSx=O{jcFy64yUY&mhNxb2+T zHaxrz{*0#!qQ3Xid{MpkQhgD4-K6V<{xD2qF5IrTeVZj#c_CW}$>PFIAN*sE&Ud!E zsNsh1>?J0<>|orH(M%xWzK8jz7x!(bDs2G^jU`-*{{l(YCznH8+h77=#GuTeJUgeK z;DT*`2<@U_X9(}2VQ&cQqG5N4=%QhN2=yXcv`nc>&4t#mY6Ej}fK7{@uGapbKNl>w zAEWfhoXXhbE25yp)K;CJ1h_FU2@xBK(1Jlobpxe8kx1w_*c_f#MIK(-#Io zB0KVA7BuT?7^ZIuhvQJ_s!nE6*%!j8@N&gSC6elFhJr*;W%?(J!RsOCy*{UQ`%C0~ z6t-eeIMas$y(2R|9GyBv)y7`XpUce6>g~786CsE|+CqNP3=*Rq-K7?4>^S+OrQM^`)yh^P;*z zeDy?Ab+7cIutLb0cw)hk`SzUtZm=|J9A?i`MN#hI_;>ZZIXQy3I3rMdu(7J{1g(A<*)mHvuE7| z4~D9xTL5as>oh4}t);VW^oK2t(k=3DhlZ5zvF(GiG@+VvJ?z<-6ZOQIy z%&Mmq*|}I|!-Gx2q=z+CCk?FXCfi;Ry|IjH^dbXaTgxSn(sZ5W6kW^BzJHNOzBMUN z+J@~c@QZk0=v(>IZ&23%489p+J z4n*KwQzh=lNq=AV>Emv8MG#n7Em5K!RCvv~X zavhf&Jc}EA1&Le9JdImDMsoW@Q&tUN^0zQ#mS5oafL|12)2f)-ILd67R8MTju24Jz zc50TG&AhJJbA|vm^bc51vSj(7c9#dFe7R@N9HhJZ$sXdBvbVV7?j0)^I|C~?8 zz6YNoc{jez!);}2r%X4qQnKN@LGV?PhuQBHgBwXUYnRqhj5W1HM7LZ0MtP(8a}MkhHW>djsEwO>xw=4xKhXV&^==M&M( zemXyhF=tC2=2o*fb(dAd)1`6f)5T6G@&%C8-y9l>czqW=Stw#!=3@iNhz8tfZI@p1 zbq#5oX0CO?UmD(Dc@BBuU1myo;avf|cV$=W`B&+-1I>r%Spm;D$Qw>c`A%#2Pp{lB)^7L#zyvm9P zJQ)WH57^{%imK>R%jEQ8OB>sC(tQgXV_vYPt~B0Sdq}8<%^v4^yGCFkH_ELemS=<* zXcarb;L^TD9|cs|m4rZA{NQ|8(n_g4*veA?6#X7YkjPn@*jynu0T4>OPK0J-kr?L9 zfb>af%b15}=jmxbn<#sBvJlIvFlt7m5C4kb_3d3cW;5= ze&_(h#ryNcqa%89?$s%#7DPO}e13fmIJEu~)vq?F+qZ})7 zb!Gzh3u_Ro$AGzqPK42_7bZAE_7luK3)?_oIG5U=y?;eeh{uG&g}EC16KCx|+qS{Y z+mn}zAlVXYq8!1@iV=+{m8?3qs6;A=rN~-&Lz!H1`8ThX_*XME)dA0^`RzpQ98zi)~DSSC0FbI@Qskz%Wz~Y zpNq$_n=zLS<&J;@I=&<&SBp+-UkbXBNZbWpitWdwJhICh>*8)VQC&?DFXzGmX9~ja zmt0mMj)QqhLH1qt{J*9^t-$!SS*uIG0OQm8e*S(WlFwi)9#EXMIqyt5{pQ zRm)oLJAaPyp+zal=^#+j|a_^y7N zgwZUo(TTBGQcZMUD16q&;;DR{MO8d=2l66(qNw0iNR~8%)*9c=Vs$LWLKn; z*6mcziIKDSosoNnIY^|SKoxaRN3-}R&xmx52DfeOfZ(Y6)|;%|n1t|G^dImYn?C}| zdI-eBk0IW+uBK!m8Y~;aq|`6Nmzx$c`6Qy@6s5KHl1a@h6{EU3Icd#$t8!#|S--_z zt2JBjKI$AT>}IaBHCwPg>KGe5v~ysh0H_qd<)+RSYNHY32il$U(>#9K8?@xZWDHo4 z=@mGTG$3ZhBJfGJLDgaIYPKnccUHDz;}dwqItvRJTM#Ar=wzgM#3n`>NVK4))YeLy z9VC>fv8reZ%_nhyDK~c&BQF>e-a@NN~Ci z#Zh8 zhISa-cMO6JuIQG z%F##{E3n*31xC@DJEd`*t+}wGd}-2X0&we_$fe0y1r7^wg?rrh^nxfCLh%KHsp)2N z{ISnAp#sPkD8shGUWcJJqkQW{uf@B!3*S_?2MeK9kn!$O&cLApP#zQ!Uo9)09A{cZ z0_4MbFwgYx?;TW-zjxoFANQ9k#B3*k$_c0dhzHd$p-A6_LMP;!P!TKi$2hZTzWWF8 zpdn1B&|VId8B03NgB4wLOAAI}3z&^2- z8Ex!x!R|P9>u7EfK{m1+uh?IdRLNV>cI=`JEtGK+w~zsQca!~u ze@V`%aHnkkf8>CzEp&hHN6=W92&I)VGvcLXcjjPevfACrr1R?GZtt0(ihTEuRk#@_6xY>Dqnfi>{iQle$ zLEj?j{v74^<2ukdB%Mw;aJUst^coeD*y3#@t>;7bk)>dM`1Y&}h!Qo)C}Dc=nij2`j*K zM|v3$OQgRO5dtSI;FTVQp2RY5=`l^HWLm*RxG0)|pbskS^>J z#={MQaFgg+5hrqQ(u znJu8R7)O79)Ofg-X?|xSuOmV07;%uFdR6sY=g&SRul77iZ$o1M1E%c*wrgH{oTRoD zS9_d9wz)so+ivz*o<2wfN?(NtVqRX>24a8Dtrjn6*W9kxlDe9vHM^S2TWGEEYuj9# zmUTlfmLnTW&PNd(#*8=Mjbj-a#Zed^_e)*YdL8W?1o* zl}M@a7A^YfY{z9q5^)6Vg1ZvM^38UvNSIac#1iuLc6BC5{G^xsUU-z91Gbjrp86Q~ zRs9R4gB-rY7@YnyqeiU=LNJ5uz9Dp`Am8d_dJ?NcGNeb0>)tlJhexblblL-^yNBf7 z>KOAi378A_!MFh~ce6ZJRNrO^JK|WwL<(&8azAq#i#N5Q!AcKdGttpj&?eG_fR+rg zmeAGWugY7Ky-F4z1U|0QbdF= znKnO9k_lTdyxwC)uos=0QIX7BQ;AnGnv<+_w)7ZgmHRU z0smvPz{FyInwAtilC?Ee6a(d*kzOAwGC$CV96QCW$ z9yuVWZ0iFK1V2y?{GpX=`T3JQDaL)#4!Vyn0>q!dfddD@SEc_@afiC-wf@qs=&9|p z+EzjLAKR(e^lCgA81+pF`^ERctQ~wnrG6x7zblzM3CAAg{jdo6Ys~fAdmycKsfAYa zuf&YBYEPikvB?<+S-B>0M!rOt+}lPR+0a$$zYhugZ%@G{b`d7Vj{43a=XkA-w{Z%W zuh9SR;#`3-3CdLh0QfEi{QvGta{c$drRXk%<+E@R|f zS+EAE3b+EOh1Q4tMO=^L1i32-<^%hH6+l_QHUKxk0eTbW7m*X}t|C|xYyj#6J^;9Z z7tn5y7m%B%UVtmoT{7?hXbL0+h=U-8{LBx7xT4&p1LJ@fK;Ho~5V?>7sGkX6q{+ob@HfRq3mfIJ8xNI#UverCtC z-sXvqgwKR5fMbvls0S1PLi$EciWrYP3fzad0X%`;K|s(C zkO-&`L27<0ZkU&fT zERY(48i)cz2$7D&i{*rukH!kE3`Gl*43Gt?0T%!kAQ$j&5CYik8&y66D|XZqV7U*0`P$f0Nng9vk+F$zks(uL;&$O0x+T# z>>~gX81M}?A9EI38;TdF9($a$qh*i{7f4}y5il12Pc8b0D1r=$XuWRq8G}Qz%Dd68uXcu1!)NELhwTV)Ga^; zXMx%Pj*#1*LJeN1S3pWz{r zp#P1Slw_8K6~Kzd3df4a3dM@Wic}A4tOPa$bpxS6zd`7r1ds~IAMgSp3HcB53>6O& z4-pTR7r;vFL~0DNO9~bTQ-b?IVt^!II0OnL7DOo^3NQr1_(o?;Z;YRhq>RE#s0>U; zDTh)AS^_K~DuG-e-ETz3IJH=y2 zJjO!CKro~gq!;iUKw?Y=Mm++!L39A30V5DNkg0%Fh@X&zsJwj+I+lH$GolM!=c!5O zP-Ux3Wx9%D>&I|8KV~!Fazba<;Btaz+u?G;XP@AhV0#e(3;}z8P`~%g3+*KRHQd)08)b`$Eij&8RHNlA z7Zt1W3^gXlNoq!ObhK0jJKrPv8`qy3$91TdTBwGSI|Vi<_ifr!G!md)m4>ORwnn0iMr#`ZRsJ+Afdi}wRba&o8M)XvihRB zn#owp$%{&K8JfIR)s^@X@0{>rg;*6VHRV+qVL^czA$IhKu1q?H zIvVP#Is`iT%ar@dKRU(-7^;4j$4u67z(dmI4UHwVSd>^ugtlDSDA>E3*pDr)(Q?WC zR#nkZD{ROo$4|3KRa!Y^746}e)NibHvhjCcO76&9f9@y0aZz|nW@p7Pzp<((g(6?G z+e^nd8!?`fQySO?2g`b!284yvrCT79@$#Qz_IOx%l$K#u>-f z#dPTZDlqvs7QMcuU~U;rBih>U6x9TIh@DJln2f{26aU4*G0B#Vil?3(OW9oYlG9vW zflDGg5nR!wUy*Qlh=OZC>G>=lwvl|XT2y}Q3CSbr7`u0&$rLiJj< zvYwi%q_k=4($1N!EhVifm73=(f6o4yWn5Dz^XM$Y%zhECEgSO1v}N1G!r&%;v+Z~y zXj7)z+|n!6vJuk2#EHTkQS;-eK)^pq3}(G>cGO?5^)sg4tivtd+_0Qdkq~Nn9|SDjcKBrZgu=J7@Ygpget4}7mMktT&B^LM=_@2e=^(6{i*<&FCC^g(*%9}ZA`_X*ESh=` zw=Z%QMc@hltR+UH5UwK~&*=zkj;^qlKydtC1b02fHm=&CHj1S+1xNG)*|oxeRzWk1 zQ9_n<4cJZI>C$SVSjwG28ydSV&_73rGd0V?rQD4iTCCY=)qkSZUoBX*ux1`=V!Z0% z;lW3sx1pat_U}Gif8qG9&G^nEgjzKxL?+4#&GIwnj6@Qr%AH9QM`(Ha+vu4ylZ$uI ziBxK>6Ej)GFBRJ7KlrlqTE(lE0^GCCl(M2PF`5X`Kv@cQQptvFh=BqQ4ILP0OO=i& zjqpwG5|luS8WEWWc9xprO$GG~KkpKmVvG&Z8XxIs^Y2!6PIf51c(RdQn9#4by7C`s z@p*CXJSGv%%^jOeHR>e;dwWYpJ8HlSP4^TrF?{%;-iR0T_!@S=T2?tV#1spUY@Z(m zvwk-PEm&-%7#gv~IW}$Pn_LcFj|366sPvG8=b#`#`k0*vaRk)3 zPS&L??)vbbqx%V1fnEX&`TDthx#eTOqx%G7Im$e}`L>9rx$|JnYB5MX#2_8u4Y7~6 z$efeE5LO{6;B#%H{3g6f;%hPH%d4979A7=rQ9wk>`l2hlYF<{CTCLk1$kxK;p?5qx zMx<7q#G8r%E1rsUoyV;^Wn$Z7`CzJ*l=#Qm5$TK}D4=`~FV(56`c{(oHJVYu246UR zWx!_vd_&kGY-dFMQR2FUCMv~KglXEEs3q)z4Fu=R8r|GhPxJW)3AnWVrt3m62t%!g zEll(8>DgYWXCftgSAE}*V9)J^PL7FcsdFUlTq)ECS|wozY5DU>=V6@@2_RuqZc~OE zAjwzDF(?A1Mb0`VH9aiJ1<)oV)dh9_*iM?*<*z^^!sumlNANJbBy8hgD3a_UNGgAeu-Pz>sq}HQ_N3AX>3df)SMsY! z&RHsLZyD#=Csufal}1ijYD6Kta#+*{h{%T0H# zqCCQu?XR4|jCU_Na`jeDl|PVj{48wrzwuE<(HZAg zozxTDPFx9r!OF-m)!vDLTsl~4es4a32|Tsn$tbG~wPgGPKDY_>r0A{aO``KvEL((- zXS%7c#fq~<^+R0snMFRHwv6BSCKV#)pTyK$F2Q)3Xv{UPG zk{1i07bsj^TNo@KH}uMPrk!5&iTPH4gqq$(Z)$C;qN!$ z<Kuq@0^k(?@QJ3=^N>s(`_w4I-C z&1>pn#}&do6(_;=UuSYRtp`+fuy=rBa+D1GoeYoQs=mBGr$A*IN|e7caJETymr6#OhSr71F2$%)=~hcdr&xLC>pyMc zGhxXytcaHAmZyuJ493;MhfM^Tl(@0;TjZxA43CSN0egVHjL1z>6Q6ws_%}&0>LPb4P z)Hz<NPg+%*LIgI<8BfLtg6NH6p&j9m*b184>42;7FY zgZ4vOg?YsKzl;IM5wHUp0LWL}_XAUYBg@yeYtmijW8~3xXx3dW2<7AzZ{sDIDkj>M z($fiPb?Fil&=G(}K12%lO7&_L6OaCp2k0jh-N@$c!b7+&f*@C_G3cUNe7-; zE23(){`2Y}e-Zx|XXX>`#SvwfPY(6TrNM6ghb^H1j&D(K|4j9!F{apM25*6U0a>%= zokV+LdjnQ&agd+C0D5%~Ee|J8L@(ff*b$U#s%wkp%N2klVB00)GUBqZz4wzHvws(B zeo`Xbkp!MTeK11;0I_zDdyqGvOw1-8zv5DM3QD#ddKSS6Qo02?G2EwhQ87Qn4-^Uz&L1Fi4|*eq{^>3q z-DeXCAxAXt{OimMS}`98l+C5h5r+&C$H}43IgD2fxBo8veZCyfG%a$cuN@#%IDy^` zm_tPGhMS8LHv$c{8BR1LG(YijrjIo z%;-0t*-x=Y;sSJ8^0(ZC+!Azzl!wp3iuZ`H%f;$XB)oF66a zrb$HI4j-*SYsV%R7QZtS7nZ!ktX~gHZ9-=HtET_*KRnpgzSjH-=OEoI$`ud?;uWg= z*s;rnaw)ZArSR{EVJ_j08-c zUl~2+(sY>~@)xPY8S@vrQyuoVzPD_~?ZXl_hU~*Kp{lTdAuE~~_qfKYIxxXnJ&Pxj zmcjk2#}r3;pc0-fb1pJ%LMnvfg>i*tj0ogH_^LHsgr5DwjdK_8o1k&7*oD$Sjz9?b z2Ji8l?D9DNAw`OR-x+jWoZv?aX`_4t6+*3&lz>`FO+gZLWPXer?pJ=-DJFz8Ct9iK zji6DcA7aH;NQHOYQ9XJ+Jc1w{OYwWiksj>>bG!C> zR7@OjBmbD^1_A^N$`a&!G;{zqLu>+UjNQ{z!Vh#N zTv0MC&EW(u<1MJ}g2Yz(bVmy|y3a&WCX=fCcJmInc`e_5}Jz2U0?_tyhI25d> zDl*g_L;5FxPmeBP!;K8L80NHLcSyOy;g>MsC zZQZYM5TA;!@^X-3p-y;_j;`H5&BRPn8!9K(Z^4*7h|^`mD$o)JeU7zHVNsBvN)>cp zl_jWx5f%|VM0WS7IUmn}f*lS|?Ti`~xtEKz!$A3&l8z|4H$W#uPAQbQS0uXkqWoEk z>Cr0c5*K49Z_iA0&x}rpnKA${G!j0DTKpIi|0sf$hli0TejO~f7q0B*BK@iyMS_FD zQv8@4?}a`TEw)F6#ey8ERPxvy@AYM9;xkIE>$CTqy%e%*`UMz~;bB0Dy4tw72$sA! z5yb_zJSyDYnJ=_82ZN57be=J}9fo-y)pB97s%ACjcXS1eIJCIp#6hVJN!FrjP8$Ed z;IXC>bWg;am^F6v+n6;=^3*R)OyboXmU@wtQ|US4gWP5we5&W-3EA>k$0&u|g>>TQ z;%br9mfDbA95lXhfoJq;m!0u;@gRZme^H5h!FGG@tl^ zoG<2RTl|4k_nVti;Xvetgd5accjQmXPmDG9Tl|5HFX*U8Tnd9o;S;|_T!^^^7QSE* ziMeskHHbe@@cle`7e^)K3p?^EG>asbb|ajF|HM9MbJyZD7=rOfl!cfP#PWBfh2dy9 z(r)Z?GUBLIKCE*C5yYa+@ki!`Y7xY;%@Ic?;?a>f7))e*p;mNr-lN6!(vgDZ56B$m0OEo_P;R&Ya^GmDs}(pCDzw-Lk& zi!yh3g~;Nkk=z(LQq7U&N#)U2kaL!WvEq6W-01dHC*&v8>+)_wb2x>F5v>^aXzrNy z6nuH*o|0{|JtFxRLp~*;_o6(f2|BWMnBSvaX~SmquW3&AbyeS9d8s)84_;SI|Ah?kOlN;osr6;7_Q5t&HqgEvCgo`;9}_wY?~cB zy~T1~>%aR_jfEK(YR%Y;CuCkgg@uvvQ>-LEzXV2v;NQCX^(_>`TLLGBFy+K1liM|Z z7u9M=TL#P@C=OLFn^6!o8&o|(9!fIi(;r^ChlTVTJ8$DFru;? zol8`^>${c&$bsTYmdV!ztt4{y=;qj*C6`XiW_0K4si1iy7tstL4|(>CV1K%g~gai=a-P>-wvuD(@O}~Fgd6CpP2xZ?-%Jgr>RhclY<0q zwYOf^Su(E_Z2Ve#d-wb+PhF3HrC)FV3py@g_h#dM;6w&)D8EVw;?(W5vFr{xQe5W^ zpKU}&uUu|0cwO%#JYJgpI~N~XfDEj0)H{y5w{Ioxh}YUhJ=qAvzdOfl?&(JI=bxRJ zYje&fZFF3yJ|kBIiJL{6FSRM7qa9h!z5I(L8)m;Ia33<7jJ}lHdl@1Nun*e1oW~A? zX9*yUB*6;zGWx{J*nxB`0Z@@7U&0@wF|Y#TY9A-OuK&oq{&0>kO3Qy#=-6ZVJETN* zE#Vx|OGkF?rY?zniIsR1S6b5?G?UoGxYaLf7>eJ=ycA}~LmB-b0*%u_Vhh0W0aSV6 z_{58{i&jtQ>}@*m&RKN=rF<3>jEOI9PL@YOjG4hkeW!d<^)jxX{93A&9z|A5O@dVO z=iw}DS+FE;OE8UMO~7XPtX6W6*sRgj3{5$;AZERSz#ML+7ISAXaOx{`+}RcW{OqH!!zB4^ICkobeeCOwdT+2I_dNfV zr=^XNtmaI7L3?Go*<80Nu_Ls~tHcpawS*vJeqq&~TS1NQ(_&+}$Pt;;Iz90@27}O$ zRBA1@Xd@TBQV-1wE5l;nMVCgYxM~lVj;OgVP9?Z%u@lpUt7?YdV+bAg?%8w5Vr;g# zy1Zu+yk{N?y=^@ky;;P$E_JuNYRtF8yRC8^X|f(n)o*M6OuhV=d}+X)(rZ(jD#EP6 zid-G*$=z5@>i1~Gj@CZHwoE_{H@){5T-ipSmTJYjp7R)7=uhzz9IoY6+=KZ?JwOb- z367qg&BLcF)HzbXhZi@ag2B5`Dr8hUVA4p*IC*p|Y7P4RA!(RV@NA1F@dd|6&z_9C zG}W$pnY3t2pDZ75nzpJ%AZg=O+moSe^(sBOsI6saj$wQlR#BLvlVYvz@3|1I%D)Z| zSdRuXArQhAME{eW##GUgg(S^-xgYi?T@Jqwk+a98LL5{W=x;YBNuVF9gY`~$Yl*c@^0(+2kbKIW5qVn2rh+6K zBHQ~(M+Uq5!NvYreH{JBU60%tmj{DVLMD&u{*sRwpKW^Ht#Xm)&d&7;XJ3B*eV&1H z{9}7Qd4=u_n};4?vOBTiU6htIhdXG(c}umeH+z3TB(SkG=%GMp#}c)XcJ~VJD1Y>H zqZn|dyHnNkIu1@F@Gf$sDY}dpusW3Mx+^%H==5qu#n=enGk&q(?0Nk;7+7~X(dlg@ zwD1|<=M;TGynVJ3O8FF<-WEB^)IoyWdc=JVAw=C9fZ>WIXC8gw9>KF(*qMg=!4&zy zjBKZpVrRGK)`G<;!?1mFcP;Fz9L7ho^ip!*oEMP%V?6o#0 z>`{y#`MQjk@nQjO6F#ID>1Uu||LK15x&vI*`HmYZ339YA;3I4B!)!lE%KHg%jOIOE z=!s_+Q$`w0BR7!Te;V$iXOyA75O-~pL%up$7Utk@ZL`MJa+ay8|HzlpcHK$mdobglQ?7yaSg>{&Bc|>1%qrMl3yULX#w%W zlb_;_WQ|E+%+)~Zxo%}8&+Do1gk_CPdPha+I*2CTb#c&`kb|l7G4s)Ia6tq@=%V-k4CeS2^;q#X2auz$J@!w@c^;geC0=Z`0gLc z>jH%PY{poB{b7XPbS{2hH~1y-^_~`)mCx%LgT;ha1}`-}bl%WOeYs&&G_bBm1(HVw_x)-3KYO`Z@O>1fc1{g$kc z_`#K@Tbv&rXj6UZ7hgGTb(f~0>hEe_K44~RIfc9*B@q6d|B2?F2o7JZDaW)^5Vy zaYEeE8==XtPaH(-4s`sbl`w@7wt`4uI`q(tE83v1$=aYzo>adhie{QNZ@x!p9r08? z?+jGFE7hFv*z#1#+qdUnf4F4jC18JHX%jwNY@A0&tYW&eEUBN>#O|l_X^h4%#CS1_N-S9nrfBTs;BR+ua1^smq@Y;u{)Em zi7UoJ?i0`^TQ@tqz)K(pW6?U=V zmXI*yEY1Nh{g)`MQ+=0R?`M?cN{_x@+#Kuu@3w{;458+y8U={H3VPwCHDU|P1=gp^ z%@*wnWQZ@hCqy<7J++p0{XAXpp7HRW`02`odGM+=>MOR?5hU>3egukKCJpNcs=;yv z4!`xbBWOafPLs%9)GIR4{~wbTB!zNaRGUayCgKWjLL%uZiZIo|cnj4IYg*a4P8F0& z6?8PtK&zL}#I(+MjIdlQ%CvBGCf2L}9qs%4t}#93H)DG(WPL5dV&hzMxbwIY(X~Pm zyuvnNiCEYW7`V&y62|z_ipylX5t&MaSu-85&-4<`_|k^Uq}PebR265rrj%_VV=XGH z>cgUY_!%@6ZMinnWf45qNY-t&){$eC!I5dvdzE^wlp1?1G2yUoojUg*xrFW$>J!l8 z2yO(UKY!dTE1*47(xFbrnP!>!bDcihEZ=KXn-x$mb@Z&m1R7ZclaQT{IvE{|vQFew z5mt?aD{J)DDJwF=wjdH3zNf5QIL+6Z(%9ni+V7Z0_X_n_Qupb)s4zv&*&g$3qmIOr zoOm{ptb4SR=$f{K?|2I{QVKtQwk%(`2saPk43Kn@C{hS#_awdTZX5(Sjob|6b&)XB z2v={81!%WTys-+WlDzM|IdMGwPR%(B&+=#>Ia*jf*|O_?R;G&%EKjz$#CbpTcP@+1 zXij+Qr=k2qKZUE4$=H{PU-l|85V!a~oMqZ0q1*~Qazi;)w@roWk;3OL)f?V^q6v~TtvL(DjtnC(-w zYX{&7hIQ_jpSlC`+JvrE1LgQ*JVG=ebylZ4ISYy5eiS$qa5q zI}StLmH{=B|JG#qM?5UAoSkcQSK#9M#zC?wN}3 z!?ud<9e&9<#}f3m75mu7u8(o_ccfnwa%VEqG!SyVVIh zY(kp){v~sUoioqk(_tLDJuI-~u#=K&dZB}J;M`0X>N&ySmgLR#BTHWRT*m=s6XVzQ z-7dA6RV{LFk%fSt#r##uc-Hk7WTU(XtH+ZvWTP)Xe#?1(kg^t^uU=s*m8@T7nas83 zvLE-P3}?Nw zqSik1cwbfACvcxPye8gAK#+btelDw&_xHL!rtDFYzdnKIdWFi~hUZc<$~^~|^0T6} zp6<1tFk%F@zU$Dc2^+rBV)TB-!S|HX=9uj+A{oAFV+b>sK7!O{mOkqXj_b2<-Wx*5q}KO&Q?x`61qvNF#^cMLR=3DN#g#i@fKUui!*`Rhnt>^&BCCmUjxp5Q^xVJs4-lc7)d-?dzEJEfn&_OFU1 zr9pW~`${T*-Lsx=`)6>?Uv6gqq((V)Uk*yA9ryTK;e&6xbXhm*;Q6V2+C47rjRx9K zgM+Rh(`{nCoXkmi)5Z$hC%+kPPKh?YrE0r=IZ*RqyesEU(D_%JyZ)@@}m9f|Fst31tB*8T{$qea9;PKS}z4ah=OI=7oq2^_;~OszioZfgZ?9 z&o`oX(;?j=db~0I@}Gp93}mo$8cxA|3?8K_T_KW*v&r#LMyQpb?gQ7N_s>RuZYPa; zr@vZ#e8JWyJzaq~YBc&7BYvtGrL{cTB|i_>auw}nB0le8mAcLTql8P&L%ICRwf$>h z{X_ZtR^LOp1KZWXd)J&+{9M%@tM2syOfcOCUhaA9poamW-Jjf>re&Y13x4a;20ydz zDlLEStRE~R*OEI*lEP@=b5SggJXZ%mfeog?f5*J5!8#2QzNO#QWE_EJEwT5MQ;de6+;m>02 za{kySFeFELuD2woWF@y{3ds`cFQ%i5PP~Od?4NlTAnCLG_(dDN?g@Us!2*WZS8=0T zr?koUwoAS2V!I3N8Hw@zG9v^jo+OlK78iL3#D#qe!$`AYWW4+Qmve9>1#rdziq&&hLRAF(T4-I4trdhLdoCu+*#U{?_L6!psGX8_p**amHEXJ?vitax>JQ$_;`BRH> zh$iMx#15^($y}QU;=hiYNaOgZzdZk`1h0^+QIwlE?h-V9ix~;>&W5g_Cga!G+`@tC zF=`L~{s)6^&-%6NBkR{Ti1VwrmL+^f#aibf=k>=LLHwlcb@#*y*w>!Y+kWwLj&c#0 z7U#{>sijO^ zrQefE|DMSzcrLvVzS_UNq~~3-wcJeWP~6FMyTI-s!||5Y?GX-_R6GdnBt^(!2@k&7 z#g0wA{PwsRAmU#`<$qkuBz`R5N+mhG4e*M2y?RvqH-Hk*S_=DL^Gk?rRL6Ld?a%q; zYTwNA9T@f2?5S_y#f1Oq_r&K6ljzk>p+DeJB)ek!3T7eDUAP)KHA|H7LndA|uykJd zJTXRSET%2$LGM_8`6oY69#g7QG{UL{NZ{BCz(#a?&xtKd0+jLP0` z)Ka&yk!ncv1G%g0=Z@b(uK%De;9XYtmHMsrB2%b^dS@@EB{nroXIUwUxJNz zY)vH^pj*MpXrHP4&5d%7&AKmdQ~~!U1IWHOJIVizEl%|z?LGe8JW*06us}g3u&4#D zG*Bkrj$NlDP#)rUZv)A2bC^aHBW((KRxyV=!+~~X^3YZ(m0!uCTFGQ|k?Qi00o{N! zqDsftV%2K<%R$ED0J-x)B9sda4b-4e@AIx>W6yy#m>5)skkllE-q@S5e?xg7`?W zyHiS|1CM%Cv1SxwZh;=%h+0YZtiA5A*7%w_-QPhKx*jhEXw+Ks&+2B2vR_sHyI-1E zEqbbjF0u>R_858#Dvfb$b-Jo@)nz#7|Lnpgc~EK5^=v8A-I=*nt5&-t>e5kBqWoShAQ%g}4IgRSDWLPg#(5=-|y8I~P-r@r!YTVfn1H znf=dfRV_i|M;W<`QG)_zxhG`ui%5KS0Yav<>1sg=dY1h6dDqe=x4}0m%Ca}2#i5}hQWux_LXt$y3IWKhNITPN-i9U8Wv&76eW42N}iN4_%wr~9K9yuo;v}h(O#}vaCFDGVF5LA z96TDI#+DY^=yTNx_^`d`Dk`Gg;}u%V;uLjhmz4n)mgChMiv$3wfccS0bnu)55_u%r)c(Aw(gNm#agkkc)hKo7%_w7m(4OwRPtFN`W{U zAiQ&Vp=fF88K7pCg#P_u$b}o9KMQHPl=sNa1|r8j>c9@kgPSCq$!S){`xE~>IFmTD zqvF*&$Zz@*=?t?q=4S?fsfYuvTN2i1ffK!b#qel@&-^=ec-U@}PlkVhHAhSE>Npa8 z*gktiWt+>?iVWQ>64F8u-`Ko)_UG$SGPhaI{0X>IM)87p;Q`M9c!mT1Ji$zk?fD}4 zPr~U9z-@G+b1PwQu<`+pa#LrCsN369sQKdZZ{hxP0&J;oxD6w^bkL}N*~&k0BgRwn znP;3!*(i0z9y@+^?Eqr%k<30Z%}v!yz$(cWjV7rU2dEkjdks-8EG#Z3xr9+D$*N4! zNI>{~9lK7}_EMd$e=7c#`+a^`V5aG44So2paeo2M>q*sklDnPuR7(Rk-5=J!_JgO# z#wS~kP-RL^&roG?xdTB5QVQDjuSfdJWxu6{s+9)fGNUkTA1u-Ag;g3RJ{G&uL*7!K z9B{4$@%%XAMHgBsq<-fUTS!&hz;z@-DDfJH~e}&4-%f zFh^-00bx{?x}d&#J5x%AVaAPgIc96&T_aE!nhX-K^}n~aTi4qo=8Xh8Q@+cY4haL* zl!712@*J*>FofT2B)5M&;!-gL826~Rco>sY8%WLzP89WEbTexHKo$z!hX}=~yi}$! z32n)*pRN?WU)C=QfweE7{e6vK8I&@VJN3BXs6Pdo;vdQl5hi8|%%H#5YIsK(H81;$ z>GO5ruM`yxN8de#m7D}o@Jc-x$m%s~$4Up|UG0){{uk66Eh&6uyW%LIh6_qrO@ zj>aoQq{|!jgX@y$r}B)m(5B}nR@MF@?|k0XO-|MR*)dB;3Uz6W?3uAlsHBVhtd;Xd zO8AK^?CiM(_9b7Z`)K?TTnKHZ=Z;wPR%OIAaXj!TtoWZ!I(Zu2Z=H&ecy?$-g((VW ze!^t`Qo)P7$UQw%no=%0LUt){V_mcY;hVu%b`zD)0k|}M&i|SgMmn9-NEp1NrK|*C zbT_QGu!L!Z-CoI*^|j;?yPv~G*$V$im8^Xm^pZ;{%NFoUnb@IB2_%^4g}!l3xgp!Q z;gLJ|YxXomYE+Pnx{=x|LEj6QV1ax(kbPp$x^cx?2_Q@Tz}jCK?EcrpH2PqC6J`5> zlKO$azcSMOZ~4G6Wt^q|ChJ>3lWI@5z4ud18{WhR!p+8?ZJ*_XgEm9x)E&f|m%VKt z&4a&l8xcQn%D6$x_Xdm~JfkFAs`t4)ryr+ zh3$JD_2Jo5uLY0nKEX+&8-{0O1218rh`4rFh3WrkP>>7wqnkxcXNy z(jB!wG@$`3CXh*5cNjv$H*rCJ!pPolh7f80!F@Nu-va8xx&l~!OfdMs=b1iz7kU5s zzy4+8rvy@ASuw-jH1IyEO!#`9$#p}>^RNVR3u0HrV)DIqe^Jec9#N{`dLP_%o;S8Q@Evq2dyfwmR}*njxJ*x$ovT>)5r$CeO<%F z^pZ~OOz;51S4kxRD@Nx>oQcjeCC!3Hex{#p__Z+UaSv+Ip*MY18oKjAw0ABnlf00` z|Do%jgENbkH&8gXCblMc<4h(tCbn(cwrx#p+jiaF z>a|zZcK6<^ANkcz{PO(XVTCI2vm#~4r3kk~5#P{)Wr#&?X$3<9h3Zq2UqbZA#7z@CTcZ1&p+?D$i!Ldlyr1W;BSqMzf2^4D;pF}7v|V!^cqO|)gIRU z#2ja@#H~cuM>L5F{c0FD5fAY?hww_I;m0`^@1T;~k(cjx-Hw3~LzeN0b9w0_Ax*UU z>Japnv(Gri4X>f!FplpOqWaqF$YGX)QvK7WF^tHNLA~K>pxQamHCJ|-1y+N)>gccE zP%#$8)>myR!<)tG2)3_JuYIP~;H5iK3t_&RMi9bUz}|wgJwWTR=eH#?D}A0NEB#vy z_oPW&q3%Zb;Y#p346^5?TWnWeRl*nKq&>_l2~n!KvfDk@oxjoRC28M~qUVucqD$i= z6Mb*I!WYS$cPI_Dw)#TvuLhC@Kc7ECAPJR`?fA%y!M{J|5{CZ%uvO5BgoNW3l+Yrj z{QP9bt{WCpU2s4`=sTsZv-0gMB60(Y4SHN z$ABV}!{9`htn60HPQKO5lB>m4xUiM!< zT)9hZi5hzN3QGURz?GQTucSjxxeL2Jc$a3jjB4GVt))zw^d&>i5&s(WvqjX$3bccq z%Xg)*3Al!R$L~mH3aAf2bOT(AHb{Ftys|e0E_PO0}a8k!F*$62T!NHtz03DX`R{L6r zn8qa4ada<#gXBPvACKEpX_XUXH}PYy#0y&Q6@M3VU0f=Msz`2haVXFWN}&&I@q3_G z3XE%e*rLq|e=OCkh|CsW!})H1KVw9c_4@suZ6R_LuT3 z)j$toA~$kkVfhs8s?MH%6tCSmeyy$j8N}G zkkBV5!e2}`>pf(Pc^9hDi+N!0q|(bYp8o+{=6E$aCny46z|LCh_wP!;R>s$dy_uVto7?s2EU|AkT4TRov$PLT`VY3gYoz}Tde%#&`g_q!W;)zn zUiSgR?W~?*?+bSnhr&Cw^7gN7ZQ@(oTOy{2KBL~gf)^gWC)9@zjHdTVx=(E%oZ#yM zk8L`?eyL9oogWnct??}e(&s3h-vs*SIhKHN@7Dkpdk}PY7(e))4f&hRNmG$SzJpOV zV(5nH{VLq65)(}K@1y&5iY$^~O+cgK0hp0CV<`;tZ&*&-S3PZTpe14<;Mcdo5b_7C zB7l%$R3VZmR}=zfDxkEWT=)l(C|eXB07du*hA48BCcsK@v7lUhF2IOAiiK&VS6r^=J}i$%6$>NO$ynudxXP2 zj8xg-155>+B*1h$ic=s;CK z?MO&n(KY^qZuA}jpf_@lTjm8j>RfR%U{6e@9UeFhuoH5mi`r1wjN3!ObT1@!FK8!V z>Vn+d(!2#|Ao(u;u0KMS@*F`Vj zQ6xs2@d~_=17)CRV@!d8qxr%8fnV#e!u7**A#VNsNz1CUV zTwkl11u-O`nP@C{x*Sg!^E{qfLn)!0vLgL*3*Q)=j@=rwQhz=hxmrFvXI{}#lNz0< zRnvnq*)6FqJ$2|268cRnsesdLt@EeJ%XA^L_9}P8%%G#Hj3x&9+rQY&WEkPc`Yw9J zJ!sXy=E5Ox)yfQ<(EDD&9+Sm=7^Wy^A2O@x`&Q!g2O7o+?mGIZJ^@~&p+;PD{3B2d z+;|i;*2?ukZM(fJU~a+54L5Ta2aTAOE;PHkyuC?65cc_lon?^;OLQSoqjX!3by|-Leo)P)_9yv{Dpcc)tuNOtgb!Fp#gI#~ z8H)8J3qf0ys#nJ$*#%2)dPwp(h&={dhmC?2xOy$z6 zG7RHg#8XjPJ*d=#fWy!~D3w%3rMC2gwOv+KJpkT)e>6fq%@eBo{%cLO?UhzFj| z7_+mBaioRoiZ0+H#~@HIZJCXo6@3l6?$tSqIB zbQalR(?8~xCqy&JH{Qa@-^d>=K@^MWEl9EUSMmx~Ac}8do4@w7%ilU+9OG^kr92#C zOCJG`C)1q0cuZ;2t25K(vkFLfNL*#5MC+ZdtlVPbmK;>6Zp^ur*CJA{Z(?eERoNZN3gG>7njFPEZbIrP)@l#E?Il)N zwEtnjMyTVUk)dl`SgvXLr{MEX?#s*ZMR>=YMxNkNzOZE~h6-KzX3^oN^dmjB`WpY~oq#YUZ&{CJFE5UDUREeu(}Wp`^|w*+zhFxa&FZLAnj+LV@3j>Z z1INKXx|yhCUFSW)SF2We37Y3AROz+AfGH&sOtq3u_KdP_KUg_*5AR%1Cy+BJ8*)oB z`6l4c43}83)}gH%eKL#dz|Z3L=bz7n7g8YjeJw4@v{)j){T0vNI89@uVKW2hMbu+_x&`jaM?LP5o?S$bv_689r+1SE z&cV_G{o&m?Y<*qU5-FxP5Y3_qiiWFG9H+FhS^w3Uu7M+!)UuRK+F&O#YBN$XwM{ZI za@w#f(rG`CKKWHzA;4ZbjVcY6!5!Mq0_bAuJcP>WG00`%pU7OlEAIq+?C4~0ON-vo z=S$=`ipF*;Ql+S8$sK8?{e*P&*)jf})+o#p`5aFX7JXPtXD+S7FwHEl1MZx#YGGo4 z+on^wX9Dni%$93P5LYUKlrHInqSka2Jru%pnV1vj8YTa};UK$1oV>sKZ$`;VhEwm0 zN9wFGdMOMzF@rO69gx(iSMgu~O|x{if;=%EptA1&TI(oCIj#})@ zBV5^_n^~S&>m5ri0xM7@ae)Fu;9#wrF0-2d0-uJP(6bpxy0k zTD;Wg)!9ktq%&vm$Du0ogQcP#EZHh*w8vU0Tx>)DOK5Mg#}OFKVrb zt5nyprwi_a7#wko6_U#)jfbzHESjoT^4+0lMMEAxX_+IR7bJU?YNrB}$-0+C_ z)S%Nx58*lJFs|6hL5RE9!o$!71D9VNl(iAaLq-`}kSp^<-KDDr-QYEW;Yl!^!2GnSsF@`^NV|#6v&VjgmdrT{f9A)#iGhZWfDFuA>zj2mV9qy*t7es&=lO>CJqlPG z>m)!Lp6z{U2@}0EZ2x+o+as*(ee68{7)MlevZ>8a&p6Xg5#u)rOK}s6dpC!+5iv1G z$H`L2q8$S08t>C$o=;{uyq?BGwtDoUlRAZEF^;@_kx8#sIrcFeGrU*~o+QdW5H`Uk zOg9z9#2iBdQNtV=vmmjxMl_;pE>nTzkofQqxgW4HvA`BIqy`Kt`e+bh^&8_I|5^Q#TIMqvBXT`l zZX+v`je>M#Bdzh!exSmz}F17Fzqj01>fu^uERZWRIV+Hs|kpdmXgT9Vf~P;In?uyu>7A38n;W#ve_S~z;^G$aHd`H(+%d%Imt{$p&;>$`Jr>@Q z=qTuBQmuJwevE5=fsTF6A5x7US|0k1J@mx8jUQr-AIncX<4@ijbV&}s9oi}AapDH) z^ixByPW}d8#xrhMJ49Z}CxMVn;YSfhJ8b+%c?y9QqCJrOB)sS0Ep zKZc&<(=YXtF1K6VDR-rIX(iit5*knA2eC_wJ{D*e>6yD`2l1?xvC8ux@DH;faRdKTe z2e=YMbpnjwqeK*0qhym-!!CS{{^mq#!AkE*6^Nh@{k{}vl~3ILk|K9vtQ{2YR3wZx z;){~C7@4*CO1>C=B92lI;O`=hRCKJOh%-*h@wlV`$c0bs;V5PY!|P))B@9OoM^id- zkpIo}D520}AUtf0PTC41tsRK&g&wqP;{l7@qKRxX*u4BbNx8P=7C(8F8iH?#QE&U) zagk*5ywODQFZY%lJ3uH2CxYhFkpvn?hrpdm4q-#XTsE}o?Ew=-6D5mEpm=BsA(!O* z<_mm6$1DL%D5MmXCxk3$-2OL!P71kS!&*>ODf&$Y&tYKORzC$RIp~Y)1NJYj%l&nW zBn_?nMHt*Ce9JPV6Ab@vNO|06n5Z^|cOqb)Py|F*E4C<6louv)(up~Ilj4-n4;&z` zBvNC@D*#2T0SqWCnLUY)Ex9L5|B8kgUSMGcAFW6)eeAe!oWQV%-AFkcxemaxtKy| z(JBhPxO82h(uM-PIJoVRmP~stWeDZ18q%M@0XITm(1^L9EIPKJuw`R%V!fC`81Sk$ zu^{=tx%|x)18ML3T%d$a0wZrX=gBA$5>C*8-a_ciqZ77$g*1_Pen`3r-e4R(l!-&@jG}2gl zf{?J5rVqk+ z#63fU1QV4KiO|;8Wxj%C4&LUtl_Hx}%M+7Gp7XtdvkO1sX6;fRp6b!pX4J5nvsH1W z)k*G5T|Nr#+A7}vk<{_rcUjVO;{w9X1D#Yp-BSBx5A6&5>bkQPVFxP%d?JU{StAGP zX(fI-v#jsa*su+~S|q>qoU?)yg5R)5(5GTP}7H>H% z(lS}{tgI8GQG^doO<*_QB)=FYf8zJdAQWp^1KvG$;Hog6?<3u}Snj28H(9HcoEi;w z{$}SA(~j#4OD}{E#~6~5R(Tk4)uo?D)vh$b_l)jFz6L=_e)9}}PlY?MM?)XqCVNL! zeaS=nOs9RfhwH0C=!4yTR^3GU{l{`AyU?%+~v(tZ>jiamgC4yvrGfAx}7 zbp}1AdgFg$lDZ|#qEUNdvwG$pB;*g+RYnjE=}be*$VTKu%LXi~ zh-U@F(h~MlDIn@9Fxx|QqO?#Hi0l$$w5V!Wq}#Gd5n_rbtW^fCRW=8rCl;|S|23#a z%^!)E0Dt{`raW1Dqy?3Mz39&R^6Np-);7}2y1tBM1HA^C#{{ughA`!l(qLc)rhbRq z8Z65XVaya*)({hiM>+`OeF*c{+5iRVBcO zxp6sY1MEt8K)!{a&|@rAWpOf4qWx3)pO}1Hnt->IA)jT-URsvP90c+eScNCd=T~TR zJ{@5-+VX^^(%5Eor9-i{V$nuojF^yMYLcpynQo|JG+zD)@N5BMy7>9%9&i6Ehx_ z+b7UlAL)ue(qjCf8O{pdFNE2e4Qb&L7-m1=#*i{q=0-fEvuL<1niv}d5g8ccXl$`M zB;#15@2G~Dmz2OKU9gg2xCv?s(syxa%6O4+NPr>&B@-k-J2syaEDExK6FEP^m4b9R zOSobZcY^&ppu`biDyF~=ks@2F@Wv8`{xe7kMIjrmWDss56zq^(8L;s)5JLADs^k12 z%QZ)eA?`dre5(H~*`0_lrb{x-Lw=(6X95fnW>{!#QSco=kqmZN@n0)gOraFGVO{$zB^_*HR;HkO0$1uxuR8b+LC}-Ulu3@{e-^u-C-pxI zF=}T3wyzl{4-j*scR=p89!-m1PrxR~u`XTN?C>exm=Ce9#~PKx^(QaM{m7Ko1am|q z8xK#6xIe=Edw^15xY2!LfGmqym{8<%8EZidfncQj_s)ws5gI4}8KT13d`ROEm{d2x zoMtESgiC;uE%-zwYeBXNTnX!pR0eno7no@+G{DzVc+C>7gm*?N6g`(zwp;bE^ zqQ@fLq4Dq|(bVkkcaMjlC*VTJf+?^SjXKBhuc4%Jm^aG8bCOk!ls;(^!(c0thFK~4 zV@}|L;TaDGEX>(o@;?T1;@)LBgZzuQPe{g0D*o7H*sR3!fDZNkIoh&*AS*JTe&L)gWn5>-^&__zbxAjhC{LB zP#PHK5A$!<%P-`=rE($z!DTNN{@ohwzy64ylegxuv`b(=S|B2TUO(8)xPfY4CV-@PI&Xo4a!DAm`WHTP+1oX2nKg- z+5@SfoELI?&0P{{TQ&G+L4?`~hDE(}25@Kv2ZT}cFe_c5d}XAjJNP{4 zlLvdXUOJJwP~jXG()5I0bDCE1T;zE4x4|wRhpp`+_T_9&eXcO`+ig#ZIyrZ=IDnU| z!!_H`a!bA5fH!NC2jgMMzn1*s*R)PBx(hKL0!TL`#M>P}YtB!fIDx$VS@V}UaRxB& zk49*nqfEjJ3F+i^)mp4x@Dj@>>OLC#J}SE#J!+q5IP9`g&Wdh5zZ19Ml5jg`Ht&xo zT$kF*Ve@P1*Qdaca61Ad;?Aw#ry^}x^ByPc91G!gPrAd#0-*=1@}a;3%i;+?m<)J3 zhW7glb1Gh!u0#Qsjd~K2&Mo?lGwj{vgVsX2UQaD;U6|H&DYaUa)=pv@*YB%mRP{^K236YQG7i=QIp%$` z##O4Y{c3HKt(_w63!7^96*VY-q_Hh*A8}XDcnqpW2h{%3ub$OD*t&A$cTtDdV6$ld zh*?yNW~pELX;5|CuQnT81d^?#49r*ziV&U3KUGd<7b^Ips>o#^X@%^!b4EP>j| zo#QP8h8n8}^Fp3^P!}W`tL^o@K1B`r=qlFvl$4i2fkQJQh1snb! z2O%10fGKvq#`Zy>0=|hd?Br%rc6g1Z~IG?ix1}B0h;K_da*m78)L5aGMZ(MD{u4 z!8^GJ=)<`aND@<(MrZO>@u2T@&TuLd_q8;l*&g`mRUx)}J>fnz8tU7asvVhQ%QrWw z?7G+-Zb1NI_~o=I6^oJbT#>uerLm21mbCKMS8JQKqnBjjd;;c>7!KK-W)t%AZu1V! zYqTr$C7pYGr$XZI*t^*-?7 zE?Ld4(v7&Rqq(|2j&4PS&4kC6VyC$(t;&+&$DQ1y477$^|*O{B+jO(L4U~%IdyJ-PzwiJAwkTE+PNAOfyLtQHEF)a zzA=$$nm{~r3hrU6|fMiq&SH8`;eYOWMij-Xva z2IHe&B*zwb|C4>VPo_dMcZfo+#S2EOCt=pVHmgJZ{!ypC$zrsu$$8_jcYb!4^@oO; zz>ua~&K%_7<7^RxY-bFV1HJ+G0rnf+di@(n&!r5)R+Wl5h*f_Yo4Rw$g=iq^@E_^WtKehWmd3K-E>^Cc= z^(DI<`)J>V7!P$MRi!4pKTW*6(d}jZG1niw4SyH|B%gy7El6dp7=and#Bi^&^=~#CV{u*tNC$$9>b`%r<)6 z{WHbND*}ycF9JuuK$4aNLBH;a55w;JZR~B+q0SejjQ^SSy8UtdT&w*=^l)1e1A11o zat>;LCJ7Zi`Zl{RMX#xA;%dqq`5g3#F8R3Innb~*+=PzY|1Ky-^+EF6%Sa~lZAs(9 z(hSyjwxx+nQM!_MSz?YaJIhU*Wf#$vf#FjvL7!StitQFo!_D_mlenxe8RJcx8JA5L zw!lMeiMXm%%&ztRGx5ZXo#h~&SuA!uj;{ui(P{tj);ITgQSInb=Z-k)q$+B|xhF>b z=AQI+i-jhA`Ezf5voD^zLR;ecZE#gDlq!)Yp6E;D>MIzjo}OCFini^JMIm2N6fs}u zzya`2vjKhb$Bn=@zY`ZoiUWKKtXe}Q*6y1Q6~Bt!?OK{7xH~F>${94C+KuuH7jms+##^06Ms2?eB^vU^mG{`6z@P4<#YxW zE^@jyj1=eKEG%`#lSS*JR*b%lf_eIA>og$SJL=k@% zE~YckY4vklA*_xNy}d|wLbxTx>FpjI^Lg`G0_u*)h@=2mNisl64>h>WfXt};jeu~) zq;q2BTeKZsC{9%H8Iged|ERdAX4D9dJ6qSh2gO$ClrSpUu(Es7%9|90e{-TXRa7{U z%i9sk+r6SH$~Uf6pp+C9%>;otfR}Hc+azQq1H1Z_4@%mS4z;xOsK_|H0bEmz2hEs{T2Y(~qA}QKh~v$e zia~^n&k*y%%F!lTQ2lcF{prjj!geKVC369%@xly-=WcI`mUZfe+;Vdx&1 z>W>`E_OAjXhA~Y!7S!BGx! zPgqcA4xF_1%2`;a0&8yqDZ(0T&x{0Y?~R{&I8~FZb}*owinR6>46W^>9|N{+*~wG6 ziu|>AR#9u29lg(dVfe{+c;clu9xY?amqhgfyHfL=b?&!MHC3La+ChLw&kGWxNxr_o z_&rj&KIHD(q4URGhu^DCpHHnmKk@6~u@zM{7JikKo}9dVPZ*Ll7I)r(S1<3YwM2uG zC!OutN&^0Z98Q%fF=IbRL_abOFJ=d*n~}9HH?~T$;P^ZxcIkq9Ml7P~+n!AbCjr_2 zqn3~BrUbiQ(d>Z{3?g|7`y{k@>UOF5zFZ|8Cw}~_D?%O?*(Zm!(kruMhmHJcx@<>* ze#u`FS&ijce+ni|26>fBNtt^LaMxaI$?j5`(WN=AO>tJA=%72?Om(`F;&Lzf2d`(Z zz7CLG`)pF;bAt(U1>;j}@Wm$;2lZUP~i^?S*(f zt~YPq({aolzjwj$&Xp_k61UDR^WI(X(tBynb>|*`zKeIiDe3+6^wM9ST>!oY-0iRu zJ6(moBbwA;YjIP83YIG2o2_7Kw1leI5w%MEr37`LPOuT9Oi0R#T(F)Hnz+?oYbObQG*3(Z3}Dt z7~BF=I-(^FzSZbb-9nCGeFOu2wf?yBc>^G6BF zQMbAp{Zl4bM^a^WhQ1=X_iP;L-~Y>qgt?%C;qF6YkcfKn=ObQ4DQ=e{^sb8?HBQ#g zruh1uVF+%uF~LNAVY+wKcc{cQq#Qc*ohYai_99*WtwcPZs0{yH^R5^!fw+#bUJS)_ z+B1JCV z@%y!(zqUB=%7JP>7Z2s4ItRgA!4!^7BfS3pQXHzEACW_ko*Xbe>52>{cZBrvaCS+> zzNO#0TdJHv>f$ou5Rvg^U@_t#;WY>v4Ig62rkMCG!A1K!=WNL zc&3`iOFOk`d*UC)pY9o3fmcvR&%4G|+R-MW*6f2>BAIG^=MQnLdSNi&*OGB$_O9_^ z&JrqvZHm_=m#0F=ao6VmeR)o%ryp|g#-6OSjm<2PviRQw&9>U~zy-e>bJnT6@6(4X zv$ibOs#~bdhMaZyRs6!b8_w#JN&RJo!N$UTW6hGt^GK^L_!Qj&w~N2dQTUawKKOSAR*b7w#H&{Pt5)Fui{pwz^B}ctjhG@MN2$FfZIaE- z7()kmFVE74hl%&ohwDwMm?CW_PAGp=AmZwYG?ug!D{!Z!NS;ezwJ+@~OP(+N>&b`V zCn@tDluDEqkt&l_W3o>Er1kl`VWNxPaG%is;rF^n)+)939_^lCnn6`Q40Hdjx1@Yx zj%Tmn-=o_bcQhHH?|1GV9M)+f^RggCdn(O&hW>ZkVxdmmmiKIik$NoUZMTl588ZP4 z;eEM)I{CHoI+6|FJ@g9TueFfb_eg1sV93Y;Aq5`^Lbco)4gV4?HU*!bbHvmL@tUpS zt%4;fiIOy?DiY`6L&FWM_wkcOFDTMQFWA$7tMImkca**RE{Wdl9OkG|s$1&8;pBN- zV4Ded)ZhEaQ4$KSPhq7C)I?hUAOG87@023~->62O_5r=hdWu(#t%Vm$_}1*W)+o5v z#56av@*0XGFV>slbaWF)e&kb|LDXd}g%{I4qNf5u9v`t3E8D-MKBkM;x23EGY{A?M z`ler~2Y-KFj21nuL@60>D4T5LT3u2P7HVzOLT=Q;ZrDL>*hx*cs`-;oJ^W4Cv$Xv9 zrNMfi2X}7|yYUok3)|lsY_MVYzmxrg+RC5&!r6FZ;c#sQZ`@2@o2`lItHWUW9^Fje zJaeXZrk?xndgk24r2mhYnDiu@FVkXBUslR%9qE7bi^to^%zwF^_nPXMCR}n-V`^=+ zI_+RPuO#x%ZInA_8l_fRr%t@kPQ2hwyl_v}5ncGCD*J0-+Gf5qAau>;vum9XcwRar z^_8v{?j9i$-H7DpC=R|LD{lJ4DhG1luWY{Z z(Djt+a@Nxqf%gU;*z+Vr=>sMD6Yul)Kl>ggGxXoEhNx%x67E!QA=Vceq0-q}U?WLB z@0)@q6gwd7L2c>7tTl}1xJti)#46b`#V#`lcaZvIemiu-s6L@DfpusCH&}bHAtDc_ zNjSd$R!pC-C6T%2Qpae&U-vH&U!ysnAyWArCLc#@b}g~I3B=`3)s)g&WL-b&vz4`G zXc&%D(wwCxxk?VR=bhv%xyqXV2Y=~w$BL}&U#D&|HK|va$Md_G*QKAl@`S3GW z4{jOMr`fNY3h2xFC#Yclu%D(FBl;OwpA$JLeF%`B#L%C_JYercFYaxlTfguF3hv^WF%6{lyqr1Z!0m)G+}dozctJ1+Ov>@J@fUH<*JH!YK^yW8b1 zl39IgyTWM;1QoV;R>F=} zj1XlaLU~rg4TWZWCdWvO>g^-o0S~^|s5s?^l3D+li$Sqh6kf)OIn=y41ryfyL%9iw zQ1I{30f|86sj**uR0-JM9sYKx0H~lgCk@0!LB1l`=x&q82~6^CD6dcqs^;JHpVr`y z6Y3=X65bIHIgkB}c!Z3{KiAKFBW#pQl$Nx6GW}0;y$6bC{28H>*$s^u-Eo3zdEIx< zwQVU*Q?F2Sm&q}%_h5Z4mv+ZO)UvjB+oh>6HR)iG>U(gcc~B?gqju#>G+5|G zRisyo02TCFUiqINs7@`xI+vvCJY!2J|5XhJ)iJ1*H7m)!T6Z)X!^lKMxNYX-kO#FRx0}z+jqE}XP9#mOINC|GIF~Fls#I#6 z5g7NFZ#+bCw#vcAJ;?0R^1k?VZdNCPWZ`N}Rhy0dc#byMC8;02nta0@0x>jrj;7!C zz&)IQ(aK z9}6&#%gQi3aN+%tZ_;lP=*+2a53*&PoOVjavz5mmvKJ(g+g*2NX1PRM&x%9x^7O`* zw8s{MS3TbsC3~J0C3TO=(NB0Iv+uUHl*xSvvEj;LROKozkL;uxpzxQA5C6VnDM+W$9PhpchRC2T*S zZA`2~m2(~hKzVxiQn60)HAtbR$1RzuR6NQTY;rpsAHT~Or*uLZq->ZLZ6u>Di)a(XjyUH(H3Pam-oWkAe zVt16DNeV)V7gmK5?+a+~#BIEIT8L0`iaVJ5dT}r_oi5TR=N|jY@Kxb0rv~HrQZg)&M*sQTEasrux66vUiryE~X;$+@Z`$qHn9+piqoc)DFV4f(YZ z%Zb22`onTi{85|0Fg8zYz^e+ z6@~iI3ksm**Fl~TfW3(+pSa7jJcKWV_|;;2F$u;)Jk)^opyrRt6kO++oWyH{UYUSq z7lZ}A<;R0PC`=Af-bDL=8XEr?f33v#v z7Ur-%*M~mA0ee6Me*=PjB&FE;Hs%YMVRddA%&Z9aq37#EgX&;TR=^&tWeWtD$3Y~m z2wT-zf1p72Fehzb4;x@_mo#0cCPMzhv@T6{UIK#tVEF=YAQFfZ)Uu1xWXO+Sw>&Hl z_lNQtYRV`2Y4)$gZj<5v61;q=fA0GVMf*^%Ugi7wzPue~zrZtc|B7I}S;h5ce!aM} zJ!yKSGcEl&yuZZuNB2P#{n}y$@!-DIS*Hl)gEX6Emr^94xwvy^rDgd#R59V@@?3#!}SvY0vVNvPvllPHw@|>-S&%ZvbV_jP2oPJ7+!wjzEm~ua6r7sf_-}Y zV*=Xw4(8VceS<24#(PDvWzM46%bhdsWWdurijmLvB;rj-u>dK8O@)k+Lw{X*(w7C} zl|1gWLm}9Q0lJ2GCus9wOyBVXxm^HGWKLm8nj7`}rgd-6t?82z@C(iI4D&f5&?sYP&`4<^%4A z5B?<=!bbqyM?P!Eo7UN9_8+I#?G{q}$YwW@pK*h-UHA;A@Zq!Q=k}&1P~sbuVLP6I zqr`7K!XQG2e$r?tcL@gwc)1<$bR0tTO+Apoz}A-L=GMO@7~}I>)K*y7sU~(>de%ml z!`GMV<)V%1B$D0<&G4?}@Gjo)F4yqxYkmjY4+_>1Y%4v@dt1!=iA;NpmF~hJe4~pY ze1Md%fT*SDb{(?hbgv}laZLUpt8(FC${lz2cEEGijUVEzPq?Y9Cr3M%@!z)EOaiFN zKTFi@Z%FF;J7;v#ReOGABZ*E}FW$9`Lrb;;!NI1iz)&Mb)t z*=gS#ZC_@b>Vh$+MQ*h>r z({t*VrM9MS3?jDkLLxiXsoi0w0MP9Q}_Hv*{#&775$2tAR22vYE0&W=?Gy5fd z;AKJus8TYwnRY{$e?2Sw3EIg%mQQi0H9sd1zfy<#LKZ9{VsQyOuh@nyKheH4Oi zgNjA8s*ju|`~7TaYyI-`zb~t8uQ@j(_E@v_6fdz5eRDe;Fz+K`zqjuIyYBM@eM`K3 zG&>wv@1=p;NHthCvsg;#mq?N#3FXm0KFak|tS7nf#9Lx{ahyo!bWFrfZm07UbPlD#m zwfvK28o7|qQ24+rgv=^2Zwm?=i7H5G5?s^6L|$4kFdSL`<=ZY^yl>dA6;)A4fP-X zf0I2s*|Lm%XDr#WlYNcsJA-7bi7?1cwlRYtdqs;aqe9l~W0X=^YAnM{QnE~9Wbk`` z&hI|=xxeS!-#PwJr_=F==R6Y-bMSMMCudQi!x7>3QwCEwJ@u*bTSu*pQmW50-vVI zzWi7?M~5j)KF@(>KkPjHE)r(;U_*m-7fXBPB;Z@eciIT`gbo$I#rMmeFBKIVE6Sx7 zUQAuXz7KpUbVb!N8ivwW%?r6Y_A2$~ZRw<7N?4#{W$sfC^8_pYqFw&ww}S5&9vug~ zq$=di`e-6jq+HVQaap8rhfq|J_0dVi^RhX1Q7b&J41uPsw>Xye)!i@ZZS%aPn`E1i_{;i{NGoVnVM z49Eu_OoJ}Mn4J$JIuptmZuyf*ZONcJtOqo9luM@OFyvTgFr{$tt&h$?c#m@~?4K;( z2T|`!h^1Z{E6E|Nau^rYH5SMuuF_SMBw=M6cc5K+=M*+nR~ zlO4TimkSz`nc~2sf_D?6lO4m97esD+mE{wbq7FSl238~{bS?D`maVDtkt1J} zdfu?QC9M4v@m@y762ty>k*^?9GrWea_`2_H=5_Mrb)xb*7gYX86L>%Pk$6=c8wh30 zQuU1l<}z5Y+?|QJpD`w7EQlLw*FNkR{(iXJv9Z%66M{LAgd+-@J|UUEp7suOpIA6n z{ZqDyCmXYJ_oUE*urEy5yh~WRr$;~4MU!YRT5`%hg#wPG?+Oq% zoRt7m5mH6LjD+m;{;4!0k-S@kO+E1=ohk6%lnqUyfGC)mKuqr+Ni!OhyI)$;EXQZ@ zR+4G(`zyE~#RogzUm|lQEjoV^xZ}EoCV_RWeVk<=-f>kEjDK&_^M`AvKTG%j`|Z2F zsWa5cYqgsZc`|xNg}X-mGp10gJXY#XPEk$jv1ZPk9zAQ(Iu@FB9+5yBBPd;78+E6W z=<5QNF{3ggJtFnP+4Q^RxrqF7_ggfj{dm7??d~jK>zZc)vs`ktNG0} z)u3-&_;6+Hk2@a;9)D7Ps{8f7t@dH<3ipp!nrRR1{Fl=p@Ur)&`iA$*su<<3GunI+ zAvFadAHF~Q@2^)9dHK|D2Jg5HjmBQ%vVk#R?L@Hg{!7$~y6M4MFSd^h+$+v+D_ZCW z_KpYXTu`(~C-T3jp{hWpaoVhbf~w5*pPbEvKAZ9n=oLn*-bf0nPH*Ye%P)9(#mA&+ zOHJO+%_B+wZfHHr%kZ1@UoUCUXjI4b>Nob()`cpdQlI^M-*ID==(3vm^ThF#>N&{x zZxG*et?VaXzg|piM3Yd@cTcVFfPDXkKTW0i64m%m_{LB|V^ZSX=WP%FaHan|iM;V7 zP|^6gwxWl8c9ShnNs|N5Iq0dTy9qJ2CXPIDBjT3oc_Z)H@D096r_HW2Pi9_=-i(g> zv3~{s=LrX&Mshvb7^$ehyi`;qmWEb1!5!z{23hT*i~+Nj|!l#ywp_VA1D+2xhrxBIGp$LyZ|^}6=C zLYc2o{$;yp8`vcArcc0EBS8;nU}x2Mh4{U* z8#m_7br%YW$r``TJLxV2Hj()OF}~^ox3{^`>~Pbz-EbWw+7b(~?J$1ZAXIAUBq`5p zSt;kG{`;*b>`fi&=11rJ=dj@SnTStbn5|LiSxI>YY-EXfXLj&{W#gq+z#mtkve!)PPD7eWn>iXnm**L}Sr{^} zdyI>m-}6?Cdb<9PX;ZZIXQlttYN)OK-9n-KES)>@(5LX83elg0PbEgQqovfT-l}f- zg#s)sziFi8nG`}tUacoyvRyjRtC`ZdepK=85tqxD=lcfgRbMx$=UI1}HD$$11lB-T zC+Z(v8=ZnGg9f(;7^%Uq$sd_syqszFWnm>u)3Lk0XGZ6$0cFlAmqbR=lL~FqzR5o~ zhn(L77uH+eXlMzz9G{R+(u7`de+Ww-yX*6iOKkM>?PdqzCtlArm5Zz98n4+Fu+J-I zcIsBm)WqfU%7a0Jw5pK zM0P#Wd3^bzKs%kMkzxMDlF9kXpzZ4C??}TJ9m$!q*K-ZDt=jgx^L6JvUgi6v%UI4+(R=(?W$p+e(&&$rU;O5td$;8rQy{<;1bfGy@cKbf%&LK9bL~r|{ELT7O@%sd z(nU6AtKSgwChd~lVht6Eo` zH(OV!GRiIeI8K*ip;?-Ab4~85m0*XLJssY9y{1gp?TTFWYYknk0F{$z#*@ty@ra$-i+yr+6x!&}l!}DF z7s#HuRnpH{r|W*#@Vd7%BI`fI8Naw&?+8VNG=)Fx=|a@~IK}vQtIND*9M*pBP~Bdw zdWzC>or%wrE#$mk-JvJ3_s#2ZBckqE1@Vo9|Hv1nv)&LLX-<5-+RGXv|+ z)$CqAjm>ukKP^tBZov(1!mA$C*-9&Vfk5^@E2e7o6q;o`TYcSNxvuF|)ztYne+SSF#@29h4d)6R|fKEz}cl&snJ7l&*hqZ=6fhccMjsza7%~ zT-4{_qttizooZnXEKK*x$nKGKY51>x4|TLD zdn7GxF|(RV>+f2~@H_n;x@a5rNIKlt%x_fPf7jxNf9v-R83JFp+p9Ff+jqNCU=(lbSH3_TqT3O8~{F&;tESyk^Vkt+W#`$=ul69wYSNh`b+ zG@|?Txk3fPmx(XRgKPq($KCVjoyK$+=8wlcYcsS8*s$No7l~Nm3U<>oT)?sFr72-o zD$}>P@EbpHn;Xn|N=g52K32DupBSMuYFmunF{Vh#d-j^Q#U5jMdd#!Ip(kw z2nq@h7(fJ%xtinr9_dDC>CJIyuWXTxBMmyCRx=&gIOH@FeU*^HYb@Oi^ zT6ZSy;)uuF%BwO7i>kay7R9KXv<;_AHZ2>Up4Yj`+`VBOuVQ}|54|4(JSZ1)0vh{1 zi?N@%?BOT9gyeS!meSp-x8QACYG6ne#p$JY^60*M==~-yjauOm+|V?=K=F3wMCn|`&NmxCl87R>?D{a!sTuvK0t3K z(hhx1{8Zc=dY$=C3(T*;5ZUcdjtpwoiC~ z)ewD|_~AqEaSCC@b^Kxn5AfV`81T4~^d~nPdD&N7gO_#Vi@}ZWzQ0y_*;}L7_%5@; z&AZ=Y@PLP}`HNZDolXm$#}%;Z8%wrM@|LXA*0;7+C9{u$=IynHq`m-E=R{f6rXXn?LVeV#v~c}+sB*Y?q_{w_s%td|8U&a zsmtirp~H>uAf)`Y7Q-Qn7Q`Q!RgLFkS(3A+F;@tejbndX{7;OKBZ44zr-0dT{xxqm|^{ zfrRaWBVXT?R||ZG3u*5MaJcLjsl0}_cV}vJHfPRfYjjX4zhA#7Wt>b;fD1dv7$b_+WqDVY^z?zB$QC=_v(i?QeuI zESq#|eu#+Eo$bj4C0zZX{H8kM=tUgZ=BP8yP}k7^5ktfQyn#1OMc~dPPAqCf(1xw( zA8e&kl#}B#L5_eezcHv*G40C3{V{))>8JPF`wpYK+8l>n*rN-bJa?ScD`gFf?c z$(|YZGR}JNj-7w8?xpd)@Q)F*yKY8b4U9@e}a+pPeI6= zK{q|lKW|LKwbK-)-h@imKigKCBK#ELh8$j!<}v<7ubwF7{Z7fvI{!0CQSsedldI*z zHsxxq;pV`x+s!O{Z%xA97$$$le_A>-xsKT&vhV1vEt!63b~O0{l~VV%7A7i}JE;?m zQq`QD=6D<$A9OIH`z}aGq*Fz${7o1X?7Q%G)LFs#^w_pB?Pl{s7MCZ@Wpg55VYlt+ zqh@b*Mce=Cm1xbef|k1S@knIU^nU(Gk9_4V7ku|w^IfTO1MxC>>tW3#_YdDydmypX z?#(snN)P0lVy(^OdjA}oNV#Ad8bzz=&8O9g_YuF?gP=`_N;&z(RW#y+Rg=U}4%5h` za^+P++I+$lRUA@ffS8_MQjjv%OnXt|(FFN`D*QonJpEuz>#0`ABMaJykePI?76LH% z8g#L?->b`MO4}V|!Yw?=zZg9YYttZXL0`gatCR^6&d$M2>zL+PGx$2`7{(v^!+FW% z;>jy2lm4fV)t@Q$;{fP0n!cDD&vXPFi zZLhbrcli@$K)Zv%Ae@xH{jfD=b8GnCgAuo?x>wLTXomUVvz^@B<+%_$#{9*}b3eF8 zSO>DOR2-@+XDMduhR@u9^&sp!kX7OTvFRg}(FMAD@B?$s^* zq*Zf}c37G8-FNKA`=vz&@pCc<&yZ*p(|U_3^>;zq_WxzW_r(`@O)2q zcM11L${jHK1y`!YhnnEdhc~pXBhCch*JqiPA8-bj84O<6JDL3G$!=2Kv~=Hf`+1X( zO|Naprg(CRtD48-D^Cb7olKPae!AKpF=oWHCCcBDi0@6)?i_viN9TSH0%6nGO!`EU zX7R66Od4{+Beu`_B-Sfk<-bx>6DT)Fx)r*I#^sMiR{~DI3b8)KCDXQ)v$j#a3w+qF!F;^!*n(%KL6NXYugQ2Op9SF04rej75%48fjk6 z&NL0bfM(TtbAkR{`&F|q>70eOPifc;25xmUzuWsb#AGo0^=a*!o6Z-OKU91O`Jkos z!^>!Ot|5vpB|LMGH4bIGo3j%1p*wpe{KH8@ROpA3#;B+d3HJsc8Lu+^drzOj_k)H$ zh2vj4eTvqPKEVV1hTX6aM;U|N#;Xkf2I-esQ>Ge{8`uToz;X4)N2aT@4Gh4Mj|ZpE zs%CIJ0ZgN4UFe0V&{=NDx@IYCo#>}ObLtr~XOW}oMFPl6!Qd|_wg&#vn``eG2dGaY zSnB#$Bp?zBE8p~NzqdS%_~v@Mg?J0y(Y+!J347IADP=SHx(nhnedvMKr*-3w8V|rH zDoTTL;SNSl4rN|Dw!FT@Y_yDsIc+5gv8K$M7rvq6RLtKwU8O~2vt@6Kf4X%`tl-7< zImKu#ypn6s^GMZBv&tVTcXw~SwY)e)47Oev!#sHUc}y--7B6#!EH~VZUta9o3Tdlw zRWPlY{62oyFYw;{QxoKzHWgEaFFtv`C<*KRS<(CTW@@`)%S-4I zA9g;XGFA7^Ty79 zl$*_kOL+|0xX&TCfiEYdqQKU5fzJEKbc%M&3X4G+(IoIz=}V!;j|dv2`2OmvS5dF4 zyxQ6{{pwVvw!mQSWx(S z4E^;BI=&b1blV^D1Gy|Wgz`LYeO<;yrq;|0ym(pNo&91by|rEI=I@);CGEl~`!Sy9 zY@P`TebU|E>eCo?<35P=R5KYGrrs8US`;lN3TSKR&2ut1=W3T}@>%`l&HX46sKc6n zC2^l^BjujsF7DKEX!+?lx1)n=v0JDdeT99Q;&@y|;AI;nGD17wp1wnvETUr;)g_1w ztNlU_?0h(7ZAS_V;1BZ8e%~7H{OaGo@^|iQ zXIsD5;-fZKd100tko~ATIv>iOuwJ9SBy81}hrm;@J!NpT-gs*B7Lkf&`O!UdFCM#S zeD1-oAvF9>l09_eMb$A?of5nMJ4nV}eU#8r@%xYb|1MwVTW)~d95t?+^|Go;=M}R)!<)|{2i{R2 z_PEdFpMeHrRcpT#_wHztujXoUZ91W}>yyUma!ODJr?9`zd@QZiXR69vjn%{|+awJ` zFzmx;#y;QE5>lVX)y*SbkD`m*17WO%zn=5Ez;Jb~zg;68UdOl0*R|s6wuK|&h41Pr zhqtNfTuF5wF!1%%S`?OmY@5En7*B9*;#qc5 zJ2e*m{)L=8(;VN@)jN0Q)rbCc{BPAj5cv@y9B4hRf`hQ);i-~PYaPx6b)OCC2~^MD%6c+)Mf-~XiA`J9D_%$9-!`~WFqbtd6ZdT?IvauLn~r?aA;Hj#|Nj7VleI1z8r zvY2mZehi044diJSLD(Y$QaK|bplpLEgg055PtQp{f(Rf!q7^ax9>tJWMF%x|S5X15 z0>TzvZYe#T1wq(aN!ysJnRz0f&6V0B>mYAfB-O25eO;uSuOX_`EYxgVrK^-$;4`Hz zR^O*@N&bP{K^&v$F&8|Lkj7RsQhTc%+VVS6vEq(p#nc-~n_zuJFxmhUyL1nd4YefI zL9dYpp|+%Ss0pbNYE3GInv*)A_N08MG3go9ic|$PBlYSP5ttLNVyqMCF({HPqJ!We z>4)vI8Z6y}!xUzvj_vC#NCSHH1cpRvObN*ZQBN?FG{hEIrIw=L6nU_ehZI=CLkTQ% zZ0BoC>gz`k*b{j$^`u*fA%ccv8aCYOtaPEYwR8d5TCN3eMQR~hQCg)?xE2yx)(wXu zx)IQd?ow!JHxgQ&0EZ$I5KvS?={7t8xm|Vy-$ooEwkwWGw@Z(Z+vV)=Z6rHl8^vBK z1ZPJIm6gDS5G4qqijq>H(h{UlxdU7X>3|SIIh5AG9gsC;v+x?kEP@w4TgqEDi{wRs z;k*@K1aB$0l(!s=D>%VPCK;ZzguF84`}q8PHwkIJlzTl7U5=~N%UbaD?a=%5ZvbV?4yb?OfSd+!}^ z^}-LFj+M89V>!2ov8r1xCPVs*AOV(GSCk@V+&5l$X2VA(B!+m8?{ zvWDUVR;jj0U6iZ?-eb9~Hj?_>H^S!QZY*fn=I^iu;-EzdTCz!S!Q>t)N(*t&LcXEpC$5oD6aIu>;1? zvc4h>VIXlXp5l6D_pgSMdyv?hb3oTyabVV4d?3|ZcM#m0e!$aPdf?KVf1uG@b#SLQ z`+&8#{N*d0`B(EunFxgh_@G<@;x)3*@*8&fu`oeot~eGPCevH;vJ2<%)l5Y6w>&!{ z9+_*|haG*aPvD%ZBguw=6ANE<>)C&`s1yCI;D9(pKCwLiW7xtg`WwuQV1s8{GE9#= zj>3pP&V*c_dyD4Z`i9ot;$Yfx^vF06uClmlTOlc|Y*ShcZ?dwOR(t#i;xYFTEwsh& zQ5VZAo0y-E{{*wn(V?ZcOgst>d_1b-N@rwz6o0{$OYc~rrjs6HAt`f2 zH1*cSCHR5F8>Hfj(#LHWJq`0|q z63ZNzSoPQs(`7kS5sFNem=!y9t+V-8t53D^tM1P@NJy000+HnB42fSJr(wb^&np%XXA&I}J`x==J_=EyJ~B~~ zKHwoR_-w$%=}pya0(0dE$;_7Xn5+3IOu*T8Fhfq+54Ztjv<%)6L?Q@QBG4Mm zWzbAHrEh`LQ(CIQ!Me6OOCrv`@xwRZ!m2#MGPY7n0>~-l${X?H{7bAs!3l*(eHGus zG1?_&Bxa>j_QXFH4Q@tn=ROlZ&wM6-67(EHUHLOs6u8NQ+1Z(GNRKA+zXSF z3G~ERRemBsX0~E4erM6)x!qioqhn(~S)&x{|GrdRb#vOI@(%$za~#X|{elkP?Z%qi zUd#8B-imzw%B9SzsObb%6vnI)OAMR=a{k@A_tNch@0?yw zXYJ+rrC$jIycvnh-BLUXdNV~+*-jE|uGY)i zQf3cInv$pl^4*Nm%h^&Y3Hmq1T{%dSY_8YK{&?EqO7+Q)cZ>y|twIwVFyn=041p`& z7f>t+Sg9CSHI=MvMALp3uF4gVwh7F^I#qI_uY^2S%oLEq2AX4ID^<~YA+4?V1Y{Hf zC$QF)Olog!%j7~3S1K`cfz6h=Rr2~F4_GR<)JA9Eoa)ZsRl0y%JfI$Q>K3l!Gv!}Y zfHI$fdC+tj&5tRTy;9ko{t6s%59)HCf2&w}M-}Mu88r`3m$&9{E1Xqz7h_&|6dW|e zfM)t`x^(GJDKzKUU2_s9?&WV#uB2Lzajl#shE;+ITa`epXMiT3aU&_tERdixS|p*F zZj$#*0!eS?hyrZa~ z#XnE_FaJUH)Box2=lxUC&(>w`TjHS*H4M~v;5@ckMUe2WvWUbxBb}%a($&w}Wwuhh zB)>Zhw0PiaY@doQVY#xFBr>C%2oCA)XYaCDDOpkg4Fe?}c!t#NeucYuT0E;N4* zz4Hg0Q}YLGQnP{9E*h{%%^Yw`Ef{b}%^mPdElDvtyO-j4mX~6AmIah{Vam0$jFcN^ z_fu@!M+}tRg6iQz0rh1=LG_3r2xD>dVuD>XGOE^{DU{;Hg)Oe8j8UHnIAL z!M)Tc_i=eCE|DXH(po`&D6bb$Q*Dd$v4XFQaK%7l`>&SicK#+PLz8<2zZvhmjW0{? ztR)ygLwiBr%tVIc%NaVC31U#-P||OvB5x1NEIJ1Ws?exJp>Gy-!-wTEou>r3)}6G! z7Z%UZqVe|>vxH@tgH{n{FMzh*_V-{pd97G1EdG|QTp^P|Q97nUo=eHL4$o~pJ zVg4-wMGZV%nU~_AIWhmwM@(7NC#7!t9#h5F z!#Mi<46=ZRo)9T3@n^?abmkI+79~hA+t-h24=Z6@$=(LpKtWH`mCgD)U_xW)2)BDO zNQvHJ#~0dPz&PEm4Q46G`%Um5JJ#-F-D0K|qNNDGdi0Lz+aE)V6r{eb0Z-%g07UNX zvBc(P|9Y|qFMmR|cSfI+^0q<~u{h2!)|g17;a7Y?9s+$kv;M?+%3 zWs)p#rX(5MC@B;tLE^(bBDvuJ2;Yh6y?m5KVLf_G5k4xT&>X#_a32*?n2%a1f=4wJ zhNFJ(%w*&C@d4Qdyf5Nc3>eGW<3=#YwZwAoX!Hsky}@N9n?{bms`wTiL5TPE>ZLhq z#^s00B;dbdmwVV^+1nrC3Vul*;jdy(dz493?JatFzogmmZ?L01A|%H4CwljPNtNJ} zup2!FB--{4z5HJ?4*0n9@JqvgQFJjh5HXyQ2meupVuqk(!8$!Qu%|mX2FJk^`BX7I z+2T7s2ZQLrqc25fDHaLJVb{zt=pF#RBMTKv1Qit4CNTGV_R(CC8Me{f!S|~rStHRe zd*tTu&DJH=(ln88W}?+0WADmzaEcxRT3)Vi-<7(=+z!^j>3Ili`OOb2!8Kx-gOzZ7 zXwAsdnMtLJJJB`}ADoj1d$;ZUq!NlXS^;8;OGb00%x`RJ9N;8Bqt!%>?a-%+g|`_X_N=qR(F z>gZ8F#}Trh@u;hx|EQp!_Nb-*Qn$5lj+YX6@>IHG_*A)L>{P5{;#8{R?Wt17 z_^Cw4Xj|#R#{9Hk^e;kD&tH->jy_R65_p`c+iKDIu?&8U@4}dMs8^lrfirH9drvSJ@+aaYia@OVnXL|MT18EySEUUnSCxl`SH;}cfw6jh z7vYEBt?=8}EnQvPEni*VMXus^QL7suxZxTwRj-2(hImkg;RdL5Xbn_8v<^bH?3G}@ zkYxx_WMHT!KOum~Pl)y8P=X&hl(b(xkJMsdNmm(OeF!&0W6D85T@oid|tVOhk>Gm?O`tD35z?1iciM}wIUiMXwoymk! zhCLsmF-$9wan(m;;s|cBr%${N11GWow*pNbmCEd;5UpT_i5ELg{JN+HhZOTbqRe<; zoF;ceI4PnYmkix`M~9ROHgYZZOoN#yx@zo(wiRRSsHQy$NEpS^gWk}(V!Wh+xEBOT zq_}%f8``^$m7vP^xFH$!vd$FAusvkcxI-zMp-U3wioo8d;GB9fiPYv9d?;p`yoA1( zTHJcSUZDjKjM8Mlo~5R@=KINp<5$aH?H51{Qaf8S{ltH*1CulvkY}mA(0hJjg6pfu zqP<=01eqPeP02;eok=XQoOeQt&#%26PLuaqH$=AW)nh;H`AvP=S0D=?=d&#?mMDi~2m<%G&k%2Lq445-=J#n1uN01`>5u3;^BsI#dM4dCOM7lFz ziarCx*_lJ4#u+$~^(-n;=?s)8oLbZ`GUU2)&rc?5tOKQm*P5!{7bGf??MSYakVL`M zf_~v4mzDHY>D{p?R02L>s&8MHs89AG`BEYiL8&GEpdmMdd#f^_v0W59o_#8JpMfYr zHYHuB1RV39<-vr~ZWyE+O4pBpP!4#9sVDm~M0K(=$-{*DSg5f9R_ACrXe6uXCwZw9 z%z1wr#WYS($XX}4Tp($fFdbhNa~L$1mGk1Z#%N~Ep_Lj7VMs^U*AivO-%P|{1{1oa zQpfA@;x`brO!?a;mcecrrOS-2@iN*=nQOrgCh!5qs%^VGG`pD0370%JHA|jknDrcO z*!V!m=&3RT*R82;Mh&8<31G_{y$0>3P^OG`2#zK`$83#tLgr7wx!jkhII{p*)>tZJ zc2m)U`@xiIR&%UkW0jD_P31{$&nc!Xz?C(Y*Id)KvzM+>e!}q{?#vWA9hTKah#Ogo zrN;xREV{kMOxxkTbPafuLm7UXiElbFtAGF-8IPsL1Ewtc84ML&<$bNkTUpv$48_r2 zX2ax$3C?OE#*P4@4DWd?g1>rffKNK6#?v2*;mwaZ@zTet_>f~JJmAUjuEzp+&0`&W z{4pJ#trrpfgo21hQSL`~QyxSEnk>45QW0HGDUKeZ)a~7)r0+FQO84ND{Jj^Hsy)Dx z?LDQG?^Sx6-Suvl))PyU(34A((UUqC)l)i`)B_}$p2E4bp3J$J9(aMn7aq<8p1zZX zA|#DqV`=b!Binn9yLQ(uQo3Kcn_~s;#neXBG!g8r{ouMI+Ao*D^%dijbr`GFn29s} zA$!Di6_b+nKGv|YK+ouhJUiDLjA_;mNu@DY&*X<(30D#(C~JkJ-B_Y${6oQk>mSCM zcKO_sj`1|uc!bI$PsNc}x?ie*gC6rR3(#Zu2#*?-YbN~iHXJLZiCFI$6)udoAuc1{9z`k+t}-(y4Mt{&-3Xw@_5d61F8PP4AXs>W%LDb| z#=L|g@-GuMm}UepV|#!Mzw4(d4HK>AFetNQ0%1b3N`h~X$e`))fEe2YTsYag&YWyg zXYVdID+-gFm4r#nio=v<`%i_#WM(B`;8_`pC|Hyt3znovg2gF{U}*}V#r`wl ztq2sSD;CQ%gi&A|!YVMOO|>wlO}8)sR*Vr4;Y{aKzZk;_f3seZ=tr(5N(2n_=f5ys zv0VhD7~sLVG_l_py$HXv+DL38nu#(2efoE{14wWl zK!WoC5}XH+;5>i?2Z$Ta14wW&KM4guf@1**US8IQ0TK-XBsdyCZZsglJpc*b3P^BQ zK!Udb65It*i{VZ(7F$G{Zq=+Dk z2E3RDw@yy$Ga;LK+hU1uVz9;V30-wxkh&pSS@fZ$}<$ECKM1P9}Ck06R9dgIY!Ei>8StJDyn{0^!~cI96W*=o@W8?0^7z3<9(@ z#9?Z6s;+DZsSl((+4Icmu#i%)?QyKN1o$yDP}gWaf+rf7r_n&X(I_H48sKlV8&Mh! z2r@L#*Jv$*D;gN6J%D_-w&9Eqn{ih2_B-O?-~{9yc=FWM=>Z5ZQKNx?d+;URYi-f9 zoVODZ|E0{1{0q03N}7HI0Y+*xkZ=!BVn%C+p4GfVo%pBI4xf9iLyDG~M!e#JvdqW< zsRB4F!VCj2I3xlv*&hD^CFL&E3 zQF#e)WoV$fA%;`Ht?*@hh*KcyCmz1GhXwsv+ir<+OMom}0=j!CigXbT4A&4K>r-cC zZb$&e#ZJ6@Z4OKNi=jpRbV6~?NINvQzZ&|aKNpJXM?t&$OQ0qF_0SI3J!m})4h7=AeGgW--2ltlhQrFXU%(2t z^I$dGPhlC`l`zCMkoWB@*n{oIu$=8OScSWhfrX-My$rDQ;$X(|<(m;~#vYP_167YN zcJ{!^^I%2pCWH1f$S4k*>G?4yG;8NesEwk;s$@m^?>r(TIWTc4-5p4~YguhxIj}+( z@8fV@D!&QQdRV@kZ+|EXY`pj(;6UkQ?nm3EGnm1#X*8(wK83yW`L;u=Gy_KqHhm0O zcLmz%>DNFjwuS)q!^KpVv1^GbC#}tT8>%gXK|5k6!-6C(} ze%C>Ze)~ZO;DBDEejw%j*Hf?c1BvsCMTmsIn9yHxvrpH$<1Aml4@Lz4gP zxmJ{hq*o+{#8woBq*i2xBv!yfG6q1#4P?_K|66kzD5gmph^L7e$frpeNV{=@P%ZgD z#Pb}cSMz}_SDpjbFn@MxC~tOpD1R1{mN$#l7y}Z%UJxt14=lOJXq*wuEK+h%UW?NY zS)Jd3RT={V9vI$Rv4&dyzMUOairw7LDV?mw3ifdb(ouh9$ zb1ag?(b=bGyDe72kv#oq%$LO932eBwB^)?TrjcW*q)XS242P&XfpiOrGIIhzJ_Z2! zx~NB)wmYxHpi%*Mu4Nt&?sZ+Y5^Z3;#fECi1Au(p(j!OPxEpAlK^vknaPV zEi$mord)e1nkw(b1ps*-0OWZU{vn_W>Z^2Y`GZ0P=kR$oByt-v@v^2FP@e>xz*# zu+?fuX>kHTo(}-|7y#t!0FcK3k?wI>F~$K)tw>Y?CjjL60FaLXK)wzDc?^)~9ybFc z9I(^cL9ufJK%Nf(`4|A?>j04N1A)GK!@yV%SZRr%95?|W&j)~f3;^<2z?cz$l@{i| z0#^Wt98hN0+MmLzyn#gb0!SV^wJ=o-0ZnaJE>rkhzL&05gqGd)FSU>R+V0G`DEO?GRsFxO-jm(x<$&6u-5tS!^R!IeKlBNQ zDTS-r?l8l2kUvHG?K*=MnPWpM`y^l@ivCEVa8+o>LSTpvSE8DV_21vPv@gRyZt}eu*#sJJ4L+IFOWio1FNTU?6~m{QSG=1 z3~}r%@Eg(|{VH6g-_hb9Qo=>4rE0rVc$0)`ilEDAx)ylJ*|sUzf=9>ZYDVRYIAx#{itY(9l5u9QSA}_n zqdd`ZFIjp+246Q$E{~oKq4-93jFSiOb))2zHQ(y}laT?ojib!IDe`HiQ@+~u5DK+% znAUi-&jg6^D5=m;R@SF}SWx9`tszdCDVaab((yT*L-p)K!wo5XPN5;oPGX^SxQY^Hyd}#t2^^T>c-4O7w?LY??oZgAC2 zkSFm5wfhdkDfAolStqs=hIB_Bg=tr1^{X?|*f#2!tY@Y0iG^vJvikK|d@5%;Jzxms zkMWin?O^3TcsPY=!;i%p+{EZNK}KcFVXZcJ3eyC36a>yM;@nivTzWb}DB;n5qvQqr zV8wpaaEkE8YSu~8#1P#PYhjw;j-bFf8%|60%%>+RgpwS+Izm3e50>wPhEoJL3|XwB zo=mO2C6}xXBKJX~DSR7-=_ipBX%~<53(r}0k_FCna7U_V%ssoI6qNB6O<66w+F47( zff$#;47mfJnzg@5+f?Fo1r$W-Hs0Ehgk|in(lt3C_T(ngKxGDYBcc4~rjGyqd#9n4 zL>tbM>oex~7%Ac#X>8Vh;&^P~IUVpua~|&aPd?o*h!SPI^{cEhO6BaR;lPe-aGY$I zG1qPNTet9BT{Z=kwX1s8(QuH$l{!ow%A8}jB6Dt>r=J8(oC}tvn#^xKDLet=)D`XJ_>Y0<9D?79J|7=ZUpuSL{+2nHmPY|IC(t&X z2b&}^Gh1YkT)EmuMm{#cT)5gNMrw_Ze-=b#Mziu3(-FhDM%}eV${Zxb{PEWuSIloc z>55j9tv4Qt=e4IJ3P08y8QE&k1KwYF-wz81;h~NqGSL~?x1(h|v_WN07;8fCCXRJt z0TtPLva_Wsvm+|9V8ZY6E;m6n&r)m4o?|I($ zdgjBdnfuzGX7*ltX|G!v(2u(vr{`neoz?8Zy1munLcU!F5F)>3$Gb+Kp8URarRM{2 zT>%h6ctHd7LtI+{`Z2Ca^?VSn3v_*myS=T!j^JG&Fbcez0sQZ-7EA^Z`usP^^VZ<2@OvUeQaod% zt{))5VWV$gE0>$^Ai+<11conwehszjG&WOkLHIo!VpiKNi})K7mP+ew@r4rLFcL_Qtg|l? z53Cb^1DAgw;7y3XrO*h)0$&iOlW4*003pnDaz)Ug?mF6Z5*-*3U>N>e3eRg_BnD{I zt!fSSQwu_35Y7O;piHY$gU6V>es zpx;C-2o-*P^p$mGy3(0~BIHhSx= ztN5FwR8TfB>9caDB==n%PlS>_I6fk&?KVdI4ZHkV9!~`Ex=Q!;sQANn@f8KR2rFGw zk*LT5tN{)x1m=9e;)#%6tP6cp~K2FM6*~-J+&o;pyKj^wNUKpB!iJ#Y zV9?mJxZBq+q`TE?b>Z0Qw2`TB^|bOnBL2_Q-}ahIm#b_#*Ra z*#9XFesh)^0>RS6{mZq(4rtNDHMn7L&{MH_QDkV>i99h)1d1iX@*;Cdqh_c6h5na> z(6TL8lbk2z#6?#7MZvFC=BkRXT{~COiqkhzZ=_5^2GciisT4uznVOX9KwZpC9-RLq zu72&j9MF-2Oj&^o(Tu_~x%U6YJAdKTI+8((VH}I4a1ZCxq|^pxGSc^m3+1NUV1d>t z%c-A&+VI!5s)-^D7ZU^-Wac{ig6>maW32_1&j^{W{>*x{?cs2n31u9X4=y`ZCJ8kt zPQKf!1Ci2xzbjIb2Y_xIT?P;k{Ky&q+~pgShuxknuxSG z&)ZSOznt>S+JIZHhj^KS+5O=$4o# zII@FBEae!(TVzbW9Eqin;ezRyiNIJS5Z`(Jp5b(&D{5@w%&R^xrh)8P+y=?4vwI9jqSMkYjo5g5YDv%A1=ogA%9t#ivs*v-QNQe9NZOLQ=+RKrWT_P%1r}7t|UE^i(#Q$ zH?0~KnV~6|{v^)-&x%uKgW|coTR_JeX??wQMKPDVu%=MV&|+Doz?j~W@BiT& za?s~Mv{PF#1X|O|5+Y(Z^C@OY86r(RRcI(SNKRCOf#O~=N0w2a7!&!sI;{_dL-R-E z7Pb=l;Lan}2w#DqN|_$n*+1=?m*#27Ems_j_QRN@k5U$qk1{P*e zoM_~P_le5KA>)eu&(PutAbgXYg5hn2e5nSo9OXPayL34BNQ1(ICR@at zsC4an*v6Vl5!SCmHe)W;Oit^W4jk8D_kkg#ILU*Sptd%WuH$-CYNgyu)Xl5#C#zV> z2OvQ?j5Lhm;)35dX_aZ48NFywE#=o}bLEhUa`;1){Q5;ex$tn4BLSkPV4zgurMU{# z@AZ@bFM3L%lA8;!B@|D!=A3}$oragVJ3+WHrdeZl=Z!tm@(R5f6|_e`dYaFZxWx!( zx|;>w+UYsNB^?4Bf~bV|;9oMFq|c9wiDZXEsH{Ln_Dqe%aAY9MFB|*`UEz($5kWiX zUgXqeq>zOt(gQd$z{JiOjPu)pCx5TN>dkX*3uT-u&b=RC5bKLkd|5T}miiQam%e-( z>wCAKA+Ho8*Hm&>&=1;)hrd$AHT$$28C zVvF!EUp-3ZrGK{H%Z3QFnlW?$zOZYpSiqQ%!98H`vYOmHzw7T(DGH`CbgH-K*Jt3) z!pAwAkHv~B>{87KTDr&SKL17oxSF;km?5+*Avupi(z395g*JOz3!Mr8W>RE4Xz+f? zQTO5!w=YFw7!@-moVxuFEcQPz_5Z=O{{tKT56u3*FvTLDJm<5+RP(NKt~u5vH4#Ot zsS>#el*qi(>gp02r7e#o_5%hkc_^(=8Fnir8kkX%FM>Z~!&`80rk13xsbXpMp^tc$ zj6xT-L3-5KJb{I2A(NKd^eatQNsOi_#ku77f@~*%w_t+bjb)3AQ+Nz=ypib-$Wl-e zA%*r(fz5%G1%7YD?xIQ^c0z&8kC@Wt3DPsq(HLTx2o2i&EJ42!!E(v2>*EcQ-DGS@ zCqj*C$yzAN-UxTY!thT) z+gEa<<%wS=ag@A5%ghm|{jK051?ih*ODAFMMSk z-cQ31C>7Z@qIIW&s$|hhjy7J9e&>QXBbMx6&AFX#{Km{dg_w`xUwjX_NeC$hLNp zW7^4@DjKEE5%mgGtgJ3ajWjiG%km`|0~MS(rwIuwS)a&O8rU>;D-;pSEYZq(bvX|S zgAEt3E;#wM+m_3W(vdHW+tXIZ$YrI0^sT*yP7SZk+#|3ZDms-ST&R??nl$q34;k}1 zEt1W{VMa87o9XGUS1uTp#B>~1hNbx&YT<3etXIq@4_ujD+{1SX`t^VC4iQE;f(Q{3MJIORVm~xEy{R#vHv=dIqBo3O~ou0U+hFB$Psj zjR$_omlJMwF+qpLNRChe5R_8@!Ung1;!w^t$n!PxtpKwo|L z6tIIxTq#rK@N?Lsj+o39HA#8rXexQ>{x31Hrf)DR*u#p6@+WzdF;G?$rOLyy?>pY^ z{Kq}EwQrv*hC7oZ@&K0+j{NVU$1_$nV__s|Py{S!U82StNq<=owJf&Yw@~e+63sI; zXrL{AC!N7jM}cEpzn`78Xc{fJew^StiDTvTK#(gVZc^?t*q}wbMy5aB_c=lsU;Z|l z&XELOR*Zh+(%w5uHG16|KrThy&W|2N(Z*Fx5zEhXZ+nsp^3`&%IRi#0go306@Y)9u z^F)_424x6xGVaIOV>xb|JXFiiW?C3L^W<7wiLlR5W?^vUl$4UJ!fcEWE7?=*n`gPe zlPc!2aV0?ub4w5U@&|H*Ozu&B+wke!Vh9-Vov|S4YfYFd9S30$JYh(HH^ELll}xYP zjss<>f!48HS_ztOpW7xxK`)%95(NhYOqi0b*)UB_sIHtPrCglhu?DnzF)kfZj~Yz; zH@hfgK?m5&NNT$H;yai72NyNTJH}EsGNRJ-eSG6DQOP)qhNhX~N_?i(tljXEIXxl# zTQvzW9DI8wRquNmFKb`gQMHVs$KS#wCb$rXw9>#*22;rmaRCD93&i?tPpN4;e4E|FM=VwbCf9s{{^XXmzqH>EI(&kP1vZc!kt4LX=M@lIh z`)X9JTAQ!s@>&kL41XUz)r{gbF^!Ebidop)LT|72F^#$1~S83?(DD^CnQ%te?=}GVEKe+c(P-&H74#?V*aME z6{sehxlbL*oy85;gKyh6TZAp4^elziqra=~d;oHG6%#)NJa;uvQD)H<&G!CUXg&BnfY^kWm<*#a0 z@+68qCwvB|IIJ9;EmZ-uL*)z#bWvl~z0_f1jwN5*`5g20y_P$6p&(M0i4QmcZ5mXD zpe&EB>nAC7eW`ylh@^Wy7CRxIzL!*1-=ML*cX$d`+Yw`R3%3$E-T~uzJ0m!~y&#y5 zh<|}`-nGxLz-1g&)``HViD{PkTW*2PkyITT&hf=(N7~Ye0x(nogPH~W!kn~Z_c;cd z?L#DgL|s_kLqyE-tFFiQAiO`_MbhxXfFp2FR3*}AY>6!y$o!I>Yj#v(cZ^jSx+lSj zaEL$a4qI?&HF3m@00O&?uX!qTBd-7f-Fg*e{y&Y1oJa!-zzLm{@_d+gwt3tsBotwh$Z z4Qkm>}p-1`>NUk*%Ysp&k7tPy0yGTU6F(QKLT zOH^lyG=X*y`>CtT?k_RjJe*Tek6;PKZED->Mk8FEeQ*{jH?-zRt%582H! zunDP?uR2GRC!Jp3W3<}7j0mOfixw&qud;ALTrN(=5|Ujdg@bB49V?*_2X-k(sdP8D zq_6naaF?(;BBql!DsoV!*AGCUOo(*T!So^@ZeLH$Pw7ymxHt8FrQT6Kt!Iov1bA*OGi;DOl;MH5?7dIlI--kpLgz&PW%&2QK*&NF}5% z5|gCSEptMbsY!dh*Yt`Rv*@%+Y85Ss2{W;&-elPPld5(`dpR6mcA=@MsUR00M}rVb zPRWp^oO56S-(de+#6tp2`l>gDE8Qct%ymtRa17k zl>RxfSuyQGr~Ym{y%IQf#e@HSZfz2V1 zv7kUFF#Bd7tsT1cp0V(wGY25BT3IWR8vWeXcSObKZyjtF%QN zkl5nCHhPP7OiU88Tzkk9(aXqx;D-o|M|={Gdt7m0vBs8L4BhF*m&EC?DwUg2PDh9d z|M@ZwNk+1*BFt%E0(o%8w_ z^Zr<$@_RO-mAB#YGKz`IWp3R^e9ON^w{JxGKmJ|Mq9tEDI+&`*wa*DxxJLZ4QYiu} z7-Y9itH*?qgfMGUepL*h5q3zPNMpwPaswd#krli?M=^QxgxhT5-F6Ku_1;9bf&9IyHzn?M_46d|1K7&5 zCP8oXIBFZrz_?yg<)}<#v-J3EFm^N3zS?4;DP5d9;@GJ9x3To_^{H&2dE3}k+HYSZ zQ?jk8zl+(hS3efgd!WBc2|99cfb{(7BvUmSkHes|NOiO&U7Fbkj;*c&;s>Q9thbRN zb0&Rn^dW3K@bBk^acep*3p#uaJtchI8{NX)h~3#lEYN;h%#6g_G?A#Ua3-l(o#szU zgiDiET+vx7hzpn+NBlSOXDm|d4B3H*9>;Lx8 zi;onw>S4IY+rk$cs4Ox3>wy+252&^Sh_FkU!t`Ba?XoY!O6B?Crw_#SV81PoG-?@b zd>w7{8ExbPC0;gD2d}5_UQS_pt)TUtqxYR7=Lr!)eowTlN^~SJ(|zaUIYt;dKp5hn z`G^($h-Lbi!VKb~`IsUPIzk#cM;H>I`KaX$IGgpkDi@pV&^bZrwy;yhaHzFtl5{G< zS#u#2Wc;cL7)nZM6P5o}hO8$F#gOL5iYt3 z)lm)5oA`ybeCDg$r=p=>yA0c7i{1u)S`MS*)u3uFYl4$(+`%&%D174?~9B@WnAQSE~g^4GE|WE_1G1YtsL*= z`iV;C#OF22rBu+&TJC-r1D_=9V=+qTSaBSQ%}df}=Do@Evz^)noy^}wb+as!SY_Mg zGIGZ@Dc@FhpG@d^zp!1$z=_Xww1wEKYT#T+5b9;W1s>mauVlAbig}{jGNyO_pzurd ztyX?7JXCn(IH|IvaW~9ZP?g+%8f{@75SHtS>CxhCQfJB6M-r#plOJ!~VgzS9-&v0U z5Fg+=HVUCno1Dk|P!C@*Ep!cztl)1$51bECG^wqGZ0^)=pe-fPNj|7Qi9pa3J)y+( zd!FFO^h-Zi$7EF4W8{Z52c!!Q_roMW<|$^7!3*$tnh-?}@)=}A^EEP8zUMKjEM>{U zoq;61>~IuAOG{PPZ?F~)rwm|M)GK7@<6O$#W{qMO)Bg%Yg5uBD{M2_7@&+LE^91|| z{C~^DQ*RoXrZe@69o&jIk=p#^)Fzqd4T(jRqE+LD^oaE%pvB06aG%T?sl{cqg;kYA66`fHLfc~VAxA5G zwn}!3a^cGzp%`RlCc2njc)uUdaiiv{f8-X7mj{+HB0PCYjHf5sutufMa_=Hbvy?;! z*v~s)n!Y0@Q4yL$ah_1}M*2FU-sO6iKETH9HaJf7?N{*L?Gl}nwqPeMdeS&^8cUI5 z-Ncr5)WCtnPU`J!+5o@boMexe3mbhoE3uXHZAO9G`YK$mr9UxBGe6&}Ibno^;LlMg zi%hq?)fed}d-<0U>72U3A?i~9t%pW2HHH6As{JPm#msq8u&?PiLeW))_`;wbjUpMq8TUJF@18pB>HpTBIV(OJ|z$~Z0o53_9tP7y*A=Q7ASMV%`v@9LC znQGH{epXC^bIuy}yg>a{2qp86nb__WW8$5eI4tw?tVz(HG$h_{WBAX86hQXe@W)wU zVr)Nbep*qtUn2=5mL>zshxjIU<#dJN^jx|9cyivPAs0shN^jm6#3HQBRrnaUrG>xn z+mw+rmL}wXcOa0fLz)e`i5YLlKXP6Kb(j$#esajIZb2MPy4&p0T-~EY^#ht~WG(^w zQ#$4g$tYNQhOB8f9AeNuch*gJwqh>lRROn8qP3|4onW%`IA_j9HvyxMh?qiIgpk`I`JNv;&DE=c6?q2hKNL z6@v>WR4|c16h+|QVZy%?4Qp2qcxU{$qSk|$tSE@uqK^6gCU#vHJ)~<9fz&xCTpjR9 zLOv_uH!;Fs|J$i>9mJycr5nM9tN*rmPwc61Ry1lqocc1?!qwEZFQBtF-5@V*|+Ef&zVXmepNwW_)jnI7}3&?CWqJaJE-oV z5%2z-5_^lO(Y0j~P15*17yCHGHbdAa`vs30_u$sv?$p)a^Oh>xY-UB)bki^{&)Z>! zNpZrRQMrkb9n_fRHQII8Kb`oV{e8#_N976_~>`#B7BurqE#pvv>-#j>-ORTiB zWV_j#s)CJ;)3fXIakVybbpfPPy4J}>h;9JXXeqmypZypsArsZ7C>|1T$;o5FH-%yM zL;m`JIzyN2#+14j?N-dx&AR-v{e|p=m$;{_#HQjcVsSjy=6CLihB={Qt!JF~YW4?3 zlXLS%psL`|%a{J)h^^OlPQqzRPu*{Q*fmR>+5vS75mkmoFIZ&BT*!qFfk#Zdje}%( z`AzPyCs#TrBX51n;~MXc_`*C7oW{FZ>EhicUw!=B~jsa)>|VuhjPTxszjoQg~stru_*CIA?0(kyOMW>II&= zG@ptz{in1)m8UxZl0Ws<9%t7yuG0qk&bV;;{cNWGV&U52FO>&u39iSRxDn`e@JV>} z-dvrNQ&$Tjt%4;liE12h6WVq^S?E<``yr*QAx6LQT%6{XoXxQIqJ1kbj*aSxv|p_G zKwpHgFqU1?pizgt$;Yv6wxvNTKg4AiZqzBSM(TCSC=ID+-8go9vJpNzx!EX=gOIiY#l6&W6PAX;>|=-fRlhdt+reBok`~U``$3ig zDTw0Oh`)zblys#b_LElxv%z-<`0K(}6_BsH#^0dvEZGN)b$H+;1fFn7TNuX4R;X=j zNoSd^=~Uy~(;$8&t@YI=nt4%$m_mMUQ*f2bx1VnoXaD%jhEZ|;gxz4cuy6LOx_Ph+ zj!G2b7nQF134Iw;5wYU?H~TJ7cky$sP-({t-s;!o9ZHJe)Lq{F_8^fo2$&p2)Y*19 ziX3lziujX&L1%oopMouW`!i(^Oi3*|4_YHRzY&H%Yk=-@EFAl5S)0NwWBxGb%D)lw zfpNUhPF6lAc;o7IG)w&Ae%t|GjR1oyNU4z6PR4A;6&zwDtP_>Cy0z3_k9BBtMl1=^^bo738eimCmiVYrw?_0tR26WPo9p%ZsYyVK*m zUFQ*3U@-KnksKujD1HUC?wzcyrF{0?xh=HG{fV4ceIFtVd5DtnnwoN(p#R0AZNJLH z#M~pM4W((!9?QF#SdLfg~FSMJyuA8ttsNwc2X*8RB97fbuyR9hRIi{ zbmOAr;5+z00=nRfVr(87(S~Gg+_+5gQjV*KdNuW#%1?o7b$XHGZq`O>M2}ho*=62y zf^TMFWkG@7?imD(htIOH5I1U~nky7iZ=YGYLl^(Xhs|CEdAy)&tA2HUVh@5Q#jhXDdgIgnNbzhILP8V{ig0^!yhf znHLbwV-nYB+)hQV`!%sYhvNZ@;CB17X&mJv<53`}ky2a?)>EcWOkI}oKPLkh!LBU` zvkXnkfxfk*7WGP8AffrcM?16xq8HqA-SJRqG?WoYPHl5{mqpK}^0eyL=qajrs6w}0 zqcclJW7>NTEpo}@Ux|}Hqd>C-HewSW;YSkD99vnWFPMv%IUxEdAaHByzI-h`%d2BYRt zj)1WEA?>+#BVPuS)A3XdNl!+didA_|p;QorIqtoeG;O#eGls-mOD2-%abB5+6_ke= znkGu@YL=9`_Ve!pm6cetg9v^SO*`Kh%F51B$Ix8KASkk)=oujh9j zKB*9S3oYheb7GAK8779L^?!>hfP^+0vD4xaJLW*r05Z5(qPCoF%;ai+0jO`Q&`ey!Fxqn2nvzqqWa8w?>lpA$Rx(N z7>Eo9MnM-b@7!v|j$=(nhVk~H!g|J<3DbVLnZ$r@V+u%_6PeyID6U;9IDxuSuF#Tk z9q<>Oq^)`Ci?lM`l#4=}U$6ZYM)^IEv#8FQAet|*WsbSplnHjnVHJv;^_mF%>Q#_6 zZ#WQm)0nBb_w1o(XN9=coGTBN`0^LNB7>Wkx|nVSorfZmS9`H10+LXvxj$vpxRRO) zg2X6`tVz$y_n3+~u$@T>JJuxItNWM`29%*Q8ccr5H3;-;4BO<}x|>uU!$6krpVlUJO0p|d3nJQ@}R@w(!#E%KNIs~$BMyxOW?%<3N!%NjS0e@!W7BIX?n z*hdM3s|gpL7~&ho^dvs(DHKg-`&loyV412`p*HcK7yR?93O;v0{qgTWV4=*X0gs83 zDwtNO%bJNv-3hkH+Y{BmqDIANdlZR&`loE6sN5neSn?Ra={KNXx>D2h<$Jd4sn#IP zneIOh52~V{5}4h%nQ=)He@hMu=1&23=z?)8 zH)fSbVs$my*+^-W>G-n_!@T{DOojmGwp#2lvUOa)5H`;xizXFTMg#m z`};!q8o^Z7!sFx*l;}v)=2D+6hP65_wqSYLu%%y{iKVPrQSD<}Yq0|N{&F1H);C0J z)fee~Rg)}9P5oalIeznAu>45cYau4jb)w^iSyc;&8pT+KPN>&m6FeS%iys)Y_V2 zU~g(!uxc{GeQVUO?>(>jt<#`u=9oU+?gt-2 zAz;RLg=z>RZ@?qYuWX~5d%OoPr}mno64!R8X$SkENdMVNO7Hn%mdsDZvZ*tYHK6oz z(w*blV^M6ab%pCJ3JU9Zc~)D@NV48D)R~E`=Vy%;se}{NMRuyZ8gf{{$2X{!MVBgI{!*D^hx4v#oQx{ica=r<-B=IzG17>#Ahl@ueNF&KMt1l%uJqS zIrWR6Vtg}Ig9n2;!y+Qp!*uMVl1UuitDAv6hM3FxX#MsfBSRS()4mUBB$Dj5sVz*b ziZD82gAppduvD7J-wM8+6VVt(fLSj=rO(6$B|*+DVol6k5}wQ{0D7g{-1Ll$j0BMG8o0C6Q zt{sZWTr)vHLPzY4&ysH-dy$!Zx_;kAuq<G3ALjl{(1+8=)~org z=72gS7OBxtcFZS)F`xBx8fo{k-Wnm-&>KQgggF~}lF@n~hq=1C^BaNfTYhG_JWxtr zQh#nDqoXrBoa!ZVA|z822X|etx_#{2-I1_NPY9js(~{~g2?r<|go=!7>Q>>B_;_;a z`JWmOdj2S{fe2H|PAfLX>8ixDU5kV+V2Kqc;gvaV_O#SF-A^sUzf7A^Xv_1GA4sFR zX9WGop<-?J^nC1lNM)Ll;Lw#YU~(Wl_1e4`8$jK#Im!k{(qocJ5gSbMnNL%x5in9u zGFc|71u9imzihz*mn)FbrG){TA(ts>R7e|Gv5BTE-`bT8P(;*dA0*cm)brWw51<9; zTb3Jsgs{V4s?x3Ko$Y_8635H)N?Uvk8(H*oELeR*`YlU6Q6DZ*h^xd4d4D%WNvl+b z6kBB|#O00?WhoF7>p(<*>_r?1FRamiPr!aPjeGD!I{}x&{+ZH zI)_S+0AbNS!*!;;`U8jXN^qgE<1EfdX~o-FmGU}D@hL6+f~MlUJ%0yV4?SGeujm2+ ztJZ00gP%<13SQc9(dKhKC+0`{W_20vYZpGo#tGRX?A%h&ke1wF6lrLqKM}NR=k|)a zQR;StmFB*Bc;~Aqj*Brm$=~o(wwh}4rPmZW(S=;~UShu~leGaHuyIz$WBpi9)Y)hr z31TgA7g)@Q;m7jjJz9j*>FkXy8ge~W*?LzE^kNycQDnUN>e}A6VRI%m9#cCip8npu zBwzh>LWTNrV-nD5BH)(M7W;GX8h~j$Lj%Sf! z&kuWqxS}Lc_VQ%u%xh8P-Ayx9yCK+jjfM5xcB`9-u;cS=$l|&tYp@Z9aHDv`uuabT zVxhbJlZW$&AEU29UyBy}5z0G&uHZ**0I35oy`G_gIM}mV@uG5Y-fzA6@b;$xVCEX}JEv*G&e)3_R{&|EEhr8`GC@K_Xht8JdS_2D)XRxxbIDuvHfKJOV)wVUGi zF1z6mqkr;URU#TLe}cT*h`G$tuAC6(n4Uj_J^+;02*8xca#L2$THsK;_t2H%<3)2Z z({qIW3|Wo0#c#?AX7r>X3dJkso(nsl0O?uKepB^RozRe%bCSCGuF0zZ{2)Tch7G*&rows0A~M?U+}(wbBk7#A;J;k z*h45muhje|h}4bIo&K@5J(hz%PHW@$j{XIW)lzPS5AYIY}OvVsXtmdscM7|y8LJ2@0uq`PO`>(bqwbSynjz@XNhNRzU1-r zjAXgq++hu5{0X~XgKWs(n#&%V>0HZ044XSnL!8_q6oS}hu20?SpjZ#8(yk2Ek!rNZ z4nUuOQga(RnV@$D*l=* z#&fml&C`QIjtSmr7mQw(3m@jS6Z2t(Rq`D1)kdhOVAl=iZ}uZTjESZ`(xXE?O+Rf z=WmKq{P2$t649}s5RRqYyl4B-ykpXW-yuKY15lXThsG9$*P?{?X`W|_ix}YF2{N)C zo|E^BNZ<{{yj7)xTC1!Q{Ue=qU6XuB7AJaAt?VqJ~LjlVLpWTSCKneXmWYZjDK@NLiG zfT_LsjiLQDblxju8)v&9k%NG@cXMcMq()NQ-y-vhv}-4;&o^CJuiQ(p2tE+L-Kbdb zCN?)Q8%^_1MZ*0!vAE6i>}ef9o?iLw*}pw~E9;(17b{rgTbnlm@Irv#w+Qw|>w96U z-#t#jDfIhT>%4^S1$%$Mo$j1lyK|j7vWYnk_9R_71NX0QA#Hmca!%+-kKc{qizap( zpq=h`uC{s_Bl1+AQsMRH7k|tJO*R%Be*3tGN>qO~>E^jzeF-H(VT!FNxnexNy=FZE%MDxEo`zQBZIn`irsO=EX|UzZBGPZ~K!xpHT9u zXVPJy?fK4h%kbS2(MDbEy8iveH;(7F@hdV#_Nbfe3OVo$l9yQND2;3rgW=79D~rJtMhR(>FN<6<@>w={tvvN)0oLQ9 zhZD9-Oe#ES(O%)v!@Ln#1)MW6DSY-fo2K+V}(2ESVX6M6&xrJ z{coz>ii8zE&xT}=-R0wBzl?-jjqAVzc^p~<MTE1^6i8f{Szkz{ z<>@4^__|J>0qbjOc_7QL-80e{8rU3po|re*j8>&;s|!D48R@yyYc+OF))$4@NB0=E zI}iUZA$p1qZAyU>Ho^uI31TBaqc)|94_jb^n*i||;&*`i~q#NG3Df`bh3(ywwrEbqHcJY==nZX57vZ zuXRX4GyKa);b#2jksv+@crXS@B()1p;)p9BBpnzhKa$f0@8^hbHv~Qy%P^A31-Eg; zvm25ZjJF*r=z@Pe66gbg4#pIUq`So_9C7!7WCi2)NAlj{?T+}rLXd;810q>(aR*1d zUm^dwV$i`vM5tj9fy8tX;K7toQW0_(gecKa!D5=xa0`@hV-dO-#0O%A(eQVakTele z$plKx6o@oH%Vd(TVhVDwHI%63K#ycH4l$W2m>f#vPx_f;Qa3S`DcE2MrzvP(O7f$q zp<)P}2njWUSTS{axbYI0^oXx&MAKq=^zg?eP?`}6YJ|07TGenXC2-3T`nSBxkpgP? z=i-4j5dT8(xguod3HnPAxq#OD(6c45uM&zjuni@s?Le=6_`maH0%EeKFa;&Z9zdsg zQa>@(Q`mtL^haROJUQI37y(SU83GE>jEzKQSdIX;%nT(S=*mV$J1mtAlV*mb1hi!% zwH{W=hHW!Ln*sW=k>d?Z=)%OAAp(F_%_Q2x3c9d$W~lW*&t@{7VVQN9JTqhmpkp(s z*RaYuY@ZqWB`~m=9Bo*f4<-tXKmxRIAyFBY=Yy>RqvQkKUC3C5rMqFWz(|Hbdlyot zVdZYvE->0Q(BFleY*^9Q3 z7en2Y6f_ZG^B8a-2|fgLObRNguqjh9oLA^l39e`~b_&|DuyqXh0|}vMbVLeDny@j` zFj#pC2Ac4rWT>wapUkbc6wKw}kI9f660}n&dK65S;g`wKZW1i7*lvT(-Qpj=(xpHnqkvwu(cB0)o9$sw98>bB|OWay=v&^ zlF+a4{l%1AVH5kP%Eb&^(Bw8~%)|Kl5==Izj>XLF(4x0d&-0K1pG@i~M#W4X;n(xf zeiE#wsDZ_-kKupWAmBh01SpcG^eEwAHYgboJprnPDIh-ljt!C)M3ar8Vali!e#QoE z4FY7Nx|_1hgugXI;DM-gQ4~!X0O7~YP}(3yT~vEh=KAobW=I|o?K+BqDU(C^RWq~~ zh-Dqs-<0(-{ErI+8id0?N(IF5|JZx)sHVQZ-;vDd7e9S@0~Sk z)|$2MT{H9C-}&pT^T%2HoPA!O_xtnN`|NEh5Wb{cj{Ou5NGzQMHl;E-mRi#s1phw4$o-@CPqxrDDHraQhw( zLpY&OaU32dEJ=kYUFQ&iirN9VYX_BtC2HaE*E#i}l0$e?VX61%Qeght>!FjYs{2u-|Qt~DIY7>Vx*|CX>;2fZf`ok|qa7WcB>||PZ<_OY7%;Di{T!A%m@i~fgv1ItA zHSV+;rOg~pm@t46BF$xslIG75fr&a$BBZ&`q2zDofMFtPl=H=0-Y8ku92uBc7zIjYU>wmhG4vk-jTR`Lbkobri}8RdnL1KdI(@CU-`h0rxPrv@my8YZ4u zi{!sy3)TQPR2$yQe2f%)Y0KLLx?g?#R3-r_K(G~P0(UK4Y7$7O)@5LK=^O`~dJ&*o z)%r=cViA1fgTPW-$VT=9I-kF-Tm*zYDD2G ztF8GnGGQP9O<0A@VPvSd6ll6ss4za{!+#-REX_B*i%#agbGAc-rM4I9(WG}>8 zJ_8#A5~PWk@{KH+mS^0J;d7_Sm_k;UECMp}V!*mIi5|Y0CG&-hvKUA-O`!+!YstzY zBWDAoNE1uqn^-b?no+dD7etdwf_z)DOwB0R09(x}b5P(%T)>9}scbY-0d3>f#Cy#)s);+HMv;*N*bqvB+eYx*qR5rn zct-%N=<@yMkIC!cUFpUC?;rw87D}w>Wz@I2iZJa$x z`oW-=FJKhK+k!hyl6^Di?+g5l;>O_INHXNXGqV6D3it&VNRrzg44MV*Epy1@Y-6PJ z2R%&zBg;JHIPVzQSA%}0z}0200GvyVOxxh;9>B~pU;%eFM(*oiU=Q%uGN%R3aYMRt z&^rk*vCR7v=d&UEcJOQx@Y^zXD$Zj=W?;}~2k>qgNIGzl=0YGeKmsUbZ5(z(m{SFD zqUam^&1qeO(|{S$7D#Q^+BTP;uf{^DX4LgE;OasHuFkK8sNZm_nF4 z3CSp{p3fR9iQ zsRU$=#_+aLjd}!4medxqm@&YwRLdSAp(UtA*2o4=CDkBFP;cqz)2x{dz+38xBq60G z)zqws4c-B&$&R3P##V5xu&^is9s%M;LFI8dAYl;|_<5Kz-ycp-sH|O%w6Itx9CMvJ z7OFUu!&4|M3J--*vW^sr-+^Ct;?#sn)Z+~cC8yxYFF0hNV(0PNg%Xe9i7zQ#Y;1V409xxAUZV?op@uqW^Cr5AuxV74-Gm}gg{4=ODZwp)lRa6_qXSUG=dToW)!2Q)Go0$W2pGzc34 zeVL;myoPFu~_Eo?_75kmIhI%`kyR8h;!8bI(ET}BR0F&8D5+KtAXTg0TCSNl9NkZE+PE%0M5==g` zE`~p!1~vshTrw=r?1&M3MdR%O6)hbP$Rx%Hw9y25z}-v63z>Z}LSJdzNuYuyeT&S8 z8~l|tND{bx$>?cj_lDqG8gK_xwPcW**}fq#Kobht565TxKklEuVX?|Qt#o63T6TT9 z!Q+zemDUt|3By&=Dh;r5-f--r>-kWX4pd`^N*=1Q-cP_lVmz$4IWm#vY8xjV=3hDu zo1P57msB1^7Ry9L)5e^BN{6YH&cF<&Q}HF)D<)$tn|kSyoV2m$c5vF**Bygk1K`K= z?ois;@KBYjxbfIR=XKNyDlF*V?coCnqcN_|Vw7b4ut0~f4yrg?<`mD3;}7dmlILpw z>(?+!_rm+-KQJEqG1kH%Q6u`-Hu7tnD?VM)1bAKI{RVcCei`p~_kqcne`glzz)edw zEXw~M*k}4nykF57{juau0_x3bj#0+7V()QSe?$Te^J2__UTkK>KVA05a7=9s^U_X- zhIx+rcg#m0KNILU+8R~d8lgbLxP6ullk=Z|F{gI%bNPoKN9?$1n-34A!%|omiWPik zMgCh8diRh)howw9;OELp(uyN6#c9pmsO>s8{toLXbTPNIVPS3<-t79W^h!vWU}nu& zWOOkt0z#8_PZNmaiHa;%jntya+n<$Ni8z>+R-2bz@tuDI8<|YRn^o@0tnjcd6^lit z(8}#jNUxkf_$jVtF1vC{?QbMmi9bFj<2rV}wgdGlG}KrukUvh4jV_KWF%w!bcvyzg z4GD#6hq_;(1-L3qygl0a5T$!z`MB?^@*w<^tlayqo5o|OUH|u#92bIsajR0sOErOV@wPBCF=O1%7fUoG%8JTm}7`*LwMwg1>rG zP=D-0d=siNWcj2TUS>s8&D}tM0X9Jw!C!q)vig5%zyQq z<|~ty>+zW=`&x*A)^V)Bb!xdiehV0g@%3C6rQL8Sl06gOJ4Onnf5J=LZG*M=#y6mb z8;Sf{f`L)KvFoz58zVvm6GQ$q=RrG!+8dcOD!p$>qSFHS3sbl77be~C_i@q2E%kpM zp8qeEh*#rNk~C-AZrL;bVU6cP%TNsunF6Cv+~!ffucD^hX_uq#CdxdBE9+#E9@8!H z_wOH;-^%UB->=A(cl~0}QttX6h6FX2PJ8JhBz?vzY$g1CHOkDyF^8YXVE{q=n?D(R zB4Lj49WMTFvgE8dvG^g<%jr7&>C6&|64Nl>`)jc@f~$x08Hwa65@E_4fBIIXaSQ9u z!+%pp{k@wgvu^wFzfIFI5C7Y=$*VNNXmv8O%1nx%$SL+pVA7uUBeWJOR>V&f5&IA8 z`5@4^C2aEs>NlN;e_bAA&?33ni~4=M=jdOjGd6(ojaqY~p-0COT^EjPTPHI~f7TUf z=n1Nz>w-~BzUyE6Gxj9hH?Vl^p{p;swEZW%L zpk6LltByCy$jyX-{-zcWERD2R&#aZ81kSC*#6(}KlzR}j_mfI0XI2&AjY-rt+t}v!l+N?u7>-1ucy#T9jv7v#C`ZVNeZKT;EnE5ItHJ7 z|BdmDD=r=#lA@K44E>vIQ=WYKjrPqe@#S*)_vDd(C(Ku?#Fv*?@^g{&2KMMdt`fd0 zAN=?3*7z>UBtMk@qN;(3zQ`2G*x*riE)w5$A8*_eHMa1|PMS7P8FE*n%D&N6OEeI9 zMcSrs;Jb<(U@d9d3lnyBsP~FQP5x`=ughB58miiE^6SgLt3Me3rK}Lll@M5a#eHN$;UBJ6_uLk@uA~tan<7fA9+8Eu?ZF`-B{?S<$kJAx6nkxmuJrwv1w0U(>z8$eJy!! zYVE2oc=nX1I>*W7XrA!xj%VyIK0{VK5yn?&Tot-nbU!HM(BhT*@hgYT=Nnk3D}WG< zD5Y8Du0D7};OgmPZ3d}H(te)6FsartLapmXAr-#-bG z4fWBEW_h)0vArW;t6paj_ZXR& zGw8P5KB&3j)PzgP6kFqK=ox%lUJ-+By2pQ+6ZqP7E!uVRaxcWIH}IwY))yr)lE3@= z*o6s5)Dxxm(~S{>w;Q~A6e#f6FTrOJIf=0+#;ktaNh8KtCo76=*zeqt->oJ5jM!}4 zTi#yZ-np7w3=6;=1IhyycN^WfA^XP1~{*$`);=!UJjsFtuDV6?DQwndt;Ui zCh9jWEa=#I+TBO>f_~?%r!FV;ylR`qN=<4;cwLnav$i&USEuLGE1XW@NDd zvG#d>^w=X^_m#+-7qi*RGxx|7rXQB4SdW&>b)Hn^FxOU9saL&DzWMvp7_XVJ_l3P; z*T{oUFEENV{wAfAC~=}7}ssLmb_W4b~Z1s*^gOj{`lc@Xp5KOYs$ zE%XaR|Jm2k`@?jt=&aW3OOErOiw@05O`ny04pTy^6NU~4)U1DfJ${gmEL1}87kn@0 zo27M-WJefXRbyYe7p_&zxTVDx8ca4d?{vbV5*);-{ z_d7;kS0IT0>U<{p@g_r&Of;&X@eVb1!HTF#~vw@Twxp57X+Wg1^fb*dReo zzoDxGfDzfrceML)KfR9RGGp7MWaXc{niigza7elNVN(z@9&nLxKH72JRp<|*U`CH# znIaNg8MK~m@UrXq&v=hRq7-+2EG3A)KGx*rqtC73zDt&x(=_D1wvfrQw5Ik9$o(%@ zY@Nm90&NSh=*!iYg=RK_zi=EsHY-@2qx5Uky&?zVGdwzB{bKRsaw))a&st0L3O3;3 zS<=Dk!E+_iQ%{du;RP{33$0!042)ZVbrKC$ps?&zM9stXg?y}6+s!*)+f%HUz{q)1D} zGnw>}>7TP#M;?4~+W*An-g+2geZ$R5Vg|mq*nWV%F#giLInAJ_j}reheRV%rhyLh~ zcam)6HTiSx9~T3?S1Fs^mgQgSzNyDrzxw|2*Q#Q|v0t`a{UfaJ+4UcKe!$5UZNKt9 z^vQi*aJ{-?rWjOM`t>;=y}!t8HiOTIFYeDSx;2j_JvdwrY(M-hcn)B4sJgUx+C-1h zabQim${TLYvOK7&>Q0e0!CEYoYA*193Y;d$7Y&5H&ZwIz`--2-Y0_K$u=;IzwI_ec zfB5_8qIJ*THJ(5g#IWZLhdv)}tb?}94qvZ1=g%Bzl`n9g@mv#ovUjcRO5oi-Kg>6F z&s)93Ytu0!`%g{oT$M)BuJT;nZ#xwYkeCtqfWSMLCQq5+ zXX)KPzKnib4phc7`!w6GTzcaA)#0}hBq{CA(D)DMpo4KjPrh>nV^KK&ZqV51JD2tu zw=3snr3eJoM)fNu%1ayTr@z!a?0aVTig@TSl|!|3bGag(~N{;vBAi^_XTtHXgK zR#!}34s3mSD9|UV==l9{=Zz0$QPx@uZ|`NkbNk-u3_if)_ly|N=IMPh561T;K%2>< z167M{BV6B%A{?_TfIr)nGkT|!&uQd{u7nI{*FpQfb!@2?E2p5 zU=QXT9Ijlm`Tk6Bi2eF`EL`@d(xQCwlkz=lmt|{*jZ5R&mD7)=c$C(pMf7IxYX&qM z`cQwLO?%lDy=#34t9Q8G@~H3mS4kDS`YC8_oc1SSs64xQ+be~b#uz|bcRe$=QD_qM z0upT*H7r;{k2yl2Ip52Xc#iRiWt#BR9A44n?xjxjW;C-56MD^UE1F+EQ_>v+PGUPNGXo0kvqBBP6Cp3vV5Uu=r@G9jL2w6cs7`g&~_o43);!=9OuWSCW}VpT--YitrF&Tu zgBk5CldZm8+x>z?Qz)YltzpzD>mWeHd((&_jO*wlMvu`=o(yY76WY+ISJw7c^K-9r z#8^fT+QMj{^l$A}%}b2fh;BZ~s7D_+dQysTYi{)NCPp$k(dI_|rSS2lFfRk5AEO0r zY}8k3JKntFb$BX{c$M)KZDsUqx5(c{r%BQaLbPYpqV>Ca{1H0M54>E67Z{JxW?fJH z;jK+)ytIg?83eRZSFgWqYx5hg!!s9&35;H}W!J#G&A#K7mmJ|1<2j*w-Y$w@?48C~ zK|@~qL^YGW&Jv>-Wb}#G9$P+4q5>lyt=`o!Z_g$qdiN168I@?guI_n9HgVf~kI2o) zWGN?*%T}0Gk+-Dt2=<0O{B({0a5ak%RSZWC!z4nWQXzy;~2}T7= zH=(=Nagq4d`xg<&z_OrQq+~lwf}(c;QJry@rMcCa>|jZ(^qwF}G4fbPw;m_k_Y;D= z+leNOGM3I3IoYwF_}2RyQHYVlQr&vAYnMi_@~$H4F^X7PTV1;jX~Y5VcSI#d0ZVPc(b7gOvhD)y4oFqPZN>{ijf3YQvW_sxSVQw0HOji& zYJKkcf$*KNgXS`-DRpvdDJ3+hdEO=b!}y5iGioSxc57|)oF=R@Hqij1y3&*5En%J= zggM3+w4l+$QkQ-2@zxd3pM>9xKdfLhXIHhqlTM4IXC7gg@g5ECs`q!+X?@^1O8CV1 zf#&V1^*`C#a>kQLc+Fs;1-csjUG~qmw!ZQFOxR-VqPe$}Ub{p!8GFeQ-=f93n&(}& zJj;kWr-Hj0=AENj$(~FC`;_(T;HdUQFtQyH&KkLWUDM7;`N7 zgf?@JigsP36d{i>%o0s#?sW}pYeV`Fh>X`P*@V_!_rUgOqzR#nG0u`qAojW~wtYoj zA@ng8S&9kmy&jA0ibx?s4ui%L*=kC5wQQ?IdJrBmrdcvuEy?bd?LkOALJ?z>C9y?F zcI$6@i@ZeWW-wU_TW!f6{q0srB|-sXgeA7syz83QHh>H!v@>Q{a$Bvt?rH7mNNYkB zV}d2MMcj4UZ#zJC?H5QP1e)<)wnP+zgf=yLDht2WMnI0C$4z^BwlOgWn`hDT_k@y9fG8H9`PvS4qCIT)89dd_`rLV zD8aaaKHBxz-@cV_#+yhqVw9qFwk~y%{T*A0Z@fPf1sK;(>2=l2J4Ll56Wth%XoJ^| zQEg=8-`T8at*)+lhbSW1d;iq6uKsyAyD8D@1Tm1&hBoQyo45U6EkM8CwoV5b)yp~y zwBkK!gk{DCn#ZVC_T;S=S+w|;kP$)F?N-}! zMU9$EUESImk=}%61_Lc?)LQE9)*gm5Ae1o1(2_>PQn&H86=WRY3B&sJ0$S0iz0_m8 z{h&b-2_a-NsA!R{CVy9*wg*TTLIYz8Ez{NF@2=B+2B}53&v=QJ=py*LwYI%MUL9d4Z#v8O;SL?j{miPYa zZ8Wf}ZvG^@CDF5wu*mp|7V3I9@4{}~_S_@vGY(iB3DxFK3N3=3IRqMGnFUIyH+NQO z&G#H3d|-TM@g&rmpR8zc_k2j0W~{UL6B^B3Dq3H8t`dGSezUj|YI>alTXa2(2&0To zEWU(>UgyBpHqRNtXT}x_kWklqa` zac|Y^I;FK(c~%i77^^JER>Q7yTI+!4JHj`{FBWjCZujJVOSD(i~UQ0|5FR_q2B2$GN%%#cvL`SJ>|@h;Lz9qa=3r_dPe-q*RO+Lzvln?l)hbx z+KFGZUNKv3dH?lVMeOtXM-dp7jY6|nLZdF@ey`^h*_>pg2g|;{S!k;volym#_ZTYP z@(`or3`N{r@6ziH3)Sl2hGuSX@2OLUMsBv#Q}KqD<2Kkx2U&!{`flTb0|0gCn@nD1?QZ}<#-;2la7;<@%#!dBa`3bxhkC0 zC;y4(t8jiexgHOwI2k@U7cW@hV!Li(UZqIt|+qz%t+`ENVwFT>9yZ5Z> zCe|UlcLr+P*X4E}4AgyF2kzcZudP~_+P$A%_ikNi_wGUMvvsB2qJuh%L+*2vvy4o0 zFLjn{V3Srt-B&}wt?EifUb43m%VodGTA(^M(n7XMtr{GuQd+E5b23ud%>f&6xiqV> zzBvM2if?RKk4P@f1WeyF#D&$CL`s(4538Gt6fC{FQu`!Qv9xHV?sp`of1zY;cBF{^ zJ;}P^NU;B%2el26GX4)9)P0KN^}l_l_I{*<|NS#{uOkKg@4l(+id66~dQ-O*$vt0a zTze~0Z2q2c-FPHq{tmgeHBxT=0lAJH37o&3SX&V(HGe;`ZZT45{_b{df27iU(RSVb zI){0oU@dlC*!-Sg9c>+CekZ@SZe7~^L4MtbbsqEE?zMN<#m(=#*G;eUo8Ns^+p#Wh zUWA{z8gCV7BQ<3ouOEmgnz|5g76|v5IvsBmXgf2N5O29?V>0CyZ?K5yo{EY;u?VNF zx%cMbr$N1CUu#mqCe)^(E0-qzgS)a`ftHVxc_rr9Y?t8Z$iIaEzcZ5~at51uyJ)Jb!EH!ZZO zx^HJat+%PQ@9=C|X;XdQ{@S$lrry5e)dTfB`*YqvmQzKOK|)O%<5usqDFd7ArN?qh zYtq}QJ21?6-tavlwKPMmJ~tw?6sOjZX(%I5YjL>Mea_!|l3^&|<}y9GX~-?mC=&@9 zw=D171$eR}JJfdUoGJU*LTgP#9 zny*u()lO^rSm&`;2jaABr&_E1#cA_S-B!oX(|}HBl%3qPTBl}|L)o-s=g}zpv(v_% zI#G_yX~9law%v(o-A*mGL*KMwr#jm{W!kD!kL|cO%^9z(U<6lxQ6b5lTOYY5#t}j~)>&=dCV6G+hV)2s|@lpa0MdD2sZGTOr#amn22u;~; z!YmO5Q|C5KE#V$h-kXM&wi8ovn-={xdQ&c&$NLfOQx`YQ`{9?S&Tbm_+p4YyCKtSY zD70p~d)=zhW6gW_rqx5eHJ9BR1C5u~&hF+9JXBh9+|5mI3|{luy_NpZdd*`u@1XJ8 zTJUbc!MA6C;o3*d+zIvWjFMiY56fXOQl163Y?j(;v|<$PdR~*Y`7o7aXys-jHf3k1 z?}oTLWm9?+F!|At*X`uLy6^v{`+8pcT$@9mst6tCGna@re_%^5@qN_h@ci-{pRg#w zw-TdJQ<(OHb1@+f*B);8zCt|;Fbs_9jqGLKtXoG-dryxxb~hHd1-n_79h7n!e?UL) zkO?-(9LJUBV$|Nah8i@7Rga%9g&W_!*hnhzGPpm^D2>E4zIF{a=nn&wQA%Z^@DX8; zOZ*J-##>6~Fkv%eD1(P#x@Av{e$I{&OD4k7$GMClXvxQZz8%-cYfFbQk~7+;N?&8n%(S378pCwTx{N;0wh;X$!qUb8#&T%m z$8)|Nx#Nwc;}~P1S8MN7RL;2M_@W;9uaCB}N23gx^O%QoZ^MA&`Nk*g``ZlKKiBGA z>C(G0{Uy31C(NU)-!O&wrEYE}%zFI57#JbgY33A18i$tJMhQ;KN5|n-oXYA99hvfV zW^YzZ$G;n^N4R&Ios4@tu373GkInYA`hVmN}PLQL3%zSbM<^(hG5gW}MC-<>U$(ERu`R&K-DCP*cJ<6JSK<37b zbSX?ErZT}8_0EbHiJ{Ds81*iNh!Z7jW#&Io4@nhMiN~1DQ4b$gyh$`?u1AHF6fh_1 z*uu;bOgOn>IPnZ~4iny8K}&RJKEbS#D@GE7n7=Wr-GPINaAr0}iX1qU=*b+$NOcEN z6HhW5Fh%6R=ZSvIPne?aKuV%L^FGFh95|eKn)w>z(;Y}lbYpg5X2^jfiGj>5%uM&< zV4^Ma7RH3UIF#tk9LJb+FH#d-n5~#@^5XNvvrIOoyL*w6=*XP&mFjbb`tl)BQ!wqu#|9VnoURVm9SUI!L#X+ zd-vHhHL3 z`@h~n|7U$ap!`zG;l5C8c^<3_1$etTEJ3y~q0r_oF%sDRN5m81@+AG}5g}5DhYd>(m%GsWN!CaJ$u+ zbYVkLS*#kuo9-GR=nv9?YtP_AcxbGoZFcDW#HLND}6wIwyFbrfs(MA~; ztBP%U7=z8sQ#d4r)SurNZohBI?8O60VmZBOP1MyWfEx_y%Q z5K~1?d%o?*T*Xv%r%|@;nMIgja@z3rY32+jxI2xu?Z)iJyd$TLB-XS0$lvA$F70Kq zbI3|_>6pD-_Cs>jTzd3gHoJ%%JeMA|cZ=Okem9qXX%EXTAY0EJVD|FZ?c`^32W^)= z3Ju)0&JJGc-T?lQILJJ-r|7@A7IRa_l*5q%HihU8o{r(()`;zN%&p6b@?Zv$`=j<| zx4YQk%y)?y>>l!mx%^8fGTAt?*ql4&L@v9Y%pIlPp>Y1h6Sg?nd*1!Ri7vJwd3xSG z{6s&SpNx$P?^FmqahE+t?wEarK2gU0LXMk#6?vkFy+Hms`|9F}D)t{TWL7t#uaHe8 z=gsP(`-<7`$u6_Hk$v~rQ{>TE-HUzY>>p&U*|vzjJM5Qa;%pnbuawOqUz}}=?0YcK z-1WQhjR-3%8IeY}i2%uhZ^6ZCG$YgufjYPc)%WSLog(vDiHHw+$ zgyTAv%3~A*gmtrAs25`Fd-&SGGZcYkwVtC3fGaqs7@r>CSBTJ{?XpOcwgsn0cKFhh z4X&r+L76jDxs5YPz_$>kLC0mW9qm-k;Ot9FeH+|=#M3k1QI$4)c7U7bW8eStUi@qf zM}C%AjATFtaS5=HZ8~VX!4s5avLTY1S+yj@h3iqS6jnMSEShD92raa8;^WFbuk7R` z=mpY*AA=e>sn+wZ<2IGC!u-eipvrd(WzLH{&cYxP3vFM3FN2@J6`^`B)IS1waaq-c zNNI7A8(E=G7us^sJE?1)yq238pz~xuprOU*N^kzjPuF!4Qz{%i#xKfSY zn))V?8IH|Vk~k)-pK^HTPe zrTz`hRB@}!398h_=^elT#Cp(US!ze;59hV)Yc>-~;g!~}9`OQ~G)y_eDZD*=(Sw24 zxh;4+mX0QID^a9&zz51U*CFr0-{D+PsMC=nfRng-Wuy}z3-?huyHK=V)C+5f@Go?C z5;_i|DAx&d9S4`dC81g`)XoFVaOKKHg>oN7esJw66m;z8k37j>XOSUux|qJ}>{@c( zoNja<)fNky+L@RWAoh;qsR5#K;7Qv}IkSCdAnGfTO|P6a}d0g2dO%Ju3GGGKohK z;xXvGER&@BltVAuXQ^ug@KoY$<}WI6!*hqn3KBf%vn;ox`-kJdhHXwuR6r87XGl^$ zqi%_(oL6e;SP$nFsNjaMMP|{GKq^o0lKKvo1FCyneFzA~;goL|N*@uqlVt;y0g2wh ziX)s0ot*@xK#_2BsO1Y~9_&p7=*5xq06$!da#^9mN8!s^0f^{A#}|+v;NNi08fA?m z;sASGZFMnH{+_UNmKP!t>7W653H}7jn8KKFSe73Z z19L2fAhNH943Idq#U(R`siLG)zJLc1twCp$gs)Bu=f&)VkbV*;M%*}aoGM8=JqsX1 zPS_Na#J-49;W(1q7m@9(G-`T`jVVYFoI?>=)-Y9*2dd-lF5QcfEf;x}6-T`q1MdOp zf{Q2;%g1`u0)QsCvZV(xatk6Vl)z=h9z6>Vp=`&cM;kmA5|x>&RLF)`5^oUX(%{); zg(SUH4yA05rH&2WREdGiZ&aZT?;YNB$hE=XWhMI0k^8F!7cmr0Q$F`WzZlN8EV&q| z_Z&hLu_W-@LB|c=^ek(T@cXPJL~5ap6G#-C3m1iIg2eA+Dnrejp!Gb>IEM1ALdklu zDJ(w%_Cf=f;fe?=w12_(7(53TgsQ(d`Vnvy_f)y6P)S^vFAIS{A?-ByZh(j3;F=>E zNACeH;2u|(BNa~xAIow^TtM14@e#nU;Q}>kO-C7k1YB=*B~r;yST@T6agJ^m!B+|% zheK+PMjY(~MB&KQ6?DaTVe>3^L^$1kjjtEH2p6hRUpu-9_+J#yYYRySJ;VRP^FIxq z6{`g)|HJSkS&ywmUn?HB{GVux+4JPjvuzjqD%rbax!LH5zT52QXu~s&D`;votjlr5qJntgzYjqA?Y*REDYlR4=d#nioK-?5% z6iix$pO=PP4#B}hZ;Co#^{KuvcWEItkQn6%>Ugn=EAKRJJp>OE8xsw~no$FUkBxEv z%;pWLA%V0dA7nI8kCOs?InVGB2hk`2U#%AI&)EVYbtEuGlAO^>H6{hla#C>>Aw|N1 zD!9dv0+Q4hv283j6&~Yc%AXH%r06f3nnKHY9^$5#ZpKKKi@m}^sP-`@d-&TxJ`|&6 z^B(8|PdARalrIea%J*w9ZJ9Gk!-A_ITYaf{gWp0bD5Hp~wc(${{g&_BV9GN0jz%h1 zRkq#|aYGr~UR46aIn;eH8nFKRP{}yyt1n+wT@N#Xc@4yK|weKoYX^0JSHG?VzXrOssBrye8u z`*OeG`#hM8;-1yOaFu22gb+yr7^%bz7)pKiC=Lrknarww;oZaSFJ;6C%ZmzPRjHma zuBL+SAa#o7vZ1MJIqxd&=TcUTNPws=R*QN%#;r#%8e~GzSvKxbwaeeT|^gi^t57I%zzc}B+)R{*cclI{?vVwU=b=+n%CCCDG1Yr@Jyyx(y<%9(}2M?^)j zM-X1Z8b`R{h|7ftC$JZ|87>ReaZ;}b%HTo@Jwco$xH09tLW%QYkFoLy_d=H!0zW`k z;Z{&<4P|kjY#g=vI#OI*>;_g8aT4jQA@CA(0d7`f(WHEe=RWRb^$n!NDKP?87U70; zX%hH5Edy>@V-=xn$a4$#ygHXIZYWlYl|;DEog)P1K~eA%HI{42@jMl{SJioRiFmPI ztRljL?y@GZ3rd4q*H}v{^YdVFl#uH%aegs8R)p#VbCwo(4mw9MMOhRpyYk${{S$Hn zCgCd9h?Swb!d!|4RzPv^CYaEelw?LWRfXj1%k_Y7bnr5Y*H^QJi zMO7pD&2o|Xn1hKZAV@4RD-dCNT{sbINev=-%nAvDfE4I5%v435cLeug2^S+;F6xdo zp!&tQn+oZIq$o$1kN2nq@Xp{qFX3av7DS`5ClE(^v=+F3WdoOLHb54Vl^GAI1{(oM zoI!l;gBO|GsMR zFFgPMjHlFuQv1K~{Lh2u&p+Su|D~S)Y1C6_LaFLsc>brsbLX#m-uf4w|7q}4noxT7 z{{=k%8v7+5eQNt1+ZMX-_qwncr;wiDPchGq)jSHQI5TqjGXGB^p$xq+bgPuIoc{V; z0E2Gtru*K0e5uK#S>i)I*_~xq#h5&~D6PH~?`6Fk$8t<_$4W~HBur}T)_OARKS)ct z#ZMaU)GaTem) zm;V@Mz-(R|ap+GBxH*$QGtBc!o$qe#gt~o&M}Dl8y_9#IUZX>xYhJ8=pp-!pt%Rx# zJ6p`X!dDYg3A5e}M-8M)N)9D4v(5d)_bGX`R!Olp^N#lV%BDRsWQF?O%=^^qE0Xp| zg%x_?X5Q&u-*M~LvM3#2^_GHk_HNTm^!4xaw|ZxXeutqTv&S&p%xnc^*I95Pcv%@S zE3gepsk2VK#K`%U_kDRUAy#?!y$xfSA}y5@A6sl<@qhO4b87{ra$6#+p{YYx0|S=+ z)W(1VB-`wsZ96kAwm(l|8wCaw4D=`_#Hv0Yb_-m%G0-EC5PRbJutK1n!{PB8486KO zefO{HAJaF>77CK@0`+wjS?@hJ%PgkKEb?Q2*r|Kez55u+D6`0m{T?8tSF0Cf7x?sM z?009W_By>F$H1q#vER=~eLL{D9|-Wf)xaqoedVNk{$irk{NiF@gI98f z6L3W#mBa}sqAV^(#U*;*cl(ZgdV1nl#mDVdR@;qD&Vlpaoo~!&zkShhX=twd#@rRx zr$xglo~g*|1+J-gB-6vb+uvx{9{8u@-O${(8*@sof9?%WxHB{74|{-(u&px05sv$~hkTjv8=%#AYUus)Y-| zM<7S|T7+@nV~}Hf_YuYVC|yXLr>_R?sMwjuB+=|H#4HS@Wm%#CNhx9GEx;)XB{6rh z?`o7wP_w~4emys8?;?8imvt4^DO7JhJ;}FTJEV>K)Pn41;+)!C4WLjFZF^82Qj_Y7 za}lAacpcQ(KUVU;_kN&OCigZ-TyOY9!RhO!YVR9vfwe_1RBHSva0M zq1x1i+qyUSvtOK7agp?^eR1ZxyxQf4vX|#>>%|@kdOY%_WrO#o_)9s+@GW~j&oR5) z&PVs`OT<5EAN#l^QK8+9bsmn9P<{Pl7af~+3&A+oDNn-8veW7@m{wYaYdwo|Z-asEAscNV11$EHZ_fOu`*M9yo zwdKW#=1!8Dnp3Ju-bt@NFGC+&obW5Js4cE|Ib@jY5w35$Vqja$HHV8}OkVhJ;oP{pv7P9)?Ti)SHgIzb=05vFWj4eaVqes`+`2Pu79Yx|DMI}8dd0MqS1mT(D9Y_D9ieUlG z=*K-rhodB~)c1_OuN42~XHi&?q^$TI89St^rs(nqocGYn;@tOu8&cXqFW=FMzNG9p zKUz0Zy>$Ku{&qLtkNn%erd|qZTRDHv9S+wVAnhC*Hj#Yy$#F;5iYhexrm9w$k?4eY z`lT}vd3X&P0jtr3xOqls;*7=24<*j>1WG0!pAma9kR=C0X~e2ZJ{NU-->|ckl}jx< zPW?yDELOE$I0Foy2l**$!XPTV7i#WMZ)QIcm(*{@f@>F8t6AjlswC}s)A~L9gyrC>f@xqZn_f>A% z_lS#Vt2A5>716o&b@EGGfoHkms8hM?d+EQMCGa?iHrzj{ednmqu*>(WUg8$_a}E9K zb5#PN$BSRwvv1UREUr?PEARL5x{43FI{`6k% zald=HwE@s$#ZC7l&pc{+aJB2jMe(N(a?MXFf4`IVc#Cgp(5cQWJ(r(flnyf#0HhITNd)HY$x9BfbkY^gH z)(*R)a(j7lK#d_AHNZcig&F{@Az?MVbGYC+{eT-H+78b8H-;lLpOd7uhD{|uG!zep z)~3F-`~LLgji2ckLLY0Z<%QlrxLyb?)o#oU?L~}*gf?o2-FP3&r=OQQ_qbT+h8f@Y zOKL05-IfKzshW}`UyTV}@o*{4Fe!sac9Jf3k4`}!=syaO9JPOhfTo`dZO}e*BlJF^ zCG7o`e}B~28I2eI4sZT(d6Vn%Mr#P5X8ba=PQzGpC`^s~Vg!R4!JICPx``?JC($8M z(f9sZYyDm0d**u9oZozBX8}l@?1`<;=#`Gp*hTpWR>EJp7nQ^1 z``&-xa9>C+QoJ*q&Px`9S-@L{7Qp5ri&OI5MVD-f^|pmF(R)-lvH`(0KI#50`F<}M z5y2%XO0FJA89k2R5*Af4mttUcn}D^fvyr$*9iykZVd)|j-OhL=!xw|g9zb^Y2jMe1YPsHN?N0T7*e%glE3Q&?6daj{h2Q-NyQ*(YXG=F2lSz}+u zX^js)XV0f``H2I=&V$yP9}HkKVRXU7DOPo6^rizt6h#<;7}ZMxVly;jP?s{6(yAkv z428Bf&IE`3onVr1{JXOxzcSJ%iPel?G9233I1?0Bh^5Gw_1D>CmtKMf$59p7aFdvD zgO+fkPPjW5+A{D{8zj3s+-DRGh7+U;RR@|gXFADRJUS;LI!B_vEBqNzZ1s2)(RB!H@lm(+cr4NI2y97FGWBVc z(MH&&?3iliY!X;%*ro)S^MBWKdQFS5zD(KVqE{J@Mq-X4V?L|2IsZiY)ThxzzaZ2F zMupAwNigD!`_+y7p#`Z@r;eJY)21>EAW-|K3_2BPm!VapX)_VM2*hx)8&TXfA#}w@ zJz{M4m=0)r5N01oEnRn zijJA0!^yVV3m#zkSNnq&I9f%(vAqneuUa6pQzx@yXa0(BN|fHe&qDM%f=fhH`&{1- z#w)qoz(H}Jr+nTwX|}htD4OJNdsJ^4H|nA}YP9Q->O zEtENgOiP>&8XYa-Z@~%-t4XYeBYAD`!Sz#gIhQL_hnh;U zovUmY^)qz=%hgK}=LOuc=jGf<=f&JH=he-j=gNBHkIL)4kLm&gkE#NbkDBdck1Flc zj~YJ)KMJ0HpO;kkKWZJff}i1ReDkn!Ol)J}(H05@6y!`GYfSHlmuWfoFJ`u)p9!@l zorScjob3Z=&p3c=XNawJXBDk3XL_x-XK$_WXEd!*XMcb)XI?;~#ay?PMG+S@PR`ac z0_qJ;WDdu+a0(vr{>;oW^q~(qilofHN#m1Cw8ux*oGxEWC%u!4cmtF3c;l1HX;Vxy z+C5AQ+Jj7UD}78$E5l5)yuD0|z!9c-;3U(s_fXXgXyl`~thZ``^GMT1)v>8q=()X^ zrbUt?RIdVmx@vx6Z^`aocLwKqYh1=AP$A=^buyz6$dsW5tjcg}b;w`Cd)$)c!mD2{5gTYlj_fEC7o~u@q0nl#Ee?w#~X~W|Z>nhw+*h{TFx&7~E-{#WQ zgnTG>q- zJlWYBUfC2IsM!r0O4)#pj44b*gJZ~={EA+?vy2q-7ShozFFs}1>BD@y# zrUXtM4zeGg?wEateY84b{AfA_Ix@Eqw+yZkuk&mAf1E*X$!$kJFI^A3oxt98z1DT) z`cq%m81=!P@Z1Ew68R;5k_u}F5Rw##q@XSuO+=j59QHqY-J!oqfuuhg{C<5R3+sNt zlN5dhC2-B`>?6s8ydgP+dwZgkIByP9kjP)mL)3)_^8%H)N_Xdx+HOu^K0rtzDt^Vi z>cZp3!nqE$(bH@zW5)!9JNHP6w=XbSFHS!46&%Ifk9>`_rC+K#F0t7##28tTGe~}rgcrl7=xlf5hy;qB! zzEg{Hx|@&9y`7H}x#y5~2c=U(e6e5x{8OV~Mb;^Q<(efAe63UF=Gv)FPIH|0P4k>i zv#{d#vv8*Ovast+uyE@Pv#_mBvT*SYv2e7Gu<*2w*Rc8wep%jS8`;?Q)UZ>%+p58S zda054$JtPJFLA~hS?Lbc@Khc1q1|*Ijp}JVSn^Z@M^gSMY z9faRVwZgx%IpPFl>5b*?EZx(zZoV6BsC;61<%mpf?oB&SgSuOl-gOLPM26koeYS$T zd)jYseF8o)NG6Sr=3f~6&;x$g?AP3Gf&xI`?;ie)0U^1g+XsJcT0oEQ4*sYC5h7FD z*fdvBUsv}vFR<@kpJX$~B;W%gFwO6nJG~;%WbYh_JtDAt?}*A%-B6S73^OqS$l-TR zJ>Nf>(k8nh$3f4=kYC^zyCT76?=;RqUr3JkMm=ty44{bs%*K~%i0Lmh#+Te+24zf$ zz&12U&QPR0IxI-0d}3?F&7gQzv=aogpd41n6U3OnpjsF_1cAULXDB?xSb(#_)f@7=Xmu{X#u3 z#IVgb7_}kKfkJ-BggdA^kw`(91wHtD5V!}3`YKo_p>sh1dYG$HaPK_g9!z9#Lu>LI zNw+{$U2wly%bkcP$N+Z)s60DTG$9Dl6Ct=E0#c~VU}byozFG#j;UH3o;UMWOY$AwQqtss2Df4iIFWKlzw=W`wgVf+fZd7eChsNQT|zQ{O@4t12E?3 zsEG<YgL|b;e$_&`>Qq7?JatGtIGc>&FS3s=tCK!c=QZMZy4eOdbAeIf%xH6p!&*}(e zC^IY&-ZIL#K!-TZToc-#%MLbW@->LgvanaZ;nX-|m7I0co+-_w8F7MB0O8ZZ6MTZb z9nvzh6UuF(D<~lIJf!sqZ-S!*_I|Rn7vdhSc194Jk(~u9X7aoTd<{Q47MpXiP)&)TxAOXKD@>!h!8IjN#ZpjX5{Y9mK5N z-lO0(E`vtVz1vCri_L3)3KOpl6C%Qd*`qS9?>teDLD*ssNy8WbPQxS>)Xi8Dq?U@< zYctNZ6MLw5({h-*Q+ep)Jaxy->+}MlU;B>0ta};p{v~5B+YY z0amTI7!1(d>`|x)+DTpHbzVO++KFFObzZiG1X?xWZnW@&6Kfm5pjKUlNNGCtm{sKN zL^Yv%+g3qLS7!IP*@@ir@e_13PJz`_%JtZtOWq8%(RkYlVRba*KyB%L0sLw|k^LIC zAcS>Dz;dgULRgl*0&A8MdU?)KciQ8qK_+Gh{%dK7w%k*}ZE?AICYV&#Yen$7++o4Z z3RQV#^BOZvrz|I{u{aM7#qcoPh*090i@`~g+`TJDdB&!0x~xsD)Xv_HPKO%@oiK>t(@Bmk_-}PhP!C zo)N}YKfc$t2+{DaY+(>O zQje_l!Xm%?8Akg?OSUF#5Lw59V|ob)<$WU->-az;>-8^4v=)()t~Vm1TzA4zy?90} zdnyU#e6tg4`=B7}|LjaW%_B4COG8*i!4ZoOsYpCWqdnjofPX<*6|;(P&F{&Vpmjf? zz~YNVizX_Dqe8h4Q;k>@OAi6nZ|~MB?>cLix&!Id`2;b`iG&fk;`zm@3PD#}vy!D= z4`>90;$f1*l=-7aiVcf%PV(t4#`7!&Z`4#*8`I-BU`R)5``Te&A zGyS*KGxN8aXVyo*o$P-P?NUVPV^I_q6Dg6-?^erT?J1MSJ5gsray>(X5kSTX z=T$%p=byw0=VQVR7jVFk(2F&z=l}pJML& zehg-k>{fYG;g-s}+A5#6x4|gyam6I>M$9blmBTpUoI^9=ZbI;ue+V|bph}!ALqT21p zXy=~CAm^FKD(BLa43OfYHt*c1ykGViW0%+?ZoEe{x>1&8G>e>ESW0%rfL2lGz;Z!< z=zO+6wo&*Lwoza;)|BTOeb=KPZP%$Fh5m`VfnWE_cfXPs72riNmA=bDeWec);6 zec`F+z4s*MefFf`eN;^&=q1&M=q0fGxBbt}n2^5rWe$0V3k%v-+cLuSMmzlVCM*KU z#xOj|<`m6N=N%?aXrRTN7&fnL*k;7%9nvRZ z7|q)+Fu0@`be&gA?EEvu7L z4am-pHZi9f@R?yd#)roY_>Yd%Zvi!rtUY$9NDurdAsx)U#x*}!2hO>W9$&%xJCIF) zJYnct@vL*}xRO3nz1G+6c>4xOW}N`zEH6~NYau9VZ>7+vEjQ!jXN0tiPW)o;>xiw)HlL#Y+);tztalZhxbUDZ+_uiUHr96T7e#2+_hWFkldi~ zKFMv$m4i&w%%2q|F;2KEXX_-*FY!T_T^z=^+k>?g*ZeD!UOX39Kae~@hM_`!*L^u% zHO4I4*R?IV;1~N+#zrErpqO0Li(_2)x3|B&;QkWMc}7Bn2g~5FZ^+@|@6V}bJOGe&7yvi*^aYr@?FRq4{KA@g{DL}$ zw(frc2V;h-4M&9B*ewV|1M-rhGsBOB$U&Cx)CYP31@lPs(OC&Taaf6}k+h+-pew^F zAU%7xA>;eFz;Soh0tK86dgOq@JAe(eQdAxoQy|?8u_MYuxE=(>&Qgy$kf|2U5w$Wz z0HVD=J1AtQy64u}Yljg?RXa__JRl`!)(+wqx=PfblMtp=9#AZ(Yj#ZE6kD`Ov9eNRJBp%=6L}s=7 zoCvs)8o>l{96+ifE`B@9r`Q+?(0 z(WYcal@rG?kr-jGB-RP@AU&_`9ig^|s7KC>yXZ@$c&k+yA+slOMS4Tz3p0?IGC@s} zTM;-QsE+3k%Oq`ab~_-x3Kr~xOtkW5yhE54+uF4lq3OVX34fOK-|bHd0GVT<38O-X z*NBPkt}8o($gnUzc@U7hgZlb%3vOIHl#Ne|S0%^EUx;j?WirK;P2i1YCuh!^h!mh@*rOVY2Zg(mKdLxV zO8O){(TdCgJmO=&K_``!veu(vODyH@ja-#dx}wp?5hje0Tjk%4Sd@~xQk2KOLuyFm zd|yn`QdT&CR0q7^EJ~E+ztWm5pjm_y6lSTY{SvW_j}~Q8NiXFp$7+(`%6}>~ER|be zUEn&?T41teJ|k|z@c8Z^Ayj};kfUOyTvK{p>a~EmKyyZM2B-@2k2+H6wq{rmSwlvS zM3ICn#GJ`H(dXoC!$6L56c;ZH5bZCJ%HN%xpNTvPvo?Pq;H3AZAt3soA;A1e92eIW zHzd*hZNIR)0G`d)+7wAF#q?sPhRx90Rh~BkBPFVhSDyn(NLu`F7c;*S{-AKU3CMCX?QP)BNnBud+kE2PLBo$u60SHzQ`o&H zP^fmxb>i-)-E>C{!nLJS3GQOsJV^&ZJ_n$@O)=4I#EXiZk zY9=EuDc<$)%j9eG(7~Tm9h!X<+1e*AKm({Bhb3jqYF*}#?2{YuGO4Tj_2(QXXo&hr zPswqTuT0Y(5DJT~@n`_X$?~iUo;~H}B=)IDc zs`a&AviMIjHbY%>opnZI&KJ4t_^?G2{XujU&dOulgjud|5k>ED;%bgNwZBSu1rIUf zr5A^i%D|-l>h7PYdl9A(1e>X0y6D>y$17F!!Ixd~vNe$?$`Zw;sFm#hT9Dx7@?cVw z+YFmmOW2EDK;-3kM46KP8P%ZHy_?1PGb=OP#V|u?O6h(md!F1`RF|Gvo?$@3#skP( zCBQ5L2$h>3+OKca0SY?cS4*!)GR%MWXxPxWc&uUTr#yiz7k3VNoZ13~H}QCiGIxjE ztu}sLC1lQ_~?g0vL4s8gi_;_PcTGqFZDwXrJR z-b0*%2)v(V=GZoR_{^6=2^pL9FF@g_$)V|*cxxKV&a^%sGA~rfp@!N+?*`@ z_!9Htow9UjZ(U2KoSaqU=@G(6E6e!)ud#RBoZqcj(^DIP$L3dqUsHlX$Cide_w3jE zFX>JbLVF%K=qIeg47V=Lj2{JlL z-_!EJ0eR#w_^04TZXXTqdikt^ej4(9CN2ky96k2t-bwCE`>5Ug>39LzZP~svISG8` zc;S7G2*d;&ZBp9$Oh@`|SrsJJh;!aU7yNb-Z@d?ZRP?8vom3+CeR=sV(w%{K;6)bx z@)4!-iD#N65|VbnLS6iF4)>=!^X6q3Zlqf}^t~PGsGFSjOQ1I!8SYdb?(*WBdiKvq zonvX!ExtHycV_a`?DHs%V-(X(AJ)24!Jrk-9EA&h7MiDQ9`uN*w@9<&?#O?c#RIMP z;(K#1L@rFqG}#F9k$ORVE-cPu#L(aa4Wy~w*yiZh!R&kg!YTX^eKEU(cL%zS+2Lu^ zq#zJAlk$QcD1kd@@N}TeP@D}?6KEwF?_L@Vl~M(AMDQs3M(WwHE6QTl&;cCkWMH2l zhLN@e2Ew|GsfkFkI&TIgt|ARxSd6sou5Pj>Fs2BXmw+s!6)%b z*#ei+LH;Az=s)@dA6IH3k2;vlzQn#@APs3IElYluy;2XhKyua+7Rh{(V%8z1|!dU!y)HmiZ+mmX1$p zD0PE+U)C`3mda=}R8@$*4l7CKujj$CDhqonXO=vj0-2f|;z;A1E_-JqAYFw&apGS} z*QdrS3wwn-UAjSA&;;G4+^2zW@B~w*{L$|%ntQqJMCiXFqkZfY^`-I>IDhz(s4V== zZFD$wG*d-W|NKtGwun1usn0RDSXHhsx5v;icyhY?vFc>5u!>XPd;zAT<(W~*@)luF z`$L{P^(SfO7}w~LYrH*O3#Hz;K$63usQC{c!Bv$UanDq(M1#XBb1xsG`Vv3NRXyR~ z?82HrK0^beTQnRYkWTrG2$&MM8QV_9!j0{HaAE*vexwh^Rx2oP| z=vRS6t2GFc1L)~m4Ns*V)nAh{f2$m5TJX0T=*VBGb0@a{78>asBRlXv{C=0`isGZ) z8Z218Ay2GzMWaNolvMJ2d8A=X>cHpl$6bMJNJk|*RZThL$T_{%T`_%PM^!Y%b$R{h zTe<69etDQ*<(as!MjUBwMR6jF#{KAW`Qm}zqUT-b8S9IRN9ucJo6KT)j>=>Cw0fa# zgsmo`dc|6}t=13a>@($Zz3lIg<@aU&9$Z|dS7OK&Z)*Pn+ZTYoFkEGZ@(LBpD%HL` zhZPAb%0H737QN^y{UuZ$y`t@qXv@fcE%7RA#G!IkL=_!z*(?+kN9ryus8wX3*cx!8 ztu4ssHFGtT8BDs`8Z|`mFI*JHa|NiBWK=A)9+7#J`A8YqE!vdmVxDQ*DQ?;slu9{( zJyyp3HEhyZXm5^vUEo&RUfWuz@#KB1$(Dz-J)Z4Z)8H)i1Rz%neHXX=D$Z}>vDUs+ zBQSi6l3cKvAL0L2cvflSo-GhphL~UH5ye@}oG`SkF&oLFz#xe1-2;}v1K*jcpdv2Cr`DLh#<%vrOQbF}a>#{RA|fu*3;oE?Y~y@wCl?$Mw1!n?VpQq{+eZXwH$vIk;Qz zv$$*T)ADz?5D?7*6XWgm#ih8eiV6W=MP>xk^L248r@$dxcfWlt{(PAPMSC%K)fA$S zrqLKhM}!i!4Aql`VhH}KvQ$N^!$j z=6N55=hOFM9(U1srMBADNM>8j*}+LgcbNtfgEc~hKU`Kbhm%z95^fY9Rjo7ztAf9( zZF9bB@qA@|ZoLBx<~zcw9fZFvbLAGFXMW`aGDzm*CP_|;aTMBG!wU6u8Bdo|72WmZ z&^EU)l)M@bX0n;E-L>QxHaF+~T-o5uJU7e#4QOP{d(-tVdDHWpfn<_8=}mQeP#$OU z1s?JV&E184u9nLsG>iFGE~XMYJr>dE_MeO{nZIh;S^1VXh37b4%1$?;es%h*h*3t`@v2zH2$mN!;Y2lj#ICMQ&>S1** z{(DU=*z*Do$PbQssJ=B0aGl%SNy65d;v~&gc?oOW^TQ5rrzy>94>s#uua%eRKewK8 zx~!M;Sk@IzD?AZj+ctl9*`O9Vt?!?-KiR)_b!PcnJLQwCzs)FJQk)z=(LKn$`Moy% zkq>Ch{VTHWRKBp5Teh$+Qo-4FQp(v5M_XvKU3j55mx^I(Q zy-4qGv?rig)kCkG{k&P!V#}dstYDq#w?)e_eZ^HV{rQzJedbjX{rZ&+efyOJ{oBCkEg$!TQb7TFbwi>m`s?^E z`rP;=`t5jZ`tEo$`mgwy^1%4^@}79D^1S%#@*QHB@=4k@*84>@<`%+ z^&}yGEs00os_3iR+@or?lQ`OFM~C|?@+OD%W(NTo0PZ%fK-quXuQxXxHj1pJFON2E zrc-)tuX=qrdR{RS=U)U4(DLM=jiFixBS3PN^7h2aLPC@Z8uOJS@kW(HR_Ct;4wqKT z#}bT*m6kCk=#IsgR$WB!%Tk=t6P1<_hP{q8S?38Rgww;vsh`ehYk(`LXV0iFl1!?L za%xq5LtLb5R5y@fSj249l(R034{5e7$mZu*t3b>PX=CIsx64myW8ts(I4Q`9tUjAO zDej8Cf-Ec;?qNLPt0nbCwh!KdK>ZYyUnm)%{7EOj)Y6OfQ%U~!@62Kzvo_&C z{8yQ@vh84<*O0U-kqExm^)$Q45T9_tG$-09=x|$YYwK8va1?EOxM7Tbc}A{_A@+WF zMxKs71T*zYPRl`hGmlDc?p^{jsYEdQR($6fPWT9UJ(m@CI4OB0 zXLn}|LV!NrFf7ktRIhFpp?z;zZ-a~PjbRqPAA%KZcW*0MnTx-)jy~QTF>XZY?pz{1 zP|zH=8i_ByLfmk7Z3YV{+(_w&R27~n4%lCsK>-RivRol??OZ7fTp?#iyosak^v+0m z^D?3nBQrz}_mAz4)~$~X;akN(ZX|{r~!{gBXIbojNGqKbyRnh<6?9XV7Sexg7fwxWwG1|1${t_CQd%|Wk6B(?3;$b|N9=waUuiT-Xh>kC=JUAH`LqV+I4X!-X z?zN4ts=VSIAc()OJO%daPVrV=PE7JowN;*9O#4oeo(s@41i66&_?PRG?gatul-w?Z zCTd!a+-{2&Zdw7&&gm<2T!c>=P$cL?w7#o8G`{vhxs@S2lN&baLO{CrFa_3# zObTN%b&WQ@;>;Wgd~d%NBI#tOb}}k;Sl*AiN^! zMgJ@#Jl&pB`J^Dc3>abyiX;S#^tc4c5|Wfo!-G@Nz=S)i8WYgKdOFMQ(3ZgD{9Ag& zD1qg0m1HHcf&n;dDi5yqs$^kiP5Jb`WYw(D81bbmL^I0tLPvi@L*8xCoaOB$V(oHx zXuEum2Bq_7@MmMmxX25WK6zaLu~b~dl9T0QYTw0cEL9JzWg2I(XbR~RB@)R;9$;l& zZ5RvWrL6B6@~T*8j=G^fl{^NU=H3xb=qAp>7L>i?dGlVHysKCna8>n8`1a^yq$K>p zc}X4fK(RSr+*$+Rx0PQCj>xzcfXhvEA6aioV=0f2funaYX!oY9gqFHQi z&t~pX%WHrwpG8C6iRExsH;83HwFrAMWL?rm(!&ABr=gQr({*SNdwo9;03aS&bvU~l zr#)gZ%e_F5FBYsAUU_#C3R&g)o@ZpkYYG%XK2-oDTEa-Kx{piA`%}#*`Glfid;p|3 znFdY{1xjS@&rr@MGN{i1qrEbkDf&=i9NbTut=AM@+fc-6Zz>$4;`*fgdu=%I+h2)h zcd&!X`td+LF>iY2>fgY&?uXxdje-O!E|SSuR@lepwh0|IDeLX%B3wZYG_rSxt=|j( zVy$9Q#XkRz|MT&N3E90BD)PKO`J}p_6lcu*y767{HEevD`i|yI?VPu-CH!_dY5#5{ zYMO(>B2xV*Q}Xz4S~OyG4EvKzVKIA&^qrI67>3zIqN(NAoo}Acopuq)0rMLp&*UF7 zk(Lq>hud!M8WEL0Sbr?8at|bu$R%sAba31xTplaZ42_Vd(@cM1QQd8D$-r7#Il{7?_i*6^p%> zt(85Cle2~6zl)T-xV43uog1^6y@{J!oVtzE{5Q0pQ-{X-eLsr`^Y!7ic>8p!e^Efm z12T$&$W`>M&f7d3##g_+seuq_jnJgkNqfCMG2qzFc^hYxYa0bP+MTv1*0T@J6B2U4 zu~?b+fw7nf%{xW0YBE`xiNpBNY*`x4D91cIcnAp0I|Vn)bij?rYFc2l2{gKXii^Pz zGJKR>s+o&x!Rkh6=!!$jC}k1nxJltI z4yW!6j?0d7wg`EdcA@dum!;a!IKNRdE-&+_1{|W%R5uIuMrkOFR!EI%zf*iDYN-NrX6#k2oz;W z@n_nv-ma#z9ASr5oEB|6?I8tt*+qvpn0BkEXc%8x#pzQP5BRqw$lqe`E3w&dHr27;6$#|x%OLha@CaZP~0)KsYW}X*>xdvDac(t7Cv&?0H4BT3T`4>O* zJiKi+@lJw5R*6o;3|P1hc!5#1cG8PJ z$9kCyQGQC$cf2~QzuQm`DR8MRCDsIp!~4z)KPX}=^0&2{MDT~=v}v|v+z+OX%p+U{ zHwlzjC~m>;aMxmCB(5Ul?;T&UkxU8k7g$5#&2OP-Zjnl~upQA&Syq1rH4gBoQ@)Z@ znt!p7U5k-%8n$s(N$e?)vb$6-G2wC zYanow64R4{!zRK*Go}Or^K>QeZ0(gUgt$AxlegNP@MWb!0YCByLLqDF*o0{J6ta7Y z_`9PC#FCGW2cCo5zR~!H%<;HHBJhEytXVSCR?kdEh73QG^tNSCUH~hX77zP_TvBFlT1vEFMB=~*u`C06pqQ=QXpWPW*U?1m^Ks3!2$=nj zCngu8k8|xtA3}9IaCfixn^~nP_NW+qCGtF@Zo)Q+37@&XkvHR5`@kMmYs)rHZH4heifFnQE7`Gu2}PKHfiDPTYu8I z&&^8I2v78T&P!y-@RQ&{qGIa_7C8)#LV^;|6#?`1^}#I`7&!b2o~qec)D3vGJlXQ| z6cVG3Jyxu&Tv`ul?cfnOuEr`EKS_^l%h?Uk&e<$tAi=#%sTADPE9|8#UCC!Q6vi3V zm6~jse68Il@VOy1!U8u zsqd}_N-3p0U}*3*R&CvBMQ*L(std1*Gx<*!j$JcjUfkX=fb^^INW7+ZA*%9YbR%P%wVey z&S|JF&T%E1*~IhNrXI;KD=};TmYC2cGAZtDKJthB?=@4e3YV+&uU zD&@Djf!h2xETQ#c1whCnCiLIO^+wHt;9NKaiN+=iLc|H)F5oZaLYqCxvazoliGRIa zXNaX7C|$3agv0IY-|&0!*QPG6I)6N8{kYn?s1e!r2gCa}!r^jWNT>`-VE5C@Bg5;@ zpK>{v**D|uSF0a^9)IBM@9gyK>kQSc{?MkvVGV1 zp6Bsv;e{O^GGX1(x}_3Ypw`A~&Z9FC(KFev@-?{o$Vs8=^k3Y1JcTmcQ`xK{r*@VCT}AIU#>>c`(wb!WT4Vy5J+f>k5>vK^o=P1# z47urrHcWivH*&}Rr24I;Oe*KsG#Yk^2=MWIfrx*K2^bujm}P1~JT_G>Ey!9cH2wKA z7{O(%KBmF~Y_{@j88U}$JUX^KQ5gXUgkQ{jACsYdC|AyTz@tjSk)S#!)u~BJ+`?St z8dyTF!444fL9GI!98x@7OAC(TXeGTvDQ}Pwyd~w`GOF@MAWfw>kV>8RyRuN%S__N0 zAxNEyeCraecOURCG?I7^LI`u^mE;>RN8vD!aZ9&<-GnW@pim!^jH9&}iybnN$shM9 z7AFhR7-&rH5hM;nnPud(q==hNOpFLeAaZ~%bLgJY1Vv+U-D?K@N)_9O+l`MdNi&ve zW<`aUF*xev>aA3UR{UqIw4No#3RY z1sv_&k%b@ln>j@62zL3`j?sUIGaPHTxElft3>+E^jP3sjPMQCUPPJ84Oi`>(WHvGr z?eF^ENCP9`_4J*gn^?cmm(^kgb*N^`2yn{#sx}Nn8&SOm3;)ZF`gM3piNShftmU!o zaMk*}arN@}HmpRhTl}mNtxPT{lQBQ+$1)K{tQ$Lv@t6F8S4@fgAy%a^anio#lH|gH zm0*nIodj*A_YWM0snTfO5 z%(Z>QpzJc0We1N9bNO3Z$=~g!1jU^UQ?)ahff|~QqTvba1NJbv>|qxDLCZY(%Og+C zpj|1)v#qzF?%Q3`hW3^e7@#QIS=**8Der zJ#q_Io`nePD)zO?F&((JG-=p!=`tMIGJ+Qv_}%wo`?e#qxoKOZFkp9Kk%c)P&|JaR z7|k(}8*}<2xu`#XrS{K?{C65G)A@ey|I?e;|4qG775o3zoAv+DoA57%tN|CK!(U)R zkkDevbkf*764Gc;u2{-+RJhJfGB{p(!_|IpXB0QQ(xgzh|B+V<@+up{R@KwndhztM z`b>ZPeEry`3G~=_QtnkHLP-Sx!_T=kN=+nsh$^JR*tH-kJ}8lw3liE*8dEPS(vBp) z(g|>O<$hbRt1C6G)lHEg3R*uaV)Q8GyKE6U~?p$)w?%!+R*0&-bKr_{rL{=sa>M(n%xBttB$tLf-&sF4%FV`laQb+ zCIE@n^bTQF{{4R{4tqL{YuYEKlv!pr3+?123um_FUk!)WZI!1RrI7}WPP3IC4E4~< zP()FjFU_%Vmlmp{bJ(h@a~l5?CsnA1tXNn>td=80gb@Kxf_oOaim%uBnF_Rl%-#2{Efz9uf~H% z2v|j#`PzZ@57gTE3r(qR_(C0;_HR2~zJx7?jhB_@Qx;#t{>RJPxfhrjux76^e3Q1E zw`8vaK}{S2my;F!l z2gtZYO^;7@@|iYS0>7x(-Sl|CnuFaIiv3!)vjNLNa5g1Lwa{@52$15$J9!$v4~G@} z)AZrDR4$j?R=t4$p;aW{#fRPmG*KKI{SibfsX@4;tGTjC(GW~W|*&qA;$d{wK8@mz8@D3SYQ&Y^zF;Gj+{uQV|=xly8I-CiMRY=0}87u39% zqmNQGIyILJstu2`r8Lf4))&cdtrw4C}LL5#5Yx&O2rrKH3NNkoJHu$-EImJ|HXa*QBg;iI?g`#QxW+GT6a zGSj5Oiiq#8+Ke?zA*9;v-ASn-)xxHwYregGKTm^NDjLgluWUr2t#C&g78RLYLLcJY z+ia&l(5yW-3U!%tvr_9!0sNQdDDA0-dI@;Qk1=tYe45 z^0{a43KU`ompnjN3^+jj?{r?ef&2&mX%6B4rsn)lI{zQd(NR-l!}^41!X2|fcL5jG ztYeZ>ae?;G7OUYD}WU*_vgg@W^2V-X$8(FiYX)`mk+sw?^ zW@ct)W@ct)<~DPi8QTnHYBRgc(B?L*?|!q=+|kVLN?EG>aa2-C8JTZ9Coc9C$o*%~C28yBy)oRi8IYsB%6kgb)MC7JYFgDa#cH6T$+NF_sYwX_r?u`w zy|A$;q0!{ab^DVh!xuU~398I)GK$&i*QiUX^`5jT}P<)p=I9pWbh@(bs9?*EBaq1F(#i(XMXiJ0TlHGW34uVNgm$R%F4y7O|_8}3L5cO4T zQ4+^8Z_(ypy?7w1NLXz@v8-zl+MfH*D~;oyL8RNI?5|2Iq%4*C-i+~->uTzWb|1JIhC#92~ zGV`T$Fv91^6)w0V?lM8-W#KXKNEbqkG)E|54ylX4DB!i^QwH-_n&>_u9#FjqzCaG- zmr)AIEQ0#)MwmAKr(8bQ>rPMp?}7fGpt~fT{!5K3L7@+n^#>8Lxs03;JykL4p z_!Zi%gn`^q`$XH(onQxnD=WJ-Z$==%IvYiCGUiQQ~yPOqnF zHnO7mmDopiwao%N38$URa#XBD6LPsP(Eyr9cgA_(KNJVT_#cYHD4?YlaKJu}bhMK> zQ8sVgoO@QrY&{yJe`;1hq_T1yag2)~H~PTO&;r{_$_`0Lj7sM-IXtzjXWqqqT#z+6 z+84z4w{$XRO3%ETHI?ny*It!>x#Guc|M>=Qk}K}Oa2?3MI1Y42lq}fOXSZhK2M1@kd8Hg~1y$iBbV?L|z9}pQ9$MMed|{l~Nt-F_<@JZQCq#APz;Hj^W!;G0 z7Se{@>>|}6{3nj1u7-hf#${bMg8Wunq9ndyjXMs;*4O!;ISxnz z@IP}LWiRT>>8tH-&$-T%?U|3)KbO!!u>2~{%EQ7KYI-Ux^+QWZ1LlZu^#no$nt;|W zN>a)ZCw=f?M3zl8=U5W`yUnDH`Xe@=dFFA-aOeOWP731Ae(|UhGi_(}377oIR!xPe zk0X6%#rSgMib=P2OGpq`-9HdV-%Lqn8!dlQ4c5JFOQ-dXrw^F)qyLPfqh-KfcP*K% zWzz${__9+`U;|McuXZS@dF$JuLnzo?uS#ZgcLUL4_1KOWP)AZUpDC5)x%M)`V@jtH zJlErg-YR@&5oOcxvgR8@pyQqW51tJVf?$!xKN8o{7eCY{y4!3cQxTlW+J(~L4cF7A z0#GnYNfm75=`QS2W zw$%>653%zLvU4%RosCpPT90B=jk4*gbVk18#39xhi&qc~7< z|HaCfaDpRfKVgwO2qGRkX$Xgv`PVFo?78Vb1V_OYjtcl)s*mJf1jkfJ{4M&6;NVmc zn6O6THjj2rTfGibRoY?FnwLtXv6@Si($Khd&bm>PH^yXXpk+~&&ZFjpk1a?Yz>^;q zC;Lh28rbmBw;uJAiq8SQgZ+h#F)$zMRS@qMZbawHk_;z%Y*b>0mOlU{TUlaQ6@TF}~zO)VF z|9?>ahp>rPJyrSdgpG4jxoQQNXmMcnJ*NR!duM+4QdM8t6!Co|@~$XPL95hM>vUH3 zA^pV5?2AImPGGmd<@SSegB)|<5f)rc!S%HHk(FSo`~ z<}86D%mSB=X4TGt)JX$lW_#4bvO2FXzZqld0xM72<~=Oy_V0A*YlyOtdxUo(Wb75T z&Qx;(RhRIVYXB<8ONSA{A;Hk02iW~O--`u326?bXp8LGdTmm)tZ} zkiJzDN2%CkKGNR_ckNrdwi7h#;%Dj8Q*gsDIxNbsIdDT=V(m$$6IK2g$(AW)_( zwZ_oJBDUBryOgC2;)z=7X<|)v7F$N!S9P=aAfAeESw`&D(AQ&p-*&^^C~j`e<--*x z|L!E4xg)x(d!4ZO7upw}(getIvpE9a!+s0bApaGATO3uAoq3fwS}aX5TnM+Hy#x`# z5}3Z>s>YB|D^Z%Vrc9z1cW#dCGjS?I8%`b9@Fi>jH04@a|Ldxm>Q`(z$2Kd>6@gr< zl^rnkd0o%TZWY&tZqG_jh9G(B@$mqqB_Kk}?TX~qV}7FE9L*#!);&1L8tGgEAQ_kB zP?EVK*o-C3dif6Z7;XmrY8}7g2f!&>uDw2>gpy|69GVxuuoSsiI!QS=0a~%~J-h`= zAs8|hr$#NjM%8kcODCn1H}ZfLjuX-wg~{NRzSGd3-XEUN)0~~!uG`-=!2qts0Hizh z!jmvFe+4Brs!i>Ck@3#FMDvR>p1qCGYvNDu!~p*o6hM>KAecMN{6( zW>RWPQBy6=Mr<-~Af^_s`u|9d;K-@y?)vG zD*{HY<#g-+wCy^M`^j@s;5jkezvIV;`sGX(jg$^#jz-D^!r;sQAe%a+=3SQv;2o0~ zUvxggC_6Cc9gH|aSHH=#Da{A6<6{C&N5%fiA1&ds=0{IBJKjxb=N;K)&nidX0!|iA z{f_*$^}hkaX)zZ@Ilruoe+GBOF&Q!fFln_^IlsKbn}V-(vg=b%eWD#27vj@0PARh; zGET9w9nw!ZvmH(zH%S2btXmX-E!HhEKribS72us!;2R*6Re&5Y%ql<%DAgM=Wffoq zpmX}96f`dY?hzuNYvtx{Z@se(b`N4%dq?EGv@0~teA1bEDFNqxexaU@Lw0>HScN?^ z-JV`gjGhxyXuac=cBMw-R}JGtTZ!xj?>P>N73{6+I0s3aXb z;z3kJj=-^3TeDp;kxGQXd#79hhtv?e$_iyEpz-cjVhV>8vSY$$mIM7wEI;=N3SFW{ zH}QP$7ML|-^^?U7fd)4*OZ$Ll3F1?`&kp&H&d_-40;-s{i+|6S z(7B{q=&p^ueJ|!jUn3D!La!qr+^15r1R3)+3L(6$7!u9DcAo0KN~Cb%B+jPo)XCBE zTK-$+g+bJ%(}pfy&LyA3fd?6pBykKB*qWWvmwy-pde&R=$i=3d~vXg={iRpiUnJZ?QK;>Cv_j0Jz4@KK7L)isE$`KW)<5$=7K!N50bG}rwVOAGoBVuX00l$6UD&@~*>c_qTQ z)~R8%YhY1X35*VkQiHTfWx&K7E;XyR@s3}c=w#7MofUsX-N`v-Bx7$sLw(JqHf4dH zq>7FgtXTjjAv~@TwJD}eAghrqHKfFeYxgc)QPIw-u%MBIv@>V-a$^F>MbXwXq}B%3 zr=H+|NMYZ%a&$l2{V=O`A#-l~_`%KAArpCG9Z>a>_vjGWU`aPku(jn- zH?vUc-Hns(cN{p-=1;PK5@7mm#e5u^&EKUnyGsJFyPegDJZgfbh)tJl92`; zFJLMZ&TM2g-WTut!OzX|9VOePx>33o4pQ7zL=#XCXir;{fz!>dBW;?1(@j^WYmE|d zI#&u;wc<+9oK@qPe%f`NU?X>g%gq7g7Rvo*HL$>h4ENZ3qo`~s@+{BC#5;sv#)TF2 zRD_w(k!J~*Kh#etG_a0)0-qdL>9gzLJb2S#)8T0-7`V;A8$GqTywuvgzU?G{0l-0; zk@nwk;8gj}%CY!K!Gv^^HHZ@G}E6%@6%93TW26k(jB*o*6$(vOn`>gMf&X$&KMrq&lXvrE$? z$wg74>Ygp9z_;^{a8|vl-+P zw^KOEtD$ua8zAyTyd}i?xP()#UbywnYPf@_Tl=^e?%}q6{$IQe%iSx(%-md8G{_yTk)4itD-MSX% zJ21F;@#lP?i_?wMbhsqd@H64JDj1d3M(P{cqF14OhROicF*@rYgg6Q}8Z$_g*zl}6 z5%YfK7BS&ykJs$AhSmgeHO)kr?D&42Ix}H9bQ0Yrg?tSkeEFSfuZX~!6rWGT)|Iz~ zPV{n2YRb5uy8Icad0>YyvFA> z1wB^h)wVyDa?*5iRnAq;;?i^qMeHn(_gkSRfaq$X(qcB)BjzaW#-29C0;uJ^sKx%S zGzmDPG{Mfrzci{UqCTDBXKKT_Ea^7`?#wrZ2I&VyxW+i+h~hT)8RPIIm?XHy9O4Y( za!v1z4{3dtBhuEhRB~0$YSVagbsIPn!5Xm;NH7$s2t)395UgDxyn)nZ(<~iJbK^2*!F zmfTg&x@g>cl`Rx1Snq%AQRWH9yJ5{#xF-EQ*~8Lfo^Fk|c3xqRmN{qBxV$qQ|5O?I zbQ$PGQ&Nfgc1nvoUXl%cP<^4Iq)rfHLU~M0ndX(MDyKk##usZ$AQ5>y zb{L^@DjbD`sj98@I%7G&TcVq)v==;wgT3H0-l}C`MOc^E9%)^V9Xdx<-%!j2e6RX9 zjCBBixDWp8>h3nz?smJ9{f;oqwrKo2NZ(78&h1octe|N6yGhmp(Yk=G8)P~c=8?k) z(Pzm{U-(X6N-u2yj zom@V5r7Gc!{U=JXJ6|KA~AEgH2to|>;`SZqVWcM;+1^fX__AvGQd1!kL zeXOPJ#zbcs?wTmop<@%_OYmwjCFQhf72!*0nd;VCXnm+r)uc)AvgIm5GG#g3gc9^D zcHtTDf*E@LRGG!YSrFQ~A=e=`uz5A(M&zJ3kR@=T-X(}~*TxN4DcuShR{@*7TTI3S$4yJC_ zjt>8)#5GOY^ga%j^KoaougZF0a4$`GGqT#nKRn3xEErjK_>_c(N0)VMo$P2MrLYz%& zgJ$wj-K3mS>{6j<0dXB=e){>+qyzw=`XFsbLh5Fk)fnislav{6EH`<>U0Q@uCY$j& z3Fn5o@=_GYY49e>e~CO*{!uy3k&!OEb`du1L`NUqOR6zTH=9dBAj2GKGLSKDbMJAx zK%}u;$bKvfucsN0hZBdl)mEdHv|g~@w3(e&`k7|RnwIW2FtOS$Lx(|UdbQXCXlxub z(>HcU?C8VSZ*S~kQf+Ib#9kt|XXxtdSP%CK(Td22UT70fOT?az-c8_C^UiW&Uvpo3a&o4ltc?Dub%FmNz7=q zSH)vF*yN1)4$E%W6H<~|?VE1sn;~RHCIXNkW>xDkKzW)QV`;N*=JRiL?&)`nUat;3vvRQDWueeW9Z+jTaAHL>81)%-Q>1pA7$ zLRX^$0_ao>yP44VKXx#tYIb^7t5|c;gn&^GdkY2X8H%<=vv*D=PDWQVQ@w|nc}z1j zt;WWao%iyVLo5q{@dnFl#kteHo##w}JV}X5e^Xj5C)<=R{|=@Wldz#9=9E9bcQO|+ z?EjiB?5^FI9s0P1C=4@<%n{Wtry*1|Px*h|9-8O{(5TcKUeCoT4SzhYEKQMd%LMxL zuFa;xpd{iFaq$~_E#9OVuiUim;SRS%oFL5M8!-1+c}?6j?_tiU-!#%OK3(fJwV67tW$bwhQ8gZGyRB@p}l3Z_(&n6yLEHMB{9QS`wHOl zeF|KM$jn=6YWQt7BjAMJ=ae_Wfqwuit&tdgDMy-jjJ5X#BVQuC4_SGX?Aa^MoPW@k ze-xj8SeJjCuV=uQ+l^B6mB7(7DXZiM@mJNe$zR2P59a{o%IQ1AFK$K#0)qEHg!4b3 z;HNgU7J)iS0kp5D6TP|+tdmJx%vcm*w+iEJ5=vQg(=Jqo*KNlz9qI+g;};wl3qkx3 zOz=?H?(6G2RSf)bcyKvQ_vhoqa=T~i=H{AfM?vg7#)7F%QqdQP%VfR)=xh}f$d#R2 z_+!A%)3c-k;z!n?zO!^-#ZL`eK+8{`6Srz9<&

w?2 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 =tjc35g zk9qY_1~7|8Vt6lI1#CTa>@NAx2SG+`KN&oCq59Cj!Sx)y7i~2NL=5$Xc!=Kmyj&`f zKFW=~7)9r56VWFW<@|?TBTNFHJ1aN{NZgPAUOdS=*qVN2|2T>n+x+j~%%&vsf5f5$ zZ^`Ml%|-8g(Sdbqu$Gvw`H|P?p=$BN=yz9PAUXqEg>+^#R8I?bE0)x`TA5 z7He8(%FU(^<={5g?lxa{z^j6X!C1q^`Yd_$TvqrbNS$ef<||HF;qt0Y48grY1VOt; z`A==R9yyQxYyJ?U;KE8gwu){gN4GMndWBV-ey_dO);;Y~Uf_c){P?`FF6!QZRt9oP zu{1Ithw&X5AX3Td`U7zN~~#Re$`bZ$zt*; zO6E&78=jMAa%vQm{xjRjBJC3SoWx?T@$nh?vV6fkbFPUkS$MZ>&MN&Ct;5uDXslqG zn;vR9+lL!r$G%Y8!>ep&>4$TdmSJi`4-1;zavP*6AH%d*31CmiNQlH zHnK{Yojk9-&#je=heV_(pW3dQah=*d@;gW^y9YzLq=s!?hrne@JRG$sR_tbKs5K{; zn+dr#099Ky{qXOUpptyAS3#XbBk>T1T5xEvE&y))E(J0d87!*Zh#ycA&lPTY*&-Lp z#ttsg?ib8&0aQjX$fDyBBs^m5`BzU9>a>fvBP)#~?pb3Ml?G zjv;pDxjRT(4TAXiW}!&G03Eg;T&$T!A2;UB%ve-G#FFYQO*pei=Jx~jRJ8NW_%KfT zq<_u#TR^_42k3Eda83Tji>gBM{&B&(>R>zj8Men(S+L)Oe1Lwr9R2{PD2{+z9(BQI zo3)vm=KQ|6YVtAguH|{p3YwLVlVxGrWslm4XXJfz87HVBwMVSEjw*7K3SDXT zC7$YH{0jLy1%ksGp;La&2xmSf+v21i`L30*Er!c{!}&#@PWzc6Tcg~$VM#|TQNdC6n3gh)fHlI*K!G(R7R7m9TUnTf7YPz7F^`=D4<2C8>0zAvqCADgAf0RQY+ zUB2Mpf58n|N|IksUDVHXQsU6J?yK

F&PNDcxn0T?K3UipDSQoIoVbnpWHL8=;^ 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 mapping data structure that is + * designed to be more memory efficient than a traditional {@link java.util.HashMap}. + * It keeps its mappings in an array data structure -- an integer array of hash + * codes for each item, and an Object array of the key/value pairs. This allows it to + * avoid having to create an extra object for every entry put in to the map, and it + * also tries to control the growth of the size of these arrays more aggressively + * (since growing them only requires copying the entries in the array, not rebuilding + * a hash map). + * + *

Note that this implementation is not intended to be appropriate for data structures + * that may contain large numbers of items. It is generally slower than a traditional + * HashMap, since lookups require a binary search and adds and removes require inserting + * and deleting entries in the array. For containers holding up to hundreds of items, + * the performance difference is not significant, less than 50%.

+ * + *

Because this container is intended to better balance memory use, unlike most other + * standard Java containers it will shrink its array as items are removed from it. Currently + * you have no control over this shrinking -- if you set a capacity and then remove an + * item, it may reduce the capacity to better match the current size. In the future an + * explicit call to set the capacity should turn off this aggressive shrinking behavior.

+ */ +public final class ArrayMap implements Map { + private static final boolean DEBUG = false; + private static final String TAG = "ArrayMap"; + + /** + * The minimum amount by which the capacity of a ArrayMap will increase. + * This is tuned to be relatively space-efficient. + */ + private static final int BASE_SIZE = 4; + + /** + * Maximum number of entries to have in array caches. + */ + private static final int CACHE_SIZE = 10; + + /** + * Special hash array value that indicates the container is immutable. + */ + static final int[] EMPTY_IMMUTABLE_INTS = new int[0]; + + /** + * @hide Special immutable empty ArrayMap. + */ + public static final ArrayMap EMPTY = new ArrayMap(true); + + /** + * Caches of small array objects to avoid spamming garbage. The cache + * Object[] variable is a pointer to a linked list of array objects. + * The first entry in the array is a pointer to the next array in the + * list; the second entry is a pointer to the int[] hash code array for it. + */ + static Object[] mBaseCache; + static int mBaseCacheSize; + static Object[] mTwiceBaseCache; + static int mTwiceBaseCacheSize; + + int[] mHashes; + Object[] mArray; + int mSize; + MapCollections mCollections; + + int indexOf(Object key, int hash) { + final int N = mSize; + + // Important fast case: if nothing is in here, nothing to look for. + if (N == 0) { + return ~0; + } + + int index = ContainerHelpers.binarySearch(mHashes, N, hash); + + // If the hash code wasn't found, then we have no entry for this key. + if (index < 0) { + return index; + } + + // If the key at the returned index matches, that's what we want. + if (key.equals(mArray[index<<1])) { + return index; + } + + // Search for a matching key after the index. + int end; + for (end = index + 1; end < N && mHashes[end] == hash; end++) { + if (key.equals(mArray[end << 1])) return end; + } + + // Search for a matching key before the index. + for (int i = index - 1; i >= 0 && mHashes[i] == hash; i--) { + if (key.equals(mArray[i << 1])) return i; + } + + // Key not found -- return negative value indicating where a + // new entry for this key should go. We use the end of the + // hash chain to reduce the number of array entries that will + // need to be copied when inserting. + return ~end; + } + + int indexOfNull() { + final int N = mSize; + + // Important fast case: if nothing is in here, nothing to look for. + if (N == 0) { + return ~0; + } + + int index = ContainerHelpers.binarySearch(mHashes, N, 0); + + // If the hash code wasn't found, then we have no entry for this key. + if (index < 0) { + return index; + } + + // If the key at the returned index matches, that's what we want. + if (null == mArray[index<<1]) { + return index; + } + + // Search for a matching key after the index. + int end; + for (end = index + 1; end < N && mHashes[end] == 0; end++) { + if (null == mArray[end << 1]) return end; + } + + // Search for a matching key before the index. + for (int i = index - 1; i >= 0 && mHashes[i] == 0; i--) { + if (null == mArray[i << 1]) return i; + } + + // Key not found -- return negative value indicating where a + // new entry for this key should go. We use the end of the + // hash chain to reduce the number of array entries that will + // need to be copied when inserting. + return ~end; + } + + private void allocArrays(final int size) { + if (mHashes == EMPTY_IMMUTABLE_INTS) { + throw new UnsupportedOperationException("ArrayMap is immutable"); + } + if (size == (BASE_SIZE*2)) { + synchronized (ArrayMap.class) { + if (mTwiceBaseCache != null) { + final Object[] array = mTwiceBaseCache; + mArray = array; + mTwiceBaseCache = (Object[])array[0]; + mHashes = (int[])array[1]; + array[0] = array[1] = null; + mTwiceBaseCacheSize--; + if (DEBUG) System.out.println("Retrieving 2x cache " + mHashes + + " now have " + mTwiceBaseCacheSize + " entries"); + return; + } + } + } else if (size == BASE_SIZE) { + synchronized (ArrayMap.class) { + if (mBaseCache != null) { + final Object[] array = mBaseCache; + mArray = array; + mBaseCache = (Object[])array[0]; + mHashes = (int[])array[1]; + array[0] = array[1] = null; + mBaseCacheSize--; + if (DEBUG) System.out.println("Retrieving 1x cache " + mHashes + + " now have " + mBaseCacheSize + " entries"); + return; + } + } + } + + mHashes = new int[size]; + mArray = new Object[size<<1]; + } + + private static void freeArrays(final int[] hashes, final Object[] array, final int size) { + if (hashes.length == (BASE_SIZE*2)) { + synchronized (ArrayMap.class) { + if (mTwiceBaseCacheSize < CACHE_SIZE) { + array[0] = mTwiceBaseCache; + array[1] = hashes; + for (int i=(size<<1)-1; i>=2; i--) { + array[i] = null; + } + mTwiceBaseCache = array; + mTwiceBaseCacheSize++; + if (DEBUG) System.out.println("Storing 2x cache " + array + + " now have " + mTwiceBaseCacheSize + " entries"); + } + } + } else if (hashes.length == BASE_SIZE) { + synchronized (ArrayMap.class) { + if (mBaseCacheSize < CACHE_SIZE) { + array[0] = mBaseCache; + array[1] = hashes; + for (int i=(size<<1)-1; i>=2; i--) { + array[i] = null; + } + mBaseCache = array; + mBaseCacheSize++; + if (DEBUG) System.out.println("Storing 1x cache " + array + + " now have " + mBaseCacheSize + " entries"); + } + } + } + } + + /** + * Create a new empty ArrayMap. The default capacity of an array map is 0, and + * will grow once items are added to it. + */ + public ArrayMap() { + mHashes = EmptyArray.INT; + mArray = EmptyArray.OBJECT; + mSize = 0; + } + + /** + * Create a new ArrayMap with a given initial capacity. + */ + public ArrayMap(int capacity) { + if (capacity == 0) { + mHashes = EmptyArray.INT; + mArray = EmptyArray.OBJECT; + } else { + allocArrays(capacity); + } + mSize = 0; + } + + private ArrayMap(boolean immutable) { + // If this is immutable, use the sentinal EMPTY_IMMUTABLE_INTS + // instance instead of the usual EmptyArray.INT. The reference + // is checked later to see if the array is allowed to grow. + mHashes = immutable ? EMPTY_IMMUTABLE_INTS : EmptyArray.INT; + mArray = EmptyArray.OBJECT; + mSize = 0; + } + + /** + * Create a new ArrayMap with the mappings from the given ArrayMap. + */ + public ArrayMap(ArrayMap map) { + this(); + if (map != null) { + putAll(map); + } + } + + /** + * Make the array map empty. All storage is released. + */ + @Override + public void clear() { + if (mSize > 0) { + freeArrays(mHashes, mArray, mSize); + mHashes = EmptyArray.INT; + mArray = EmptyArray.OBJECT; + mSize = 0; + } + } + + /** + * @hide + * Like {@link #clear}, but doesn't reduce the capacity of the ArrayMap. + */ + public void erase() { + if (mSize > 0) { + final int N = mSize<<1; + final Object[] array = mArray; + for (int i=0; iminimumCapacity + * items. + */ + public void ensureCapacity(int minimumCapacity) { + if (mHashes.length < minimumCapacity) { + final int[] ohashes = mHashes; + final Object[] oarray = mArray; + allocArrays(minimumCapacity); + if (mSize > 0) { + System.arraycopy(ohashes, 0, mHashes, 0, mSize); + System.arraycopy(oarray, 0, mArray, 0, mSize<<1); + } + freeArrays(ohashes, oarray, mSize); + } + } + + /** + * Check whether a key exists in the array. + * + * @param key The key to search for. + * @return Returns true if the key exists, else false. + */ + @Override + public boolean containsKey(Object key) { + return indexOfKey(key) >= 0; + } + + /** + * Returns the index of a key in the set. + * + * @param key The key to search for. + * @return Returns the index of the key if it exists, else a negative integer. + */ + public int indexOfKey(Object key) { + return key == null ? indexOfNull() : indexOf(key, key.hashCode()); + } + + int indexOfValue(Object value) { + final int N = mSize*2; + final Object[] array = mArray; + if (value == null) { + for (int i=1; i>1; + } + } + } else { + for (int i=1; i>1; + } + } + } + return -1; + } + + /** + * Check whether a value exists in the array. This requires a linear search + * through the entire array. + * + * @param value The value to search for. + * @return Returns true if the value exists, else false. + */ + @Override + public boolean containsValue(Object value) { + return indexOfValue(value) >= 0; + } + + /** + * Retrieve a value from the array. + * @param key The key of the value to retrieve. + * @return Returns the value associated with the given key, + * or null if there is no such key. + */ + @Override + public V get(Object key) { + final int index = indexOfKey(key); + return index >= 0 ? (V)mArray[(index<<1)+1] : null; + } + + /** + * Return the key at the given index in the array. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @return Returns the key stored at the given index. + */ + public K keyAt(int index) { + return (K)mArray[index << 1]; + } + + /** + * Return the value at the given index in the array. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @return Returns the value stored at the given index. + */ + public V valueAt(int index) { + return (V)mArray[(index << 1) + 1]; + } + + /** + * Set the value at a given index in the array. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @param value The new value to store at this index. + * @return Returns the previous value at the given index. + */ + public V setValueAt(int index, V value) { + index = (index << 1) + 1; + V old = (V)mArray[index]; + mArray[index] = value; + return old; + } + + /** + * Return true if the array map contains no items. + */ + @Override + public boolean isEmpty() { + return mSize <= 0; + } + + /** + * Add a new value to the array map. + * @param key The key under which to store the value. If + * this key already exists in the array, its value will be replaced. + * @param value The value to store for the given key. + * @return Returns the old value that was stored for the given key, or null if there + * was no such key. + */ + @Override + public V put(K key, V value) { + final int hash; + int index; + if (key == null) { + hash = 0; + index = indexOfNull(); + } else { + hash = key.hashCode(); + index = indexOf(key, hash); + } + if (index >= 0) { + index = (index<<1) + 1; + final V old = (V)mArray[index]; + mArray[index] = value; + return old; + } + + index = ~index; + if (mSize >= mHashes.length) { + final int n = mSize >= (BASE_SIZE*2) ? (mSize+(mSize>>1)) + : (mSize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE); + + if (DEBUG) System.out.println("put: grow from " + mHashes.length + " to " + n); + + final int[] ohashes = mHashes; + final Object[] oarray = mArray; + allocArrays(n); + + if (mHashes.length > 0) { + if (DEBUG) System.out.println("put: copy 0-" + mSize + " to 0"); + System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length); + System.arraycopy(oarray, 0, mArray, 0, oarray.length); + } + + freeArrays(ohashes, oarray, mSize); + } + + if (index < mSize) { + if (DEBUG) System.out.println("put: move " + index + "-" + (mSize-index) + + " to " + (index+1)); + System.arraycopy(mHashes, index, mHashes, index + 1, mSize - index); + System.arraycopy(mArray, index << 1, mArray, (index + 1) << 1, (mSize - index) << 1); + } + + mHashes[index] = hash; + mArray[index<<1] = key; + mArray[(index<<1)+1] = value; + mSize++; + return null; + } + + /** + * Special fast path for appending items to the end of the array without validation. + * The array must already be large enough to contain the item. + * @hide + */ + public void append(K key, V value) { + int index = mSize; + final int hash = key == null ? 0 : key.hashCode(); + if (index >= mHashes.length) { + throw new IllegalStateException("Array is full"); + } + if (index > 0 && mHashes[index-1] > hash) { + RuntimeException e = new RuntimeException("here"); + e.fillInStackTrace(); + System.out.println("New hash " + hash + + " is before end of array hash " + mHashes[index-1] + + " at index " + index + " key " + key); + e.printStackTrace(); + put(key, value); + return; + } + mSize = index+1; + mHashes[index] = hash; + index <<= 1; + mArray[index] = key; + mArray[index+1] = value; + } + + /** + * The use of the {@link #append} function can result in invalid array maps, in particular + * an array map where the same key appears multiple times. This function verifies that + * the array map is valid, throwing IllegalArgumentException if a problem is found. The + * main use for this method is validating an array map after unpacking from an IPC, to + * protect against malicious callers. + * @hide + */ + public void validate() { + final int N = mSize; + if (N <= 1) { + // There can't be dups. + return; + } + int basehash = mHashes[0]; + int basei = 0; + for (int i=1; i=basei; j--) { + final Object prev = mArray[j<<1]; + if (cur == prev) { + throw new IllegalArgumentException("Duplicate key in ArrayMap: " + cur); + } + if (cur != null && prev != null && cur.equals(prev)) { + throw new IllegalArgumentException("Duplicate key in ArrayMap: " + cur); + } + } + } + } + + /** + * Perform a {@link #put(Object, Object)} of all key/value pairs in array + * @param array The array whose contents are to be retrieved. + */ + public void putAll(ArrayMap array) { + final int N = array.mSize; + ensureCapacity(mSize + N); + if (mSize == 0) { + if (N > 0) { + System.arraycopy(array.mHashes, 0, mHashes, 0, N); + System.arraycopy(array.mArray, 0, mArray, 0, N<<1); + mSize = N; + } + } else { + for (int i=0; i= 0) { + return removeAt(index); + } + + return null; + } + + /** + * Remove the key/value mapping at the given index. + * @param index The desired index, must be between 0 and {@link #size()}-1. + * @return Returns the value that was stored at this index. + */ + public V removeAt(int index) { + final Object old = mArray[(index << 1) + 1]; + if (mSize <= 1) { + // Now empty. + if (DEBUG) System.out.println("remove: shrink from " + mHashes.length + " to 0"); + freeArrays(mHashes, mArray, mSize); + mHashes = EmptyArray.INT; + mArray = EmptyArray.OBJECT; + mSize = 0; + } else { + if (mHashes.length > (BASE_SIZE*2) && mSize < mHashes.length/3) { + // Shrunk enough to reduce size of arrays. We don't allow it to + // shrink smaller than (BASE_SIZE*2) to avoid flapping between + // that and BASE_SIZE. + final int n = mSize > (BASE_SIZE*2) ? (mSize + (mSize>>1)) : (BASE_SIZE*2); + + if (DEBUG) System.out.println("remove: shrink from " + mHashes.length + " to " + n); + + final int[] ohashes = mHashes; + final Object[] oarray = mArray; + allocArrays(n); + + mSize--; + if (index > 0) { + if (DEBUG) System.out.println("remove: copy from 0-" + index + " to 0"); + System.arraycopy(ohashes, 0, mHashes, 0, index); + System.arraycopy(oarray, 0, mArray, 0, index << 1); + } + if (index < mSize) { + if (DEBUG) System.out.println("remove: copy from " + (index+1) + "-" + mSize + + " to " + index); + System.arraycopy(ohashes, index + 1, mHashes, index, mSize - index); + System.arraycopy(oarray, (index + 1) << 1, mArray, index << 1, + (mSize - index) << 1); + } + } else { + mSize--; + if (index < mSize) { + if (DEBUG) System.out.println("remove: move " + (index+1) + "-" + mSize + + " to " + index); + System.arraycopy(mHashes, index + 1, mHashes, index, mSize - index); + System.arraycopy(mArray, (index + 1) << 1, mArray, index << 1, + (mSize - index) << 1); + } + mArray[mSize << 1] = null; + mArray[(mSize << 1) + 1] = null; + } + } + return (V)old; + } + + /** + * Return the number of items in this array map. + */ + @Override + public int size() { + return mSize; + } + + /** + * {@inheritDoc} + * + *

This implementation returns false if the object is not a map, or + * if the maps have different sizes. Otherwise, for each key in this map, + * values of both maps are compared. If the values for any key are not + * equal, the method returns false, otherwise it returns true. + */ + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object instanceof Map) { + Map map = (Map) object; + if (size() != map.size()) { + return false; + } + + try { + for (int i=0; iThis implementation composes a string by iterating over its mappings. If + * this map contains itself as a key or a value, the string "(this Map)" + * will appear in its place. + */ + @Override + public String toString() { + if (isEmpty()) { + return "{}"; + } + + StringBuilder buffer = new StringBuilder(mSize * 28); + buffer.append('{'); + for (int i=0; i 0) { + buffer.append(", "); + } + Object key = keyAt(i); + if (key != this) { + buffer.append(key); + } else { + buffer.append("(this Map)"); + } + buffer.append('='); + Object value = valueAt(i); + if (value != this) { + buffer.append(value); + } else { + buffer.append("(this Map)"); + } + } + buffer.append('}'); + return buffer.toString(); + } + + // ------------------------------------------------------------------------ + // Interop with traditional Java containers. Not as efficient as using + // specialized collection APIs. + // ------------------------------------------------------------------------ + + private MapCollections getCollection() { + if (mCollections == null) { + mCollections = new MapCollections() { + @Override + protected int colGetSize() { + return mSize; + } + + @Override + protected Object colGetEntry(int index, int offset) { + return mArray[(index<<1) + offset]; + } + + @Override + protected int colIndexOfKey(Object key) { + return indexOfKey(key); + } + + @Override + protected int colIndexOfValue(Object value) { + return indexOfValue(value); + } + + @Override + protected Map colGetMap() { + return ArrayMap.this; + } + + @Override + protected void colPut(K key, V value) { + put(key, value); + } + + @Override + protected V colSetValue(int index, V value) { + return setValueAt(index, value); + } + + @Override + protected void colRemoveAt(int index) { + removeAt(index); + } + + @Override + protected void colClear() { + clear(); + } + }; + } + return mCollections; + } + + /** + * Determine if the array map contains all of the keys in the given collection. + * @param collection The collection whose contents are to be checked against. + * @return Returns true if this array map contains a key for every entry + * in collection, else returns false. + */ + public boolean containsAll(Collection collection) { + return MapCollections.containsAllHelper(this, collection); + } + + /** + * Perform a {@link #put(Object, Object)} of all key/value pairs in map + * @param map The map whose contents are to be retrieved. + */ + @Override + public void putAll(Map map) { + ensureCapacity(mSize + map.size()); + for (Map.Entry entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + /** + * Remove all keys in the array map that exist in the given collection. + * @param collection The collection whose contents are to be used to remove keys. + * @return Returns true if any keys were removed from the array map, else false. + */ + public boolean removeAll(Collection collection) { + return MapCollections.removeAllHelper(this, collection); + } + + /** + * Remove all keys in the array map that do not exist in the given collection. + * @param collection The collection whose contents are to be used to determine which + * keys to keep. + * @return Returns true if any keys were removed from the array map, else false. + */ + public boolean retainAll(Collection collection) { + return MapCollections.retainAllHelper(this, collection); + } + + /** + * Return a {@link java.util.Set} for iterating over and interacting with all mappings + * in the array map. + * + *

Note: this is a very inefficient way to access the array contents, it + * requires generating a number of temporary objects and allocates additional state + * information associated with the container that will remain for the life of the container.

+ * + *

Note:

the semantics of this + * Set are subtly different than that of a {@link java.util.HashMap}: most important, + * the {@link java.util.Map.Entry Map.Entry} object returned by its iterator is a single + * object that exists for the entire iterator, so you can not hold on to it + * after calling {@link java.util.Iterator#next() Iterator.next}.

+ */ + @Override + public Set> entrySet() { + return getCollection().getEntrySet(); + } + + /** + * Return a {@link java.util.Set} for iterating over and interacting with all keys + * in the array map. + * + *

Note: this is a fairly inefficient way to access the array contents, it + * requires generating a number of temporary objects and allocates additional state + * information associated with the container that will remain for the life of the container.

+ */ + @Override + public Set keySet() { + return getCollection().getKeySet(); + } + + /** + * Return a {@link java.util.Collection} for iterating over and interacting with all values + * in the array map. + * + *

Note: this is a fairly inefficient way to access the array contents, it + * requires generating a number of temporary objects and allocates additional state + * information associated with the container that will remain for the life of the container.

+ */ + @Override + public Collection values() { + return getCollection().getValues(); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/android/util/ContainerHelpers.java b/jre_lwjgl3glfw/src/main/java/android/util/ContainerHelpers.java new file mode 100644 index 000000000..4e5fefb9d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/android/util/ContainerHelpers.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +class ContainerHelpers { + + // This is Arrays.binarySearch(), but doesn't do any argument validation. + static int binarySearch(int[] array, int size, int value) { + int lo = 0; + int hi = size - 1; + + while (lo <= hi) { + final int mid = (lo + hi) >>> 1; + final int midVal = array[mid]; + + if (midVal < value) { + lo = mid + 1; + } else if (midVal > value) { + hi = mid - 1; + } else { + return mid; // value found + } + } + return ~lo; // value not present + } + + static int binarySearch(long[] array, int size, long value) { + int lo = 0; + int hi = size - 1; + + while (lo <= hi) { + final int mid = (lo + hi) >>> 1; + final long midVal = array[mid]; + + if (midVal < value) { + lo = mid + 1; + } else if (midVal > value) { + hi = mid - 1; + } else { + return mid; // value found + } + } + return ~lo; // value not present + } +} diff --git a/jre_lwjgl3glfw/src/main/java/android/util/EmptyArray.java b/jre_lwjgl3glfw/src/main/java/android/util/EmptyArray.java new file mode 100644 index 000000000..a5735fbc5 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/android/util/EmptyArray.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.util; + +public final class EmptyArray { + private EmptyArray() {} + public static final boolean[] BOOLEAN = new boolean[0]; + public static final byte[] BYTE = new byte[0]; + public static final char[] CHAR = new char[0]; + public static final double[] DOUBLE = new double[0]; + public static final int[] INT = new int[0]; + public static final Class[] CLASS = new Class[0]; + public static final Object[] OBJECT = new Object[0]; + public static final String[] STRING = new String[0]; + public static final Throwable[] THROWABLE = new Throwable[0]; + public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0]; +} diff --git a/jre_lwjgl3glfw/src/main/java/android/util/MapCollections.java b/jre_lwjgl3glfw/src/main/java/android/util/MapCollections.java new file mode 100644 index 000000000..acfc1adad --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/android/util/MapCollections.java @@ -0,0 +1,557 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.util; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * Helper for writing standard Java collection interfaces to a data + * structure like {@link ArrayMap}. + * @hide + */ +abstract class MapCollections { + EntrySet mEntrySet; + KeySet mKeySet; + ValuesCollection mValues; + + final class ArrayIterator implements Iterator { + final int mOffset; + int mSize; + int mIndex; + boolean mCanRemove = false; + + ArrayIterator(int offset) { + mOffset = offset; + mSize = colGetSize(); + } + + @Override + public boolean hasNext() { + return mIndex < mSize; + } + + @Override + public T next() { + Object res = colGetEntry(mIndex, mOffset); + mIndex++; + mCanRemove = true; + return (T)res; + } + + @Override + public void remove() { + if (!mCanRemove) { + throw new IllegalStateException(); + } + mIndex--; + mSize--; + mCanRemove = false; + colRemoveAt(mIndex); + } + } + + final class MapIterator implements Iterator>, Map.Entry { + int mEnd; + int mIndex; + boolean mEntryValid = false; + + MapIterator() { + mEnd = colGetSize() - 1; + mIndex = -1; + } + + @Override + public boolean hasNext() { + return mIndex < mEnd; + } + + @Override + public Map.Entry next() { + mIndex++; + mEntryValid = true; + return this; + } + + @Override + public void remove() { + if (!mEntryValid) { + throw new IllegalStateException(); + } + colRemoveAt(mIndex); + mIndex--; + mEnd--; + mEntryValid = false; + } + + @Override + public K getKey() { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + return (K)colGetEntry(mIndex, 0); + } + + @Override + public V getValue() { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + return (V)colGetEntry(mIndex, 1); + } + + @Override + public V setValue(V object) { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + return colSetValue(mIndex, object); + } + + @Override + public final boolean equals(Object o) { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + if (!(o instanceof Map.Entry)) { + return false; + } + Map.Entry e = (Map.Entry) o; + return Objects.equal(e.getKey(), colGetEntry(mIndex, 0)) + && Objects.equal(e.getValue(), colGetEntry(mIndex, 1)); + } + + @Override + public final int hashCode() { + if (!mEntryValid) { + throw new IllegalStateException( + "This container does not support retaining Map.Entry objects"); + } + final Object key = colGetEntry(mIndex, 0); + final Object value = colGetEntry(mIndex, 1); + return (key == null ? 0 : key.hashCode()) ^ + (value == null ? 0 : value.hashCode()); + } + + @Override + public final String toString() { + return getKey() + "=" + getValue(); + } + } + + final class EntrySet implements Set> { + @Override + public boolean add(Map.Entry object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection> collection) { + int oldSize = colGetSize(); + for (Map.Entry entry : collection) { + colPut(entry.getKey(), entry.getValue()); + } + return oldSize != colGetSize(); + } + + @Override + public void clear() { + colClear(); + } + + @Override + public boolean contains(Object o) { + if (!(o instanceof Map.Entry)) + return false; + Map.Entry e = (Map.Entry) o; + int index = colIndexOfKey(e.getKey()); + if (index < 0) { + return false; + } + Object foundVal = colGetEntry(index, 1); + return Objects.equal(foundVal, e.getValue()); + } + + @Override + public boolean containsAll(Collection collection) { + Iterator it = collection.iterator(); + while (it.hasNext()) { + if (!contains(it.next())) { + return false; + } + } + return true; + } + + @Override + public boolean isEmpty() { + return colGetSize() == 0; + } + + @Override + public Iterator> iterator() { + return new MapIterator(); + } + + @Override + public boolean remove(Object object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + return colGetSize(); + } + + @Override + public Object[] toArray() { + throw new UnsupportedOperationException(); + } + + @Override + public T[] toArray(T[] array) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object object) { + return equalsSetHelper(this, object); + } + + @Override + public int hashCode() { + int result = 0; + for (int i=colGetSize()-1; i>=0; i--) { + final Object key = colGetEntry(i, 0); + final Object value = colGetEntry(i, 1); + result += ( (key == null ? 0 : key.hashCode()) ^ + (value == null ? 0 : value.hashCode()) ); + } + return result; + } + }; + + final class KeySet implements Set { + + @Override + public boolean add(K object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + colClear(); + } + + @Override + public boolean contains(Object object) { + return colIndexOfKey(object) >= 0; + } + + @Override + public boolean containsAll(Collection collection) { + return containsAllHelper(colGetMap(), collection); + } + + @Override + public boolean isEmpty() { + return colGetSize() == 0; + } + + @Override + public Iterator iterator() { + return new ArrayIterator(0); + } + + @Override + public boolean remove(Object object) { + int index = colIndexOfKey(object); + if (index >= 0) { + colRemoveAt(index); + return true; + } + return false; + } + + @Override + public boolean removeAll(Collection collection) { + return removeAllHelper(colGetMap(), collection); + } + + @Override + public boolean retainAll(Collection collection) { + return retainAllHelper(colGetMap(), collection); + } + + @Override + public int size() { + return colGetSize(); + } + + @Override + public Object[] toArray() { + return toArrayHelper(0); + } + + @Override + public T[] toArray(T[] array) { + return toArrayHelper(array, 0); + } + + @Override + public boolean equals(Object object) { + return equalsSetHelper(this, object); + } + + @Override + public int hashCode() { + int result = 0; + for (int i=colGetSize()-1; i>=0; i--) { + Object obj = colGetEntry(i, 0); + result += obj == null ? 0 : obj.hashCode(); + } + return result; + } + }; + + final class ValuesCollection implements Collection { + + @Override + public boolean add(V object) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection collection) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + colClear(); + } + + @Override + public boolean contains(Object object) { + return colIndexOfValue(object) >= 0; + } + + @Override + public boolean containsAll(Collection collection) { + Iterator it = collection.iterator(); + while (it.hasNext()) { + if (!contains(it.next())) { + return false; + } + } + return true; + } + + @Override + public boolean isEmpty() { + return colGetSize() == 0; + } + + @Override + public Iterator iterator() { + return new ArrayIterator(1); + } + + @Override + public boolean remove(Object object) { + int index = colIndexOfValue(object); + if (index >= 0) { + colRemoveAt(index); + return true; + } + return false; + } + + @Override + public boolean removeAll(Collection collection) { + int N = colGetSize(); + boolean changed = false; + for (int i=0; i collection) { + int N = colGetSize(); + boolean changed = false; + for (int i=0; i T[] toArray(T[] array) { + return toArrayHelper(array, 1); + } + }; + + public static boolean containsAllHelper(Map map, Collection collection) { + Iterator it = collection.iterator(); + while (it.hasNext()) { + if (!map.containsKey(it.next())) { + return false; + } + } + return true; + } + + public static boolean removeAllHelper(Map map, Collection collection) { + int oldSize = map.size(); + Iterator it = collection.iterator(); + while (it.hasNext()) { + map.remove(it.next()); + } + return oldSize != map.size(); + } + + public static boolean retainAllHelper(Map map, Collection collection) { + int oldSize = map.size(); + Iterator it = map.keySet().iterator(); + while (it.hasNext()) { + if (!collection.contains(it.next())) { + it.remove(); + } + } + return oldSize != map.size(); + } + + public Object[] toArrayHelper(int offset) { + final int N = colGetSize(); + Object[] result = new Object[N]; + for (int i=0; i T[] toArrayHelper(T[] array, int offset) { + final int N = colGetSize(); + if (array.length < N) { + @SuppressWarnings("unchecked") T[] newArray + = (T[]) Array.newInstance(array.getClass().getComponentType(), N); + array = newArray; + } + for (int i=0; i N) { + array[N] = null; + } + return array; + } + + public static boolean equalsSetHelper(Set set, Object object) { + if (set == object) { + return true; + } + if (object instanceof Set) { + Set s = (Set) object; + + try { + return set.size() == s.size() && set.containsAll(s); + } catch (NullPointerException ignored) { + return false; + } catch (ClassCastException ignored) { + return false; + } + } + return false; + } + + public Set> getEntrySet() { + if (mEntrySet == null) { + mEntrySet = new EntrySet(); + } + return mEntrySet; + } + + public Set getKeySet() { + if (mKeySet == null) { + mKeySet = new KeySet(); + } + return mKeySet; + } + + public Collection getValues() { + if (mValues == null) { + mValues = new ValuesCollection(); + } + return mValues; + } + + protected abstract int colGetSize(); + protected abstract Object colGetEntry(int index, int offset); + protected abstract int colIndexOfKey(Object key); + protected abstract int colIndexOfValue(Object key); + protected abstract Map colGetMap(); + protected abstract void colPut(K key, V value); + protected abstract V colSetValue(int index, V value); + protected abstract void colRemoveAt(int index); + protected abstract void colClear(); +} diff --git a/jre_lwjgl3glfw/src/main/java/android/util/Objects.java b/jre_lwjgl3glfw/src/main/java/android/util/Objects.java new file mode 100644 index 000000000..64693903b --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/android/util/Objects.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.util; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +public final class Objects { + private Objects() {} + /** + * Returns true if two possibly-null objects are equal. + */ + public static boolean equal(Object a, Object b) { + return a == b || (a != null && a.equals(b)); + } + public static int hashCode(Object o) { + return (o == null) ? 0 : o.hashCode(); + } + /** + * Returns a string reporting the value of each declared field, via reflection. + * Static and transient fields are automatically skipped. Produces output like + * "SimpleClassName[integer=1234,string="hello",character='c',intArray=[1,2,3]]". + */ + public static String toString(Object o) { + Class c = o.getClass(); + StringBuilder sb = new StringBuilder(); + sb.append(c.getSimpleName()).append('['); + int i = 0; + for (Field f : c.getDeclaredFields()) { + if ((f.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0) { + continue; + } + f.setAccessible(true); + try { + Object value = f.get(o); + if (i++ > 0) { + sb.append(','); + } + sb.append(f.getName()); + sb.append('='); + if (value.getClass().isArray()) { + if (value.getClass() == boolean[].class) { + sb.append(Arrays.toString((boolean[]) value)); + } else if (value.getClass() == byte[].class) { + sb.append(Arrays.toString((byte[]) value)); + } else if (value.getClass() == char[].class) { + sb.append(Arrays.toString((char[]) value)); + } else if (value.getClass() == double[].class) { + sb.append(Arrays.toString((double[]) value)); + } else if (value.getClass() == float[].class) { + sb.append(Arrays.toString((float[]) value)); + } else if (value.getClass() == int[].class) { + sb.append(Arrays.toString((int[]) value)); + } else if (value.getClass() == long[].class) { + sb.append(Arrays.toString((long[]) value)); + } else if (value.getClass() == short[].class) { + sb.append(Arrays.toString((short[]) value)); + } else { + sb.append(Arrays.toString((Object[]) value)); + } + } else if (value.getClass() == Character.class) { + sb.append('\'').append(value).append('\''); + } else if (value.getClass() == String.class) { + sb.append('"').append(value).append('"'); + } else { + sb.append(value); + } + } catch (IllegalAccessException unexpected) { + throw new AssertionError(unexpected); + } + } + sb.append("]"); + return sb.toString(); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/net/minecraft/client/ClientBrandRetriever.java.z b/jre_lwjgl3glfw/src/main/java/net/minecraft/client/ClientBrandRetriever.java.z new file mode 100644 index 000000000..987a62f05 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/net/minecraft/client/ClientBrandRetriever.java.z @@ -0,0 +1,8 @@ +package net.minecraft.client; + +public class ClientBrandRetriever { + public static String getClientModName() { + // return "vanilla"; + return System.getProperty("net.minecraft.clientmodname", "vanilla"); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferChecks.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferChecks.java new file mode 100644 index 000000000..1160c72e1 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferChecks.java @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl; + +import java.nio.*; + +/** + *

+ * A class to check buffer boundaries in general. If there is unsufficient space + * in the buffer when the call is made then a buffer overflow would otherwise + * occur and cause unexpected behaviour, a crash, or worse, a security risk. + * + * Internal class, don't use. + *

+ * + * @author cix_foo + * @author elias_naur + * @version $Revision$ $Id$ + */ +public class BufferChecks { + private BufferChecks() { + } + + /** + * Helper methods to ensure a function pointer is not-null (0) + */ + public static void checkFunctionAddress(long pointer) { + if (LWJGLUtil.CHECKS && pointer == 0) + throw new IllegalStateException("Function is not supported"); + + } + + /** + * Helper methods to ensure a ByteBuffer is null-terminated + */ + public static void checkNullTerminated(ByteBuffer buf) { + if (LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0) + throw new IllegalArgumentException("Missing null termination"); + } + + public static void checkNullTerminated(ByteBuffer buf, int count) { + if (LWJGLUtil.CHECKS) { + int nullFound = 0; + for (int i = buf.position(); i < buf.limit(); i++) { + if (buf.get(i) == 0) + nullFound++; + } + + if (nullFound < count) + throw new IllegalArgumentException("Missing null termination"); + } + } + + /** Helper method to ensure an IntBuffer is null-terminated */ + public static void checkNullTerminated(IntBuffer buf) { + if (LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0) + throw new IllegalArgumentException("Missing null termination"); + + } + + /** Helper method to ensure a LongBuffer is null-terminated */ + public static void checkNullTerminated(LongBuffer buf) { + if (LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0) + throw new IllegalArgumentException("Missing null termination"); + + } + + /** Helper method to ensure a PointerBuffer is null-terminated */ + public static void checkNullTerminated(PointerBuffer buf) { + if (LWJGLUtil.CHECKS && buf.get(buf.limit() - 1) != 0) + throw new IllegalArgumentException("Missing null termination"); + + } + + public static void checkNotNull(Object o) { + if (LWJGLUtil.CHECKS && o == null) + throw new IllegalArgumentException("Null argument"); + } + + /** + * Helper methods to ensure a buffer is direct (and, implicitly, non-null). + */ + public static void checkDirect(ByteBuffer buf) { + if (LWJGLUtil.CHECKS && !buf.isDirect()) + throw new IllegalArgumentException("ByteBuffer is not direct"); + + } + + public static void checkDirect(ShortBuffer buf) { + if (LWJGLUtil.CHECKS && !buf.isDirect()) + throw new IllegalArgumentException("ShortBuffer is not direct"); + + } + + public static void checkDirect(IntBuffer buf) { + if (LWJGLUtil.CHECKS && !buf.isDirect()) + throw new IllegalArgumentException("IntBuffer is not direct"); + + } + + public static void checkDirect(LongBuffer buf) { + if (LWJGLUtil.CHECKS && !buf.isDirect()) { + throw new IllegalArgumentException("LongBuffer is not direct"); + } + } + + public static void checkDirect(FloatBuffer buf) { + if (LWJGLUtil.CHECKS && !buf.isDirect()) + throw new IllegalArgumentException("FloatBuffer is not direct"); + + } + + public static void checkDirect(DoubleBuffer buf) { + if (LWJGLUtil.CHECKS && !buf.isDirect()) + throw new IllegalArgumentException("DoubleBuffer is not direct"); + + } + + public static void checkDirect(PointerBuffer buf) { + // NO-OP, PointerBuffer is always direct. + } + + public static void checkArray(Object[] array) { + if (LWJGLUtil.CHECKS && (array == null || array.length == 0)) + throw new IllegalArgumentException("Invalid array"); + } + + /** + * This is a separate call to help inline checkBufferSize. + */ + private static void throwBufferSizeException(Buffer buf, int size) { + throw new IllegalArgumentException( + "Number of remaining buffer elements is " + buf.remaining() + ", must be at least " + size + + ". Because at most " + size + " elements can be returned, a buffer with at least " + size + + " elements is required, regardless of actual returned element count"); + } + + private static void throwBufferSizeException(PointerBuffer buf, int size) { + throw new IllegalArgumentException( + "Number of remaining pointer buffer elements is " + buf.remaining() + ", must be at least " + size); + } + + private static void throwArraySizeException(Object[] array, int size) { + throw new IllegalArgumentException( + "Number of array elements is " + array.length + ", must be at least " + size); + } + + private static void throwArraySizeException(long[] array, int size) { + throw new IllegalArgumentException( + "Number of array elements is " + array.length + ", must be at least " + size); + } + + /** + * Helper method to ensure a buffer is big enough to receive data from a + * glGet* operation. + * + * @param buf + * The buffer to check + * @param size + * The minimum buffer size + * @throws IllegalArgumentException + */ + public static void checkBufferSize(Buffer buf, int size) { + if (LWJGLUtil.CHECKS && buf.remaining() < size) + throwBufferSizeException(buf, size); + + } + + /** + * Detects the buffer type and performs the corresponding check and also + * returns the buffer position in bytes. + * + * @param buffer + * the buffer to check + * @param size + * the size to check + * + * @return the buffer position in bytes + */ + public static int checkBuffer(final Buffer buffer, final int size) { + final int posShift; + if (buffer instanceof ByteBuffer) { + BufferChecks.checkBuffer((ByteBuffer) buffer, size); + posShift = 0; + } else if (buffer instanceof ShortBuffer) { + BufferChecks.checkBuffer((ShortBuffer) buffer, size); + posShift = 1; + } else if (buffer instanceof IntBuffer) { + BufferChecks.checkBuffer((IntBuffer) buffer, size); + posShift = 2; + } else if (buffer instanceof LongBuffer) { + BufferChecks.checkBuffer((LongBuffer) buffer, size); + posShift = 4; + } else if (buffer instanceof FloatBuffer) { + BufferChecks.checkBuffer((FloatBuffer) buffer, size); + posShift = 2; + } else if (buffer instanceof DoubleBuffer) { + BufferChecks.checkBuffer((DoubleBuffer) buffer, size); + posShift = 4; + } else + throw new IllegalArgumentException("Unsupported Buffer type specified: " + buffer.getClass()); + + return buffer.position() << posShift; + } + + public static void checkBuffer(ByteBuffer buf, int size) { + if (LWJGLUtil.CHECKS) { + checkBufferSize(buf, size); + checkDirect(buf); + } + } + + public static void checkBuffer(ShortBuffer buf, int size) { + if (LWJGLUtil.CHECKS) { + checkBufferSize(buf, size); + checkDirect(buf); + } + } + + public static void checkBuffer(IntBuffer buf, int size) { + if (LWJGLUtil.CHECKS) { + checkBufferSize(buf, size); + checkDirect(buf); + } + } + + public static void checkBuffer(LongBuffer buf, int size) { + if (LWJGLUtil.CHECKS) { + checkBufferSize(buf, size); + checkDirect(buf); + } + } + + public static void checkBuffer(FloatBuffer buf, int size) { + if (LWJGLUtil.CHECKS) { + checkBufferSize(buf, size); + checkDirect(buf); + } + } + + public static void checkBuffer(DoubleBuffer buf, int size) { + if (LWJGLUtil.CHECKS) { + checkBufferSize(buf, size); + checkDirect(buf); + } + } + + public static void checkBuffer(PointerBuffer buf, int size) { + if (LWJGLUtil.CHECKS && buf.remaining() < size) { + throwBufferSizeException(buf, size); + } + } + + public static void checkArray(Object[] array, int size) { + if (LWJGLUtil.CHECKS && array.length < size) + throwArraySizeException(array, size); + } + + public static void checkArray(long[] array, int size) { + if (LWJGLUtil.CHECKS && array.length < size) + throwArraySizeException(array, size); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferUtils.java.z b/jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferUtils.java.z new file mode 100644 index 000000000..643170c53 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/BufferUtils.java.z @@ -0,0 +1,269 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + */ +package org.lwjgl; + +import org.lwjgl.system.*; + +import java.nio.*; + +import static org.lwjgl.system.APIUtil.*; +import static org.lwjgl.system.MemoryUtil.*; + +/** + *

This class makes it easy and safe to work with direct buffers. It is the recommended way to allocate memory to use with LWJGL.

+ * + *

Direct buffers

+ * + *

LWJGL requires that all NIO buffers passed to it are direct buffers. Direct buffers essentially wrap an address that points to off-heap memory, i.e. a + * native pointer. This is the only way LWJGL can safely pass data from Java code to native code, and vice-versa, without a performance penalty. It does not + * support on-heap Java arrays (or plain NIO buffers, which wrap them) because arrays may be moved around in memory by the JVM's garbage collector while native + * code is accessing them. In addition, Java arrays have an unspecified layout, i.e. they are not necessarily contiguous in memory.

+ * + *

Usage

+ * + *

When a direct buffer is passed as an argument to an LWJGL method, no data is copied. Instead, the current buffer position is added to the buffer's memory + * address and the resulting value is passed to native code. The native code interprets that value as a pointer and reads or copies from it as necessary. LWJGL + * will often also use the current buffer limit (via {@link Buffer#remaining()}) to automatically pass length/maxlength arguments. This means that, just like + * other APIs that use NIO buffers, the current {@link Buffer#position()} and {@link Buffer#limit()} at the time of the call is very important. Contrary to + * other APIs, LWJGL never modifies the current position, it will be the same value before and after the call.

+ * + *

Arrays of pointers

+ * + *

In addition to the standard NIO buffer classes, LWJGL provides a {@link PointerBuffer} class for storing pointer data in an architecture independent way. + * It is used in bindings for pointer-to-pointers arguments, usually to provide arrays of data (input parameter) or to store returned pointer values (output + * parameter). Also, there's the {@link CLongBuffer} class which is similar to {@code PointerBuffer}, but for C {@code long} data.

+ * + *

Memory management

+ * + *

Using NIO buffers for off-heap memory has some drawbacks:

+ *
    + *
  • Memory blocks bigger than {@link Integer#MAX_VALUE} bytes cannot be allocated.
  • + *
  • Memory blocks are zeroed-out on allocation, for safety. This has (sometimes unwanted) performance implications.
  • + *
  • There is no way to free a buffer explicitly (without JVM specific reflection). Buffer objects are subject to GC and it usually takes two GC cycles to + * free the off-heap memory after the buffer object becomes unreachable.
  • + *
+ * + *

An alternative API for allocating off-heap memory can be found in the {@link org.lwjgl.system.MemoryUtil} class. This has none of the above drawbacks, + * but requires allocated memory to be explictly freed when not used anymore.

+ * + *

Memory alignment

+ * + *

Allocations done via this class have a guaranteed alignment of 8 bytes. If higher alignment values are required, use the explicit memory management API + * or pad the requested memory with extra bytes and align manually.

+ * + *

Structs and arrays of structs

+ * + *

Java does not support struct value types, so LWJGL requires struct values that are backed by off-heap memory. Each struct type defined in a binding + * has a corresponding class in LWJGL that can be used to access its members. Each struct class also has a {@code Buffer} inner class that can be used to + * access (packed) arrays of struct values. Both struct and struct buffer classes may be backed by direct {@link ByteBuffer}s allocated from this class, but it + * is highly recommended to use explicit memory management for performance.

+ */ +public final class BufferUtils { +// -- Begin LWJGL2 parts -- + /** + * @return n, where buffer_element_size=2^n. + */ + public static int getElementSizeExponent(Buffer buf) { + if (buf instanceof ByteBuffer) + return 0; + else if (buf instanceof ShortBuffer || buf instanceof CharBuffer) + return 1; + else if (buf instanceof FloatBuffer || buf instanceof IntBuffer) + return 2; + else if (buf instanceof LongBuffer || buf instanceof DoubleBuffer) + return 3; + else + throw new IllegalStateException("Unsupported buffer type: " + buf); + } + + /** + * A helper function which is used to get the byte offset in an arbitrary + * buffer based on its position + * + * @return the position of the buffer, in BYTES + */ + public static int getOffset(Buffer buffer) { + return buffer.position() << getElementSizeExponent(buffer); + } + + /** + * Returns the memory address of the specified buffer. + * + * @param buffer + * the buffer + * + * @return the memory address + */ + static long getBufferAddress(Buffer buffer) { + // Should be below or memAddress0() ? + return memAddress(buffer); + } +// -- End LWJGL2 parts -- + + private BufferUtils() {} + + /** + * Allocates a direct native-ordered {@code ByteBuffer} with the specified capacity. + * + * @param capacity the capacity, in bytes + * + * @return a {@code ByteBuffer} + */ + public static ByteBuffer createByteBuffer(int capacity) { + return ByteBuffer.allocateDirect(capacity).order(ByteOrder.nativeOrder()); + } + + static int getAllocationSize(int elements, int elementShift) { + apiCheckAllocation(elements, apiGetBytes(elements, elementShift), 0x7FFF_FFFFL); + return elements << elementShift; + } + + /** + * Allocates a direct native-order {@code ShortBuffer} with the specified number of elements. + * + * @param capacity the capacity, in shorts + * + * @return a {@code ShortBuffer} + */ + public static ShortBuffer createShortBuffer(int capacity) { + return createByteBuffer(getAllocationSize(capacity, 1)).asShortBuffer(); + } + + /** + * Allocates a direct native-order {@code CharBuffer} with the specified number of elements. + * + * @param capacity the capacity, in chars + * + * @return a {@code CharBuffer} + */ + public static CharBuffer createCharBuffer(int capacity) { + return createByteBuffer(getAllocationSize(capacity, 1)).asCharBuffer(); + } + + /** + * Allocates a direct native-order {@code IntBuffer} with the specified number of elements. + * + * @param capacity the capacity, in ints + * + * @return an {@code IntBuffer} + */ + public static IntBuffer createIntBuffer(int capacity) { + return createByteBuffer(getAllocationSize(capacity, 2)).asIntBuffer(); + } + + /** + * Allocates a direct native-order {@code LongBuffer} with the specified number of elements. + * + * @param capacity the capacity, in longs + * + * @return a {@code LongBuffer} + */ + public static LongBuffer createLongBuffer(int capacity) { + return createByteBuffer(getAllocationSize(capacity, 3)).asLongBuffer(); + } + + /** + * Allocates a {@code CLongBuffer} with the specified number of elements. + * + * @param capacity the capacity, in memory addresses + * + * @return a {@code CLongBuffer} + */ + public static CLongBuffer createCLongBuffer(int capacity) { + return CLongBuffer.allocateDirect(capacity); + } + + /** + * Allocates a direct native-order {@code FloatBuffer} with the specified number of elements. + * + * @param capacity the capacity, in floats + * + * @return a FloatBuffer + */ + public static FloatBuffer createFloatBuffer(int capacity) { + return createByteBuffer(getAllocationSize(capacity, 2)).asFloatBuffer(); + } + + /** + * Allocates a direct native-order {@code DoubleBuffer} with the specified number of elements. + * + * @param capacity the capacity, in doubles + * + * @return a {@code DoubleBuffer} + */ + public static DoubleBuffer createDoubleBuffer(int capacity) { + return createByteBuffer(getAllocationSize(capacity, 3)).asDoubleBuffer(); + } + + /** + * Allocates a {@code PointerBuffer} with the specified number of elements. + * + * @param capacity the capacity, in memory addresses + * + * @return a {@code PointerBuffer} + */ + public static PointerBuffer createPointerBuffer(int capacity) { + return PointerBuffer.allocateDirect(capacity); + } + + // memsets + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static void zeroBuffer(ByteBuffer buffer) { memSet(buffer, 0); } + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static void zeroBuffer(ShortBuffer buffer) { memSet(buffer, 0); } + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static void zeroBuffer(CharBuffer buffer) { memSet(buffer, 0); } + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static void zeroBuffer(IntBuffer buffer) { memSet(buffer, 0); } + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static void zeroBuffer(FloatBuffer buffer) { memSet(buffer, 0); } + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static void zeroBuffer(LongBuffer buffer) { memSet(buffer, 0); } + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static void zeroBuffer(DoubleBuffer buffer) { memSet(buffer, 0); } + + /** + * Fills the specified buffer with zeros from the current position to the current limit. + * + * @param buffer the buffer to fill with zeros + */ + public static > void zeroBuffer(T buffer) { memSet(buffer, 0); } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/LWJGLUtil.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/LWJGLUtil.java new file mode 100644 index 000000000..e074d9a2b --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/LWJGLUtil.java @@ -0,0 +1,640 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.nio.ByteBuffer; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.*; + +/** + *

+ * Internal library methods + *

+ * + * @author Brian Matzon + * @version $Revision: 3608 $ $Id: LWJGLUtil.java 3608 2011-08-10 16:05:46Z + * spasi $ + */ +public class LWJGLUtil { + public static final int PLATFORM_LINUX = 1; + public static final int PLATFORM_MACOSX = 2; + public static final int PLATFORM_WINDOWS = 3; + public static final String PLATFORM_LINUX_NAME = "linux"; + public static final String PLATFORM_MACOSX_NAME = "macosx"; + public static final String PLATFORM_WINDOWS_NAME = "windows"; + + private static final String LWJGL_ICON_DATA_16x16 = "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\376\377\377\377\302\327\350\377" + + "\164\244\313\377\120\213\275\377\124\216\277\377\206\257\322\377" + + "\347\357\366\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\365\365\365\377\215\217\221\377\166\202\215\377" + + "\175\215\233\377\204\231\252\377\224\267\325\377\072\175\265\377" + + "\110\206\272\377\332\347\361\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\364\370\373\377\234\236\240\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\344\344\344\377\204\255\320\377" + + "\072\175\265\377\133\222\301\377\374\375\376\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\221\266\325\377\137\137\137\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\042\042\042\377\377\377\377\377\350\360\366\377" + + "\071\174\265\377\072\175\265\377\304\330\351\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\306\331\351\377" + + "\201\253\316\377\035\035\035\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\146\146\146\377\377\377\377\377\320\340\355\377" + + "\072\175\265\377\072\175\265\377\215\264\324\377\377\377\377\377" + + "\362\362\362\377\245\245\245\377\337\337\337\377\242\301\334\377" + + "\260\305\326\377\012\012\012\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\250\250\250\377\377\377\377\377\227\272\330\377" + + "\072\175\265\377\072\175\265\377\161\241\312\377\377\377\377\377" + + "\241\241\241\377\000\000\000\377\001\001\001\377\043\043\043\377" + + "\314\314\314\377\320\320\320\377\245\245\245\377\204\204\204\377" + + "\134\134\134\377\357\357\357\377\377\377\377\377\140\226\303\377" + + "\072\175\265\377\072\175\265\377\155\236\310\377\377\377\377\377" + + "\136\136\136\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\317\317\317\377\037\037\037\377\003\003\003\377\053\053\053\377" + + "\154\154\154\377\306\306\306\377\372\374\375\377\236\277\332\377" + + "\167\245\314\377\114\211\274\377\174\250\316\377\377\377\377\377" + + "\033\033\033\377\000\000\000\377\000\000\000\377\027\027\027\377" + + "\326\326\326\377\001\001\001\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\122\122\122\377\345\345\345\377\075\075\075\377" + + "\150\150\150\377\246\246\247\377\332\336\341\377\377\377\377\377" + + "\164\164\164\377\016\016\016\377\000\000\000\377\131\131\131\377" + + "\225\225\225\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\221\221\221\377\233\233\233\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\002\002\002\377\103\103\103\377" + + "\377\377\377\377\356\356\356\377\214\214\214\377\277\277\277\377" + + "\126\126\126\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\323\323\323\377\130\130\130\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\063\063\063\377" + + "\377\377\377\377\377\377\377\377\374\375\376\377\377\377\377\377" + + "\300\300\300\377\100\100\100\377\002\002\002\377\000\000\000\377" + + "\033\033\033\377\373\373\373\377\027\027\027\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\170\170\170\377" + + "\377\377\377\377\377\377\377\377\322\341\356\377\176\251\316\377" + + "\340\352\363\377\377\377\377\377\324\324\324\377\155\155\155\377" + + "\204\204\204\377\323\323\323\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\275\275\275\377" + + "\377\377\377\377\377\377\377\377\376\376\376\377\146\232\305\377" + + "\075\177\266\377\202\254\320\377\344\355\365\377\377\377\377\377" + + "\377\377\377\377\345\345\345\377\055\055\055\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\014\014\014\377\366\366\366\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\342\354\364\377" + + "\115\211\274\377\072\175\265\377\076\200\266\377\207\260\322\377" + + "\347\357\366\377\377\377\377\377\376\376\376\377\274\274\274\377" + + "\117\117\117\377\003\003\003\377\112\112\112\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\353\362\370\377\214\263\324\377\126\220\300\377\120\214\275\377" + + "\167\245\314\377\355\363\370\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\337\337\337\377\346\346\346\377\377\377\377\377"; + + private static final String LWJGL_ICON_DATA_32x32 = "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\374\375\377" + + "\313\335\354\377\223\267\326\377\157\240\311\377\134\223\302\377\140\226\303\377\172\247\315\377\254\310\340\377\355\363\370\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\375\376\377\265\316\343\377\132\222\301\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\105\205\271\377" + + "\241\301\334\377\374\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\374\374\377\342\352\361\377\270\317\343\377\256\311\340\377" + + "\243\302\334\377\230\272\330\377\214\263\323\377\201\254\317\377\156\237\310\377\075\177\266\377\072\175\265\377\072\175\265\377" + + "\072\175\265\377\162\242\312\377\365\370\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\330\330\330\377\061\061\061\377\044\044\044\377\061\061\061\377\100\100\100\377" + + "\122\122\122\377\145\145\145\377\164\164\164\377\217\217\217\377\367\370\370\377\254\310\337\377\073\175\265\377\072\175\265\377" + + "\072\175\265\377\072\175\265\377\171\247\315\377\374\375\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\376\376\376\377\150\150\150\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\266\266\266\377\376\376\376\377\206\256\321\377\072\175\265\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\256\312\341\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\323\342\356\377\341\352\362\377\050\050\050\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\002\002\002\377\336\336\336\377\377\377\377\377\365\370\373\377\133\222\301\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\110\206\272\377\364\370\373\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\354\363\370\377\144\231\305\377\327\331\333\377\005\005\005\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\044\044\044\377\376\376\376\377\377\377\377\377\377\377\377\377\300\325\347\377" + + "\071\174\265\377\072\175\265\377\072\175\265\377\072\175\265\377\253\310\340\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\377\377\377" + + "\170\246\314\377\173\247\315\377\236\236\236\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\145\145\145\377\377\377\377\377\377\377\377\377\377\377\377\377\342\354\364\377" + + "\067\173\264\377\072\175\265\377\072\175\265\377\072\175\265\377\146\232\305\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\303\327\350\377" + + "\071\175\265\377\262\314\341\377\130\130\130\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\251\251\251\377\377\377\377\377\377\377\377\377\377\377\377\377\274\322\345\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\100\201\267\377\356\364\371\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\374\375\377\132\222\301\377" + + "\075\177\266\377\335\345\355\377\034\034\034\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\007\007\007\377\347\347\347\377\377\377\377\377\377\377\377\377\377\377\377\377\205\256\321\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\071\175\265\377\314\336\354\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\272\322\345\377\072\175\265\377" + + "\127\220\277\377\320\321\321\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\063\063\063\377\375\375\375\377\377\377\377\377\377\377\377\377\373\374\375\377\120\213\275\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\071\175\265\377\261\314\342\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\312\312\312\377\067\067\067\377\141\141\141\377\242\242\242\377\335\335\335\377\344\354\363\377\261\313\341\377" + + "\264\315\342\377\346\346\346\377\043\043\043\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\162\162\162\377\377\377\377\377\377\377\377\377\377\377\377\377\330\345\360\377\072\175\265\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\240\300\333\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\146\146\146\377\000\000\000\377\000\000\000\377\000\000\000\377\006\006\006\377\047\047\047\377\146\146\146\377" + + "\324\324\324\377\377\377\377\377\366\366\366\377\320\320\320\377\227\227\227\377\136\136\136\377\047\047\047\377\004\004\004\377" + + "\000\000\000\377\003\003\003\377\300\300\300\377\377\377\377\377\377\377\377\377\377\377\377\377\242\301\333\377\072\175\265\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\236\277\332\377\377\377\377\377\377\377\377\377" + + "\373\373\373\377\045\045\045\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\134\134\134\377\377\377\377\377\352\352\352\377\217\217\217\377\265\265\265\377\351\351\351\377\375\375\375\377\347\347\347\377" + + "\262\262\262\377\275\275\275\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\153\235\307\377\072\175\265\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\241\301\334\377\377\377\377\377\377\377\377\377" + + "\333\333\333\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\203\203\203\377\377\377\377\377\137\137\137\377\000\000\000\377\000\000\000\377\013\013\013\377\067\067\067\377\166\166\166\377" + + "\267\267\267\377\360\360\360\377\377\377\377\377\377\377\377\377\377\377\377\377\360\365\371\377\113\210\273\377\075\177\266\377" + + "\071\174\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\262\314\342\377\377\377\377\377\377\377\377\377" + + "\232\232\232\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\305\305\305\377\367\367\367\377\035\035\035\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\007\007\007\377\074\074\074\377\337\337\337\377\377\377\377\377\373\374\375\377\374\375\376\377\363\367\372\377" + + "\314\335\353\377\236\276\332\377\162\241\311\377\114\211\273\377\072\175\265\377\311\334\353\377\377\377\377\377\377\377\377\377" + + "\126\126\126\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\017\017\017\377" + + "\371\371\371\377\321\321\321\377\003\003\003\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\216\216\216\377\377\377\377\377\371\371\371\377\204\204\204\377\160\160\160\377" + + "\260\260\260\377\352\352\352\377\377\377\377\377\371\373\374\377\334\350\362\377\366\371\374\377\377\377\377\377\377\377\377\377" + + "\025\025\025\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\116\116\116\377" + + "\377\377\377\377\221\221\221\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\273\273\273\377\377\377\377\377\236\236\236\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\004\004\004\377\057\057\057\377\160\160\160\377\260\260\260\377\346\346\346\377\376\376\376\377\377\377\377\377" + + "\071\071\071\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\220\220\220\377" + + "\377\377\377\377\115\115\115\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\020\020\020\377\360\360\360\377\377\377\377\377\132\132\132\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\011\011\011\377\062\062\062\377\261\261\261\377" + + "\366\366\366\377\241\241\241\377\065\065\065\377\002\002\002\377\000\000\000\377\000\000\000\377\002\002\002\377\321\321\321\377" + + "\365\365\365\377\023\023\023\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\105\105\105\377\376\376\376\377\370\370\370\377\035\035\035\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\053\053\053\377" + + "\377\377\377\377\377\377\377\377\374\374\374\377\276\276\276\377\120\120\120\377\005\005\005\377\045\045\045\377\371\371\371\377" + + "\302\302\302\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\206\206\206\377\377\377\377\377\322\322\322\377\001\001\001\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\103\103\103\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\377\334\334\334\377\340\340\340\377\377\377\377\377" + + "\225\225\225\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\001\001\001\377\310\310\310\377\377\377\377\377\216\216\216\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\210\210\210\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\337\337\337\377\051\051\051\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\030\030\030\377\365\365\365\377\377\377\377\377\112\112\112\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\317\317\317\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\361\366\372\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\371\371\371\377\265\265\265\377\113\113\113\377\006\006\006\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\122\122\122\377\377\377\377\377\370\370\370\377\020\020\020\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\034\034\034\377\370\370\370\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\206\257\321\377\220\265\325\377\352\361\367\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\333\333\333\377\170\170\170\377\033\033\033\377\000\000\000\377" + + "\000\000\000\377\226\226\226\377\377\377\377\377\306\306\306\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\132\132\132\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\303\330\351\377\072\175\265\377\103\203\270\377" + + "\224\270\326\377\355\363\370\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\364\364\364\377\247\247\247\377" + + "\205\205\205\377\364\364\364\377\377\377\377\377\206\206\206\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\235\235\235\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\373\375\377\135\224\302\377\072\175\265\377" + + "\072\175\265\377\106\205\271\377\230\273\330\377\357\364\371\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\233\233\233\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\005\005\005\377\335\335\335\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\305\331\351\377\073\176\266\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\110\206\272\377\236\276\332\377\362\366\372\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\373\373\373\377\216\216\216\377\045\045\045\377\001\001\001\377\000\000\000\377" + + "\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\054\054\054\377\374\374\374\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\217\265\325\377" + + "\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\112\207\273\377\243\302\334\377\363\367\372\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\372\372\372\377\260\260\260\377\105\105\105\377" + + "\004\004\004\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\156\156\156\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\374\375\376\377" + + "\205\257\321\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\115\211\274\377" + + "\250\305\336\377\366\371\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\377" + + "\322\322\322\377\150\150\150\377\016\016\016\377\000\000\000\377\001\001\001\377\270\270\270\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\376\376\377\377\261\313\342\377\114\211\274\377\071\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377\072\175\265\377" + + "\072\175\265\377\115\211\274\377\277\324\347\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\354\354\354\377\223\223\223\377\233\233\233\377\375\375\375\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\363\367\372\377\265\316\343\377\201\254\320\377\145\231\305\377\141\227\304\377\154\236\310\377" + + "\217\265\325\377\305\331\351\377\367\372\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"; + + /** LWJGL Logo - 16 by 16 pixels */ + public static final ByteBuffer LWJGLIcon16x16 = loadIcon(LWJGL_ICON_DATA_16x16); + + /** LWJGL Logo - 32 by 32 pixels */ + public static final ByteBuffer LWJGLIcon32x32 = loadIcon(LWJGL_ICON_DATA_32x32); + + /** Debug flag. */ + public static final boolean DEBUG = getPrivilegedBoolean("org.lwjgl.util.Debug"); + + public static final boolean CHECKS = !getPrivilegedBoolean("org.lwjgl.util.NoChecks"); + + private static final int PLATFORM; + + static { + final String osName = getPrivilegedProperty("os.name"); + if (osName.startsWith("Windows")) + PLATFORM = PLATFORM_WINDOWS; + else if (osName.startsWith("Linux") || osName.startsWith("FreeBSD") || osName.startsWith("SunOS") + || osName.startsWith("Unix") || osName.startsWith("Android")) + PLATFORM = PLATFORM_LINUX; + else if (osName.startsWith("Mac OS X") || osName.startsWith("Darwin")) + PLATFORM = PLATFORM_MACOSX; + else + throw new LinkageError("Unknown platform: " + osName); + } + + private static ByteBuffer loadIcon(String data) { + int len = data.length(); + ByteBuffer bb = BufferUtils.createByteBuffer(len); + for (int i = 0; i < len; i++) { + bb.put(i, (byte) data.charAt(i)); + } + return bb.asReadOnlyBuffer(); + } + + /** + * @see #PLATFORM_WINDOWS + * @see #PLATFORM_LINUX + * @see #PLATFORM_MACOSX + * @return the current platform type + */ + public static int getPlatform() { + return PLATFORM; + } + + /** + * @see #PLATFORM_WINDOWS_NAME + * @see #PLATFORM_LINUX_NAME + * @see #PLATFORM_MACOSX_NAME + * @return current platform name + */ + public static String getPlatformName() { + switch (LWJGLUtil.getPlatform()) { + case LWJGLUtil.PLATFORM_LINUX: + return PLATFORM_LINUX_NAME; + case LWJGLUtil.PLATFORM_MACOSX: + return PLATFORM_MACOSX_NAME; + case LWJGLUtil.PLATFORM_WINDOWS: + return PLATFORM_WINDOWS_NAME; + default: + return "unknown"; + } + } + + /** + * Locates the paths required by a library. + * + * @param libname + * Local Library Name to search the classloader with ("openal"). + * @param platform_lib_name + * The native library name ("libopenal.so") + * @param classloader + * The classloader to ask for library paths + * @return Paths to located libraries, if any + */ + public static String[] getLibraryPaths(String libname, String platform_lib_name, ClassLoader classloader) { + return getLibraryPaths(libname, new String[] { platform_lib_name }, classloader); + } + + /** + * Locates the paths required by a library. + * + * @param libname + * Local Library Name to search the classloader with ("openal"). + * @param platform_lib_names + * The list of possible library names ("libopenal.so") + * @param classloader + * The classloader to ask for library paths + * @return Paths to located libraries, if any + */ + public static String[] getLibraryPaths(String libname, String[] platform_lib_names, ClassLoader classloader) { + // need to pass path of possible locations of library to native side + List possible_paths = new ArrayList(); + + String classloader_path = getPathFromClassLoader(libname, classloader); + if (classloader_path != null) { + log("getPathFromClassLoader: Path found: " + classloader_path); + possible_paths.add(classloader_path); + } + + for (String platform_lib_name : platform_lib_names) { + String lwjgl_classloader_path = getPathFromClassLoader("lwjgl", classloader); + if (lwjgl_classloader_path != null) { + log("getPathFromClassLoader: Path found: " + lwjgl_classloader_path); + possible_paths + .add(lwjgl_classloader_path.substring(0, lwjgl_classloader_path.lastIndexOf(File.separator)) + + File.separator + platform_lib_name); + } + + // add Installer path + String alternative_path = getPrivilegedProperty("org.lwjgl.librarypath"); + if (alternative_path != null) { + possible_paths.add(alternative_path + File.separator + platform_lib_name); + } + + // Add all possible paths from java.library.path + String java_library_path = getPrivilegedProperty("java.library.path"); + + StringTokenizer st = new StringTokenizer(java_library_path, File.pathSeparator); + while (st.hasMoreTokens()) { + String path = st.nextToken(); + possible_paths.add(path + File.separator + platform_lib_name); + } + + // add current path + String current_dir = getPrivilegedProperty("user.dir"); + possible_paths.add(current_dir + File.separator + platform_lib_name); + + // add pure library (no path, let OS search) + possible_paths.add(platform_lib_name); + } + + // create needed string array + return possible_paths.toArray(new String[possible_paths.size()]); + } + + static void execPrivileged(final String[] cmd_array) throws Exception { + try { + Process process = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Process run() throws Exception { + return Runtime.getRuntime().exec(cmd_array); + } + }); + // Close unused streams to make sure the child process won't hang + process.getInputStream().close(); + process.getOutputStream().close(); + process.getErrorStream().close(); + } catch (PrivilegedActionException e) { + throw (Exception) e.getCause(); + } + } + + private static String getPrivilegedProperty(final String property_name) { + return AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return System.getProperty(property_name); + } + }); + } + + /** + * Tries to locate named library from the current ClassLoader This method + * exists because native libraries are loaded from native code, and as such + * is exempt from ClassLoader library loading rutines. It therefore always + * fails. We therefore invoke the protected method of the ClassLoader to see + * if it can locate it. + * + * @param libname + * Name of library to search for + * @param classloader + * Classloader to use + * @return Absolute path to library if found, otherwise null + */ + private static String getPathFromClassLoader(final String libname, final ClassLoader classloader) { + try { + log("getPathFromClassLoader: searching for: " + libname); + Class c = classloader.getClass(); + while (c != null) { + final Class clazz = c; + try { + return AccessController.doPrivileged(new PrivilegedExceptionAction() { + public String run() throws Exception { + Method findLibrary = clazz.getDeclaredMethod("findLibrary", String.class); + findLibrary.setAccessible(true); + String path = (String) findLibrary.invoke(classloader, libname); + return path; + } + }); + } catch (PrivilegedActionException e) { + log("Failed to locate findLibrary method: " + e.getCause()); + c = c.getSuperclass(); + } + } + } catch (Exception e) { + log("Failure locating " + e + " using classloader:" + e); + } + return null; + } + + /** + * Gets a boolean property as a privileged action. + */ + public static boolean getPrivilegedBoolean(final String property_name) { + return AccessController.doPrivileged(new PrivilegedAction() { + public Boolean run() { + return Boolean.getBoolean(property_name); + } + }); + } + + /** + * Gets an integer property as a privileged action. + * + * @param property_name + * the integer property name + * + * @return the property value + */ + public static Integer getPrivilegedInteger(final String property_name) { + return AccessController.doPrivileged(new PrivilegedAction() { + public Integer run() { + return Integer.getInteger(property_name); + } + }); + } + + /** + * Gets an integer property as a privileged action. + * + * @param property_name + * the integer property name + * @param default_val + * the default value to use if the property is not defined + * + * @return the property value + */ + public static Integer getPrivilegedInteger(final String property_name, final int default_val) { + return AccessController.doPrivileged(new PrivilegedAction() { + public Integer run() { + return Integer.getInteger(property_name, default_val); + } + }); + } + + /** + * Prints the given message to System.err if DEBUG is true. + * + * @param msg + * Message to print + */ + public static void log(CharSequence msg) { + if (DEBUG) { + System.err.println("[LWJGL] " + msg); + } + } + + /** + * Method to determine if the current system is running a version of Mac OS + * X better than the given version. This is only useful for Mac OS X + * specific code and will not work for any other platform. + */ + public static boolean isMacOSXEqualsOrBetterThan(int major_required, int minor_required) { + String os_version = getPrivilegedProperty("os.version"); + StringTokenizer version_tokenizer = new StringTokenizer(os_version, "."); + int major; + int minor; + try { + String major_str = version_tokenizer.nextToken(); + String minor_str = version_tokenizer.nextToken(); + major = Integer.parseInt(major_str); + minor = Integer.parseInt(minor_str); + } catch (Exception e) { + LWJGLUtil.log("Exception occurred while trying to determine OS version: " + e); + // Best guess, no + return false; + } + return major > major_required || (major == major_required && minor >= minor_required); + } + + /** + * Returns a map of public static final integer fields in the specified + * classes, to their String representations. An optional filter can be + * specified to only include specific fields. The target map may be null, in + * which case a new map is allocated and returned. + *

+ * This method is useful when debugging to quickly identify values returned + * from the AL/GL/CL APIs. + * + * @param filter + * the filter to use (optional) + * @param target + * the target map (optional) + * @param tokenClasses + * an array of classes to get tokens from + * + * @return the token map + */ + + public static Map getClassTokens(final TokenFilter filter, final Map target, + final Class... tokenClasses) { + return getClassTokens(filter, target, Arrays.asList(tokenClasses)); + } + + /** + * Returns a map of public static final integer fields in the specified + * classes, to their String representations. An optional filter can be + * specified to only include specific fields. The target map may be null, in + * which case a new map is allocated and returned. + *

+ * This method is useful when debugging to quickly identify values returned + * from the AL/GL/CL APIs. + * + * @param filter + * the filter to use (optional) + * @param target + * the target map (optional) + * @param tokenClasses + * the classes to get tokens from + * + * @return the token map + */ + public static Map getClassTokens(final TokenFilter filter, Map target, + final Iterable tokenClasses) { + if (target == null) + target = new HashMap(); + + final int TOKEN_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL; + + for (final Class tokenClass : tokenClasses) { + for (final Field field : tokenClass.getDeclaredFields()) { + // Get only fields. + if ((field.getModifiers() & TOKEN_MODIFIERS) == TOKEN_MODIFIERS && field.getType() == int.class) { + try { + final int value = field.getInt(null); + if (filter != null && !filter.accept(field, value)) + continue; + + if (target.containsKey(value)) // Print colliding tokens + // in their hex + // representation. + target.put(value, toHexString(value)); + else + target.put(value, field.getName()); + } catch (IllegalAccessException e) { + // Ignore + } + } + } + } + + return target; + } + + /** + * Returns a string representation of the integer argument as an unsigned + * integer in base 16. The string will be uppercase and will have a + * leading '0x'. + * + * @param value + * the integer value + * + * @return the hex string representation + */ + public static String toHexString(final int value) { + return "0x" + Integer.toHexString(value).toUpperCase(); + } + + /** Simple interface for Field filtering. */ + public interface TokenFilter { + + /** + * Should return true if the specified Field passes the filter. + * + * @param field + * the Field to test + * @param value + * the integer value of the field + * + * @result true if the Field is accepted + */ + boolean accept(Field field, int value); + + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/MemoryUtil.java.z b/jre_lwjgl3glfw/src/main/java/org/lwjgl/MemoryUtil.java.z new file mode 100644 index 000000000..9dd389abf --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/MemoryUtil.java.z @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl; + +import java.lang.reflect.Field; +import java.nio.*; +import java.nio.charset.*; + +/** + * [INTERNAL USE ONLY] + *

+ * This class provides utility methods for passing buffers to JNI API calls. + * + * @author Spasi + */ +public final class MemoryUtil { + + private static final Charset ascii; + private static final Charset utf8; + private static final Charset utf16; + + static { + ascii = Charset.forName("ISO-8859-1"); + utf8 = Charset.forName("UTF-8"); + utf16 = Charset.forName("UTF-16LE"); + } + + private static final Accessor memUtil; + + static { + Accessor util; + try { + // Depends on java.nio.Buffer#address and sun.misc.Unsafe + util = loadAccessor("org.lwjgl.MemoryUtilSun$AccessorUnsafe"); + } catch (Exception e0) { + try { + // Depends on java.nio.Buffer#address and sun.reflect.FieldAccessor + util = loadAccessor("org.lwjgl.MemoryUtilSun$AccessorReflectFast"); + } catch (Exception e1) { + try { + // Depends on java.nio.Buffer#address + util = new AccessorReflect(); + } catch (Exception e2) { + LWJGLUtil.log("Unsupported JVM detected, this will likely result in low performance. Please inform LWJGL developers."); + util = new AccessorJNI(); + } + } + } + + LWJGLUtil.log("MemoryUtil Accessor: " + util.getClass().getSimpleName()); + memUtil = util; + + /* + BENCHMARK RESULTS - Oracle Server VM: + + Unsafe: 4ns + ReflectFast: 8ns + Reflect: 10ns + JNI: 82ns + + BENCHMARK RESULTS - Oracle Client VM: + + Unsafe: 5ns + ReflectFast: 81ns + Reflect: 85ns + JNI: 87ns + + On non-Oracle VMs, Unsafe should be the fastest implementation as well. In the absence + of Unsafe, performance will depend on how reflection and JNI are implemented. For now + we'll go with what we see on the Oracle VM (that is, we'll prefer reflection over JNI). + */ + } + + private MemoryUtil() { + } + + /** + * Returns the memory address of the specified buffer. [INTERNAL USE ONLY] + * + * @param buffer the buffer + * + * @return the memory address + */ + public static long getAddress0(Buffer buffer) { return memUtil.getAddress(buffer); } + + public static long getAddress0Safe(Buffer buffer) { return buffer == null ? 0L : memUtil.getAddress(buffer); } + + public static long getAddress0(PointerBuffer buffer) { return memUtil.getAddress(buffer.getBuffer()); } + + public static long getAddress0Safe(PointerBuffer buffer) { return buffer == null ? 0L : memUtil.getAddress(buffer.getBuffer()); } + + // --- [ API utilities ] --- + + public static long getAddress(ByteBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(ByteBuffer buffer, int position) { return getAddress0(buffer) + position; } + + public static long getAddress(ShortBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(ShortBuffer buffer, int position) { return getAddress0(buffer) + (position << 1); } + + public static long getAddress(CharBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(CharBuffer buffer, int position) { return getAddress0(buffer) + (position << 1); } + + public static long getAddress(IntBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(IntBuffer buffer, int position) { return getAddress0(buffer) + (position << 2); } + + public static long getAddress(FloatBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(FloatBuffer buffer, int position) { return getAddress0(buffer) + (position << 2); } + + public static long getAddress(LongBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(LongBuffer buffer, int position) { return getAddress0(buffer) + (position << 3); } + + public static long getAddress(DoubleBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(DoubleBuffer buffer, int position) { return getAddress0(buffer) + (position << 3); } + + public static long getAddress(PointerBuffer buffer) { return getAddress(buffer, buffer.position()); } + + public static long getAddress(PointerBuffer buffer, int position) { return getAddress0(buffer) + (position * PointerBuffer.getPointerSize()); } + + // --- [ API utilities - Safe ] --- + + public static long getAddressSafe(ByteBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(ByteBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(ShortBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(ShortBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(CharBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(CharBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(IntBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(IntBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(FloatBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(FloatBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(LongBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(LongBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(DoubleBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(DoubleBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + public static long getAddressSafe(PointerBuffer buffer) { return buffer == null ? 0L : getAddress(buffer); } + + public static long getAddressSafe(PointerBuffer buffer, int position) { return buffer == null ? 0L : getAddress(buffer, position); } + + // --- [ String utilities ] --- + + /** + * Returns a ByteBuffer containing the specified text ASCII encoded and null-terminated. + * If text is null, null is returned. + * + * @param text the text to encode + * + * @return the encoded text or null + * + * @see String#getBytes() + */ + public static ByteBuffer encodeASCII(final CharSequence text) { + return encode(text, ascii); + } + + /** + * Returns a ByteBuffer containing the specified text UTF-8 encoded and null-terminated. + * If text is null, null is returned. + * + * @param text the text to encode + * + * @return the encoded text or null + * + * @see String#getBytes() + */ + public static ByteBuffer encodeUTF8(final CharSequence text) { + return encode(text, utf8); + } + + /** + * Returns a ByteBuffer containing the specified text UTF-16LE encoded and null-terminated. + * If text is null, null is returned. + * + * @param text the text to encode + * + * @return the encoded text + */ + public static ByteBuffer encodeUTF16(final CharSequence text) { + return encode(text, utf16); + } + + /** + * Wraps the specified text in a null-terminated CharBuffer and encodes it using the specified Charset. + * + * @param text the text to encode + * @param charset the charset to use for encoding + * + * @return the encoded text + */ + private static ByteBuffer encode(final CharSequence text, final Charset charset) { + if ( text == null ) + return null; + + return encode(CharBuffer.wrap(new CharSequenceNT(text)), charset); + } + + /** + * A {@link CharsetEncoder#encode(java.nio.CharBuffer)} implementation that uses {@link BufferUtils#createByteBuffer(int)} + * instead of {@link ByteBuffer#allocate(int)}. + * + * @see CharsetEncoder#encode(java.nio.CharBuffer) + */ + private static ByteBuffer encode(final CharBuffer in, final Charset charset) { + final CharsetEncoder encoder = charset.newEncoder(); // encoders are not thread-safe, create a new one on every call + + int n = (int)(in.remaining() * encoder.averageBytesPerChar()); + ByteBuffer out = BufferUtils.createByteBuffer(n); + + if ( n == 0 && in.remaining() == 0 ) + return out; + + encoder.reset(); + while ( true ) { + CoderResult cr = in.hasRemaining() ? encoder.encode(in, out, true) : CoderResult.UNDERFLOW; + if ( cr.isUnderflow() ) + cr = encoder.flush(out); + + if ( cr.isUnderflow() ) + break; + + if ( cr.isOverflow() ) { + n = 2 * n + 1; // Ensure progress; n might be 0! + ByteBuffer o = BufferUtils.createByteBuffer(n); + out.flip(); + o.put(out); + out = o; + continue; + } + + try { + cr.throwException(); + } catch (CharacterCodingException e) { + throw new RuntimeException(e); + } + } + out.flip(); + return out; + } + + public static String decodeASCII(final ByteBuffer buffer) { + return decode(buffer, ascii); + } + + public static String decodeUTF8(final ByteBuffer buffer) { + return decode(buffer, utf8); + } + + public static String decodeUTF16(final ByteBuffer buffer) { + return decode(buffer, utf16); + } + + private static String decode(final ByteBuffer buffer, final Charset charset) { + if ( buffer == null ) + return null; + + return decodeImpl(buffer, charset); + } + + private static String decodeImpl(final ByteBuffer in, final Charset charset) { + final CharsetDecoder decoder = charset.newDecoder(); // decoders are not thread-safe, create a new one on every call + + int n = (int)(in.remaining() * decoder.averageCharsPerByte()); + CharBuffer out = BufferUtils.createCharBuffer(n); + + if ( (n == 0) && (in.remaining() == 0) ) + return ""; + + decoder.reset(); + for (; ; ) { + CoderResult cr = in.hasRemaining() ? decoder.decode(in, out, true) : CoderResult.UNDERFLOW; + if ( cr.isUnderflow() ) + cr = decoder.flush(out); + + if ( cr.isUnderflow() ) + break; + if ( cr.isOverflow() ) { + n = 2 * n + 1; // Ensure progress; n might be 0! + CharBuffer o = BufferUtils.createCharBuffer(n); + out.flip(); + o.put(out); + out = o; + continue; + } + try { + cr.throwException(); + } catch (CharacterCodingException e) { + throw new RuntimeException(e); + } + } + out.flip(); + return out.toString(); + } + + /** A null-terminated CharSequence. */ + private static class CharSequenceNT implements CharSequence { + + final CharSequence source; + + CharSequenceNT(CharSequence source) { + this.source = source; + } + + public int length() { + return source.length() + 1; + + } + + public char charAt(final int index) { + return index == source.length() ? '\0' : source.charAt(index); + + } + + public CharSequence subSequence(final int start, final int end) { + return new CharSequenceNT(source.subSequence(start, Math.min(end, source.length()))); + } + + } + + interface Accessor { + + long getAddress(Buffer buffer); + + } + + private static Accessor loadAccessor(final String className) throws Exception { + return (Accessor)Class.forName(className).newInstance(); + } + + /** Default implementation. */ + private static class AccessorJNI implements Accessor { + + public long getAddress(final Buffer buffer) { + return BufferUtils.getBufferAddress(buffer); + } + + } + + /** Implementation using reflection on ByteBuffer. */ + private static class AccessorReflect implements Accessor { + + private final Field address; + + AccessorReflect() { + try { + address = getAddressField(); + } catch (NoSuchFieldException e) { + throw new UnsupportedOperationException(e); + } + address.setAccessible(true); + } + + public long getAddress(final Buffer buffer) { + try { + return address.getLong(buffer); + } catch (IllegalAccessException e) { + // cannot happen + return 0L; + } + } + + } + + static Field getAddressField() throws NoSuchFieldException { + return getDeclaredFieldRecursive(ByteBuffer.class, "address"); + } + + private static Field getDeclaredFieldRecursive(final Class root, final String fieldName) throws NoSuchFieldException { + Class type = root; + + do { + try { + return type.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + type = type.getSuperclass(); + } + } while ( type != null ); + + throw new NoSuchFieldException(fieldName + " does not exist in " + root.getSimpleName() + " or any of its superclasses."); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerBuffer.java.z b/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerBuffer.java.z new file mode 100644 index 000000000..990185312 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerBuffer.java.z @@ -0,0 +1,807 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + */ +package org.lwjgl; + +import org.lwjgl.system.*; + +import javax.annotation.*; +import java.nio.*; + +import static org.lwjgl.system.CheckIntrinsics.*; +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.MemoryUtil.*; + +/** This class is a container for architecture-independent pointer data. Its interface mirrors the {@link LongBuffer} API for convenience. */ +public class PointerBuffer extends CustomBuffer implements Comparable { +// -- Begin LWJGL2 parts -- + public PointerBuffer(final int capacity) { + this(allocateDirect(capacity)); + } + + public PointerBuffer(final ByteBuffer source) { + this(create(source)); + } + + // Workaround for LWJGL2 bridge + protected PointerBuffer(PointerBuffer copy) { + this(copy.address0(), copy.container, copy.mark, copy.position, copy.limit, copy.capacity); + } + + /** + * Returns the ByteBuffer that backs this PointerBuffer. + * + * @return the pointer ByteBuffer + */ + public ByteBuffer getBuffer() { + return container; + } + + /** Returns true if the underlying architecture is 64bit. */ + public static boolean is64Bit() { + return POINTER_SIZE == 8; + } + + /** + * Returns the pointer size in bytes, based on the underlying architecture. + * + * @return The pointer size in bytes + */ + public static int getPointerSize() { + return POINTER_SIZE; + } + + /** + * Returns this buffer's position, in bytes.

+ * + * @return The position of this buffer in bytes. + */ + public final int positionByte() { + return position() * getPointerSize(); + } + + /** + * Returns the number of bytes between the current position and the + * limit.

+ * + * @return The number of bytes remaining in this buffer + */ + public final int remainingByte() { + return remaining() * getPointerSize(); + } + + /** + * Creates a new, read-only pointer buffer that shares this buffer's + * content. + *

+ *

The content of the new buffer will be that of this buffer. Changes + * to this buffer's content will be visible in the new buffer; the new + * buffer itself, however, will be read-only and will not allow the shared + * content to be modified. The two buffers' position, limit, and mark + * values will be independent. + *

+ *

The new buffer's capacity, limit and position will be + * identical to those of this buffer. + *

+ *

If this buffer is itself read-only then this method behaves in + * exactly the same way as the {@link #duplicate duplicate} method.

+ * + * @return The new, read-only pointer buffer + */ + public PointerBuffer asReadOnlyBuffer() { + final PointerBuffer buffer = new PointerBufferR(container); + + buffer.position(position()); + buffer.limit(limit()); + + return buffer; + } + + public boolean isReadOnly() { + return false; + } + + + /** + * Read-only version of PointerBuffer. + * + * @author Spasi + */ + private static final class PointerBufferR extends PointerBuffer { + + PointerBufferR(final ByteBuffer source) { + super(source); + } + + public boolean isReadOnly() { + return true; + } + + protected PointerBuffer newInstance(final ByteBuffer source) { + return new PointerBufferR(source); + } + + public PointerBuffer asReadOnlyBuffer() { + return duplicate(); + } + + public PointerBuffer put(final long l) { + throw new ReadOnlyBufferException(); + } + + public PointerBuffer put(final int index, final long l) { + throw new ReadOnlyBufferException(); + } + + public PointerBuffer put(final PointerBuffer src) { + throw new ReadOnlyBufferException(); + } + + public PointerBuffer put(final long[] src, final int offset, final int length) { + throw new ReadOnlyBufferException(); + } + + public PointerBuffer compact() { + throw new ReadOnlyBufferException(); + } + + } +// -- End LWJGL2 parts -- + + protected PointerBuffer(long address, @Nullable ByteBuffer container, int mark, int position, int limit, int capacity) { + super(address, container, mark, position, limit, capacity); + } + + /** + * Allocates a new pointer buffer. + * + *

The new buffer's position will be zero, its limit will be its capacity, and its mark will be undefined.

+ * + * @param capacity the new buffer's capacity, in pointers + * + * @return the new pointer buffer + * + * @throws IllegalArgumentException If the {@code capacity} is a negative integer + */ + public static PointerBuffer allocateDirect(int capacity) { + ByteBuffer source = BufferUtils.createByteBuffer(BufferUtils.getAllocationSize(capacity, POINTER_SHIFT)); + return wrap(PointerBuffer.class, memAddress(source), capacity, source); + } + + /** + * Creates a new PointerBuffer that starts at the specified memory address and has the specified capacity. + * + * @param address the starting memory address + * @param capacity the buffer capacity, in number of pointers + */ + public static PointerBuffer create(long address, int capacity) { + return wrap(PointerBuffer.class, address, capacity); + } + + /** + * Creates a new PointerBuffer using the specified ByteBuffer as its pointer data source. + * + * @param source the source buffer + */ + public static PointerBuffer create(ByteBuffer source) { + int capacity = source.remaining() >> POINTER_SHIFT; + return wrap(PointerBuffer.class, memAddress(source), capacity, source); + } + + @Override + protected PointerBuffer self() { + return this; + } + + @Override + public int sizeof() { + return POINTER_SIZE; + } + + /** + * Relative get method. Reads the pointer at this buffer's current position, and then increments the position. + * + * @return the pointer at the buffer's current position + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public long get() { + return memGetAddress(address + Integer.toUnsignedLong(nextGetIndex()) * POINTER_SIZE); + } + + /** + * Convenience relative get from a source ByteBuffer. + * + * @param source the source ByteBuffer + */ + public static long get(ByteBuffer source) { + if (source.remaining() < POINTER_SIZE) { + throw new BufferUnderflowException(); + } + + try { + return memGetAddress(memAddress(source)); + } finally { + source.position(source.position() + POINTER_SIZE); + } + } + + /** + * Relative put method  (optional operation). + * + *

Writes the specified pointer into this buffer at the current position, and then increments the position.

+ * + * @param p the pointer to be written + * + * @return This buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer put(long p) { + memPutAddress(address + Integer.toUnsignedLong(nextPutIndex()) * POINTER_SIZE, p); + return this; + } + + /** + * Convenience relative put on a target ByteBuffer. + * + * @param target the target ByteBuffer + * @param p the pointer value to be written + */ + public static void put(ByteBuffer target, long p) { + if (target.remaining() < POINTER_SIZE) { + throw new BufferOverflowException(); + } + + try { + memPutAddress(memAddress(target), p); + } finally { + target.position(target.position() + POINTER_SIZE); + } + } + + /** + * Absolute get method. Reads the pointer at the specified {@code index}. + * + * @param index the index from which the pointer will be read + * + * @return the pointer at the specified {@code index} + * + * @throws IndexOutOfBoundsException If {@code index} is negative or not smaller than the buffer's limit + */ + public long get(int index) { + return memGetAddress(address + check(index, limit) * POINTER_SIZE); + } + + /** + * Convenience absolute get from a source ByteBuffer. + * + * @param source the source ByteBuffer + * @param index the index at which the pointer will be read + */ + public static long get(ByteBuffer source, int index) { + checkFromIndexSize(index, POINTER_SIZE, source.limit()); + return memGetAddress(memAddress0(source) + index); + } + + /** + * Absolute put method  (optional operation). + * + *

Writes the specified pointer into this buffer at the specified {@code index}.

+ * + * @param index the index at which the pointer will be written + * @param p the pointer value to be written + * + * @return This buffer + * + * @throws IndexOutOfBoundsException If {@code index} is negative or not smaller than the buffer's limit + */ + public PointerBuffer put(int index, long p) { + memPutAddress(address + check(index, limit) * POINTER_SIZE, p); + return this; + } + + /** + * Convenience absolute put on a target ByteBuffer. + * + * @param target the target ByteBuffer + * @param index the index at which the pointer will be written + * @param p the pointer value to be written + */ + public static void put(ByteBuffer target, int index, long p) { + checkFromIndexSize(index, POINTER_SIZE, target.limit()); + memPutAddress(memAddress0(target) + index, p); + } + + // -- PointerWrapper operations -- + + /** Puts the pointer value of the specified {@link Pointer} at the current position and then increments the position. */ + public PointerBuffer put(Pointer pointer) { + put(pointer.address()); + return this; + } + + /** Puts the pointer value of the specified {@link Pointer} at the specified {@code index}. */ + public PointerBuffer put(int index, Pointer pointer) { + put(index, pointer.address()); + return this; + } + + // -- Buffer address operations -- + + /** + *

Writes the address of the specified {@code buffer} into this buffer at the current position, and then increments the position.

+ * + * @param buffer the pointer to be written + * + * @return this buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer put(ByteBuffer buffer) { + put(memAddress(buffer)); + return this; + } + + /** + *

Writes the address of the specified {@code buffer} into this buffer at the current position, and then increments the position.

+ * + * @param buffer the pointer to be written + * + * @return this buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer put(ShortBuffer buffer) { + put(memAddress(buffer)); + return this; + } + + /** + *

Writes the address of the specified {@code buffer} into this buffer at the current position, and then increments the position.

+ * + * @param buffer the pointer to be written + * + * @return this buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer put(IntBuffer buffer) { + put(memAddress(buffer)); + return this; + } + + /** + *

Writes the address of the specified {@code buffer} into this buffer at the current position, and then increments the position.

+ * + * @param buffer the pointer to be written + * + * @return this buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer put(LongBuffer buffer) { + put(memAddress(buffer)); + return this; + } + + /** + *

Writes the address of the specified {@code buffer} into this buffer at the current position, and then increments the position.

+ * + * @param buffer the pointer to be written + * + * @return this buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer put(FloatBuffer buffer) { + put(memAddress(buffer)); + return this; + } + + /** + *

Writes the address of the specified {@code buffer} into this buffer at the current position, and then increments the position.

+ * + * @param buffer the pointer to be written + * + * @return this buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer put(DoubleBuffer buffer) { + put(memAddress(buffer)); + return this; + } + + /** + *

Writes the address of the specified {@code buffer} into this buffer at the current position, and then increments the position.

+ * + * @param buffer the pointer to be written + * + * @return this buffer + * + * @throws BufferOverflowException If this buffer's current position is not smaller than its limit + */ + public PointerBuffer putAddressOf(CustomBuffer buffer) { + put(memAddress(buffer)); + return this; + } + + // --- + + /** Puts the address of the specified {@code buffer} at the specified {@code index}. */ + public PointerBuffer put(int index, ByteBuffer buffer) { + put(index, memAddress(buffer)); + return this; + } + + /** Puts the address of the specified {@code buffer} at the specified {@code index}. */ + public PointerBuffer put(int index, ShortBuffer buffer) { + put(index, memAddress(buffer)); + return this; + } + + /** Puts the address of the specified {@code buffer} at the specified {@code index}. */ + public PointerBuffer put(int index, IntBuffer buffer) { + put(index, memAddress(buffer)); + return this; + } + + /** Puts the address of the specified {@code buffer} at the specified {@code index}. */ + public PointerBuffer put(int index, LongBuffer buffer) { + put(index, memAddress(buffer)); + return this; + } + + /** Puts the address of the specified {@code buffer} at the specified {@code index}. */ + public PointerBuffer put(int index, FloatBuffer buffer) { + put(index, memAddress(buffer)); + return this; + } + + /** Puts the address of the specified {@code buffer} at the specified {@code index}. */ + public PointerBuffer put(int index, DoubleBuffer buffer) { + put(index, memAddress(buffer)); + return this; + } + + /** Puts the address of the specified {@code buffer} at the specified {@code index}. */ + public PointerBuffer putAddressOf(int index, CustomBuffer buffer) { + put(index, memAddress(buffer)); + return this; + } + + // --- + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is returned as a {@link ByteBuffer} instance that + * starts at the pointer address and has capacity equal to the specified {@code size}. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public ByteBuffer getByteBuffer(int size) { return memByteBuffer(get(), size); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is returned as a {@link ShortBuffer} instance that + * starts at the pointer address and has capacity equal to the specified {@code size}. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public ShortBuffer getShortBuffer(int size) { return memShortBuffer(get(), size); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is returned as a {@link IntBuffer} instance that + * starts at the pointer address and has capacity equal to the specified {@code size}. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public IntBuffer getIntBuffer(int size) { return memIntBuffer(get(), size); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is returned as a {@link LongBuffer} instance that + * starts at the pointer address and has capacity equal to the specified {@code size}. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public LongBuffer getLongBuffer(int size) { return memLongBuffer(get(), size); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is returned as a {@link FloatBuffer} instance that + * starts at the pointer address and has capacity equal to the specified {@code size}. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public FloatBuffer getFloatBuffer(int size) { return memFloatBuffer(get(), size); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is returned as a {@link DoubleBuffer} instance that + * starts at the pointer address and has capacity equal to the specified {@code size}. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public DoubleBuffer getDoubleBuffer(int size) { return memDoubleBuffer(get(), size); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is returned as a {@code PointerBuffer} instance that + * starts at the pointer address and has capacity equal to the specified {@code size}. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public PointerBuffer getPointerBuffer(int size) { return memPointerBuffer(get(), size); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is evaluated as a null-terminated ASCII string, which + * is decoded and returned as a {@link String} instance. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public String getStringASCII() { return memASCII(get()); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is evaluated as a null-terminated UTF-8 string, which + * is decoded and returned as a {@link String} instance. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public String getStringUTF8() { return memUTF8(get()); } + + /** + * Reads the pointer at this buffer's current position, and then increments the position. The pointer is evaluated as a null-terminated UTF-16 string, + * which is decoded and returned as a {@link String} instance. + * + * @throws BufferUnderflowException If the buffer's current position is not smaller than its limit + */ + public String getStringUTF16() { return memUTF16(get()); } + + // --- + + /** Returns a {@link ByteBuffer} instance that starts at the address found at the specified {@code index} and has capacity equal to the specified size. */ + public ByteBuffer getByteBuffer(int index, int size) { return memByteBuffer(get(index), size); } + + /** Returns a {@link ShortBuffer} instance that starts at the address found at the specified {@code index} and has capacity equal to the specified size. */ + public ShortBuffer getShortBuffer(int index, int size) { return memShortBuffer(get(index), size); } + + /** Returns a {@link IntBuffer} instance that starts at the address found at the specified {@code index} and has capacity equal to the specified size. */ + public IntBuffer getIntBuffer(int index, int size) { return memIntBuffer(get(index), size); } + + /** Returns a {@link LongBuffer} instance that starts at the address found at the specified {@code index} and has capacity equal to the specified size. */ + public LongBuffer getLongBuffer(int index, int size) { return memLongBuffer(get(index), size); } + + /** Returns a {@link FloatBuffer} instance that starts at the address found at the specified {@code index} and has capacity equal to the specified size. */ + public FloatBuffer getFloatBuffer(int index, int size) { return memFloatBuffer(get(index), size); } + + /** Returns a {@link DoubleBuffer} instance that starts at the address found at the specified {@code index} and has capacity equal to the specified size. */ + public DoubleBuffer getDoubleBuffer(int index, int size) { return memDoubleBuffer(get(index), size); } + + /** Returns a {@code PointerBuffer} instance that starts at the address found at the specified {@code index} and has capacity equal to the specified size. */ + public PointerBuffer getPointerBuffer(int index, int size) { return memPointerBuffer(get(index), size); } + + /** Decodes the ASCII string that starts at the address found at the specified {@code index}. */ + public String getStringASCII(int index) { return memASCII(get(index)); } + + /** Decodes the UTF-8 string that starts at the address found at the specified {@code index}. */ + public String getStringUTF8(int index) { return memUTF8(get(index)); } + + /** Decodes the UTF-16 string that starts at the address found at the specified {@code index}. */ + public String getStringUTF16(int index) { return memUTF16(get(index)); } + + // -- Bulk get operations -- + + /** + * Relative bulk get method. + * + *

This method transfers pointers from this buffer into the specified destination array. An invocation of this method of the form {@code src.get(a)} + * behaves in exactly the same way as the invocation + * + *

+     *     src.get(a, 0, a.length) 
+ * + * @return This buffer + * + * @throws BufferUnderflowException If there are fewer than {@code length} pointers remaining in this buffer + */ + public PointerBuffer get(long[] dst) { + return get(dst, 0, dst.length); + } + + /** + * Relative bulk get method. + * + *

This method transfers pointers from this buffer into the specified destination array. If there are fewer pointers remaining in the buffer than are + * required to satisfy the request, that is, if {@code length} {@code >} {@code remaining()}, then no pointers are transferred and a + * {@link BufferUnderflowException} is thrown. + * + *

Otherwise, this method copies {@code length} pointers from this buffer into the specified array, starting at the current position of this buffer and + * at the specified offset in the array. The position of this buffer is then incremented by {@code length}. + * + *

In other words, an invocation of this method of the form {@code src.get(dst, off, len)} has exactly the same effect as the loop

+ * + *
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get(); 
+ * + *

except that it first checks that there are sufficient pointers in this buffer and it is potentially much more efficient.

+ * + * @param dst the array into which pointers are to be written + * @param offset the offset within the array of the first pointer to be written; must be non-negative and no larger than {@code dst.length} + * @param length the maximum number of pointers to be written to the specified array; must be non-negative and no larger than {@code dst.length - offset} + * + * @return This buffer + * + * @throws BufferUnderflowException If there are fewer than {@code length} pointers remaining in this buffer + * @throws IndexOutOfBoundsException If the preconditions on the {@code offset} and {@code length} parameters do not hold + */ + public PointerBuffer get(long[] dst, int offset, int length) { + if (BITS64) { + memLongBuffer(address(), remaining()).get(dst, offset, length); + position(position() + length); + } else { + get32(dst, offset, length); + } + + return this; + } + + private void get32(long[] dst, int offset, int length) { + checkFromIndexSize(offset, length, dst.length); + if (remaining() < length) { + throw new BufferUnderflowException(); + } + for (int i = offset, end = offset + length; i < end; i++) { + dst[i] = get(); + } + } + + /** + * Relative bulk put method  (optional operation). + * + *

This method transfers the entire content of the specified source pointer array into this buffer. An invocation of this method of the form + * {@code dst.put(a)} behaves in exactly the same way as the invocation

+ * + *
+     *     dst.put(a, 0, a.length) 
+ * + * @return This buffer + * + * @throws BufferOverflowException If there is insufficient space in this buffer + */ + public PointerBuffer put(long[] src) { + return put(src, 0, src.length); + } + + /** + * Relative bulk put method  (optional operation). + * + *

This method transfers pointers into this buffer from the specified source array. If there are more pointers to be copied from the array than remain + * in this buffer, that is, if {@code length} {@code >} {@code remaining()}, then no pointers are transferred and a + * {@link BufferOverflowException} is thrown. + * + *

Otherwise, this method copies {@code length} pointers from the specified array into this buffer, starting at the specified offset in the array and + * at the current position of this buffer. The position of this buffer is then incremented by {@code length}.

+ * + *

In other words, an invocation of this method of the form {@code dst.put(src, off, len)} has exactly the same effect as the loop

+ * + *
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]); 
+ * + *

except that it first checks that there is sufficient space in this buffer and it is potentially much more efficient.

+ * + * @param src the array from which pointers are to be read + * @param offset the offset within the array of the first pointer to be read; must be non-negative and no larger than {@code array.length} + * @param length the number of pointers to be read from the specified array; must be non-negative and no larger than {@code array.length - offset} + * + * @return This buffer + * + * @throws BufferOverflowException If there is insufficient space in this buffer + * @throws IndexOutOfBoundsException If the preconditions on the {@code offset} and {@code length} parameters do not hold + */ + public PointerBuffer put(long[] src, int offset, int length) { + if (BITS64) { + memLongBuffer(address(), remaining()).put(src, offset, length); + position(position() + length); + } else { + put32(src, offset, length); + } + + return this; + } + + private void put32(long[] src, int offset, int length) { + checkFromIndexSize(offset, length, src.length); + if (remaining() < length) { + throw new BufferOverflowException(); + } + int end = offset + length; + for (int i = offset; i < end; i++) { + put(src[i]); + } + } + + /** + * Returns the current hash code of this buffer. + * + *

The hash code of a pointer buffer depends only upon its remaining elements; that is, upon the elements from {@code position()} up to, and including, + * the element at {@code limit()} - {@code 1}.

+ * + *

Because buffer hash codes are content-dependent, it is inadvisable to use buffers as keys in hash maps or similar data structures unless it is known + * that their contents will not change.

+ * + * @return the current hash code of this buffer + */ + public int hashCode() { + int h = 1; + int p = position(); + for (int i = limit() - 1; i >= p; i--) { + h = 31 * h + (int)get(i); + } + return h; + } + + /** + * Tells whether or not this buffer is equal to another object. + * + *

Two pointer buffers are equal if, and only if,

+ * + *
    + *
  1. They have the same element type,
  2. + *
  3. They have the same number of remaining elements, and
  4. + *
  5. The two sequences of remaining elements, considered + * independently of their starting positions, are pointwise equal.
  6. + *
+ * + *

A pointer buffer is not equal to any other type of object.

+ * + * @param ob the object to which this buffer is to be compared + * + * @return {@code true} if, and only if, this buffer is equal to the + * given object + */ + public boolean equals(Object ob) { + if (!(ob instanceof PointerBuffer)) { + return false; + } + PointerBuffer that = (PointerBuffer)ob; + if (this.remaining() != that.remaining()) { + return false; + } + int p = this.position(); + for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) { + long v1 = this.get(i); + long v2 = that.get(j); + if (v1 != v2) { + return false; + } + } + return true; + } + + /** + * Compares this buffer to another. + * + *

Two pointer buffers are compared by comparing their sequences of remaining elements lexicographically, without regard to the starting position of + * each sequence within its corresponding buffer.

+ * + *

A pointer buffer is not comparable to any other type of object.

+ * + * @return A negative integer, zero, or a positive integer as this buffer is less than, equal to, or greater than the specified buffer + */ + @Override + public int compareTo(PointerBuffer that) { + int n = this.position() + Math.min(this.remaining(), that.remaining()); + for (int i = this.position(), j = that.position(); i < n; i++, j++) { + long v1 = this.get(i); + long v2 = that.get(j); + if (v1 == v2) { + continue; + } + if (v1 < v2) { + return -1; + } + return +1; + } + return this.remaining() - that.remaining(); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapper.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapper.java new file mode 100644 index 000000000..f68f18dd9 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapper.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl; + +/** + * A common interface for classes that wrap pointer addresses. + * + * @author Spasi + */ +public interface PointerWrapper { + + long getPointer(); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapperAbstract.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapperAbstract.java new file mode 100644 index 000000000..56f17aebf --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/PointerWrapperAbstract.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2002-2010 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl; + +/** + * Base PointerWrapper implementation. + * + * @author Spasi + */ +public abstract class PointerWrapperAbstract implements PointerWrapper { + + protected final long pointer; + + protected PointerWrapperAbstract(final long pointer) { + this.pointer = pointer; + } + + /** + * Returns true if this object represents a valid pointer. + * The pointer might be invalid because it is NULL or because + * some other action has deleted the object that this pointer + * represents. + * + * @return true if the pointer is valid + */ + public boolean isValid() { + return pointer != 0; + } + + /** + * Checks if the pointer is valid and throws an IllegalStateException if + * it is not. This method is a NO-OP, unless the org.lwjgl.util.Debug + * property has been set to true. + */ + public final void checkValid() { + if ( LWJGLUtil.DEBUG && !isValid() ) + throw new IllegalStateException("This " + getClass().getSimpleName() + " pointer is not valid."); + } + + public final long getPointer() { + checkValid(); + return pointer; + } + + public boolean equals(final Object o) { + if ( this == o ) return true; + if ( !(o instanceof PointerWrapperAbstract) ) return false; + + final PointerWrapperAbstract that = (PointerWrapperAbstract)o; + + if ( pointer != that.pointer ) return false; + + return true; + } + + public int hashCode() { + return (int)(pointer ^ (pointer >>> 32)); + } + + public String toString() { + return getClass().getSimpleName() + " pointer (0x" + Long.toHexString(pointer).toUpperCase() + ")"; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/Sys.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/Sys.java new file mode 100644 index 000000000..17299f66f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/Sys.java @@ -0,0 +1,87 @@ +package org.lwjgl; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.glfw.GLFW; + +import java.awt.Desktop; +import java.net.URI; + +import javax.swing.JOptionPane; +import javax.swing.UIManager; + +public class Sys { + + /** + * No constructor for Sys. + */ + private Sys() { + } + + /** Returns the LWJGL version. */ + public static String getVersion() { + return org.lwjgl.Version.getVersion(); + } + + public static void initialize() { + if (!GLFW.glfwInit()) + throw new IllegalStateException("Unable to initialize GLFW"); + } + + /** + * GLFW automatically recomputes the time via + * {@link GLFW#glfwGetTimerValue()}, no need to divide the frequency + * + * @return 1 + */ + public static long getTimerResolution() { + return 1000; + } + + /** + * Gets the current value of the hires timer, in ticks. When the Sys class + * is first loaded the hi-res timer is reset to 0. If no hi-res timer is + * present then this method will always return 0. + *

+ * PLEASE NOTE: the hi-res timer WILL wrap around. + * + * @return the current hi-res time, in ticks (always >= 0) + */ + public static long getTime() { + return GLFW.glfwGetTimerValue(); + } + + public static long getNanoTime() { + return System.nanoTime(); + // return getTime() * 1000L * 1000L; + } + + public static boolean openURL(String url) { + if (!Desktop.isDesktopSupported()) + return false; + + Desktop desktop = Desktop.getDesktop(); + if (!desktop.isSupported(Desktop.Action.BROWSE)) + return false; + + try { + desktop.browse(new URI(url)); + return true; + } catch (Exception ex) { + ex.printStackTrace(); + return false; + } + } + + public static void alert(String title, String message) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + LWJGLUtil.log("Caught exception while setting Look-and-Feel: " + e); + } + JOptionPane.showMessageDialog(null, message, title, JOptionPane.WARNING_MESSAGE); + } + + public static String getClipboard() { + return GLFW.glfwGetClipboardString(GLFW.glfwGetPrimaryMonitor()); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java new file mode 100644 index 000000000..e9a34a682 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/CallbackBridge.java @@ -0,0 +1,82 @@ +package org.lwjgl.glfw; +import java.io.*; +import java.util.*; +import android.util.*; + +public class CallbackBridge { + public static final int CLIPBOARD_COPY = 2000; + public static final int CLIPBOARD_PASTE = 2001; + + public static final int EVENT_TYPE_CHAR = 1000; + public static final int EVENT_TYPE_CHAR_MODS = 1001; + public static final int EVENT_TYPE_CURSOR_ENTER = 1002; + public static final int EVENT_TYPE_CURSOR_POS = 1003; + public static final int EVENT_TYPE_FRAMEBUFFER_SIZE = 1004; + public static final int EVENT_TYPE_KEY = 1005; + public static final int EVENT_TYPE_MOUSE_BUTTON = 1006; + public static final int EVENT_TYPE_SCROLL = 1007; + public static final int EVENT_TYPE_WINDOW_SIZE = 1008; + + public static final int ANDROID_TYPE_GRAB_STATE = 0; + + // Should pending events be limited? + volatile public static List PENDING_EVENT_LIST = new ArrayList<>(); + volatile public static boolean PENDING_EVENT_READY = false; + + public static final boolean INPUT_DEBUG_ENABLED; + + // TODO send grab state event to Android + + static { + INPUT_DEBUG_ENABLED = Boolean.parseBoolean(System.getProperty("glfwstub.debugInput", "false")); + + +/* + if (isDebugEnabled) { + //try { + //debugEventStream = new PrintStream(new File(System.getProperty("user.dir"), "glfwstub_inputeventlog.txt")); + debugEventStream = System.out; + //} catch (FileNotFoundException e) { + // e.printStackTrace(); + //} + } + + //Quick and dirty: debul all key inputs to System.out +*/ + } + + public static void sendGrabbing(boolean grab, int xset, int yset) { + // sendData(ANDROID_TYPE_GRAB_STATE, Boolean.toString(grab)); + + GLFW.mGLFWIsGrabbing = grab; + nativeSetGrabbing(grab, xset, yset); + } + + // Called from Android side + public static void receiveCallback(int type, int i1, int i2, int i3, int i4) { + /* + if (INPUT_DEBUG_ENABLED) { + System.out.println("LWJGL GLFW Callback received type=" + Integer.toString(type) + ", data=" + i1 + ", " + i2 + ", " + i3 + ", " + i4); + } + */ + if (PENDING_EVENT_READY) { + if (type == EVENT_TYPE_CURSOR_POS) { + GLFW.mGLFWCursorX = i1; + GLFW.mGLFWCursorY = i2; + } else { + PENDING_EVENT_LIST.add(new Integer[]{type, i1, i2, i3, i4}); + } + } // else System.out.println("Event input is not ready yet!"); + } + + public static void sendData(int type, String data) { + nativeSendData(false, type, data); + } + + public static native void nativeSendData(boolean isAndroid, int type, String data); + public static native boolean nativeSetInputReady(boolean ready); + public static native String nativeClipboard(int action, String copy); + + private static native void nativeSetGrabbing(boolean grab, int xset, int yset); +} + diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/Callbacks.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/Callbacks.java new file mode 100644 index 000000000..9216a1c34 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/Callbacks.java @@ -0,0 +1,72 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryUtil.*; +import java.lang.reflect.*; + +/** Utility class for GLFW callbacks. */ +public final class Callbacks { + + private Callbacks() {} + + /** + * Resets all callbacks for the specified GLFW window to {@code NULL} and {@link Callback#free frees} all previously set callbacks. + * + *

This method resets only callbacks registered with a GLFW window. Non-window callbacks (registered with + * {@link GLFW#glfwSetErrorCallback SetErrorCallback}, {@link GLFW#glfwSetMonitorCallback SetMonitorCallback}, etc.) must be reset and freed + * separately.

+ * + *

This method is not official GLFW API. It exists in LWJGL to simplify window callback cleanup.

+ * + * @param window the GLFW window + */ + public static void glfwFreeCallbacks(@NativeType("GLFWwindow *") long window) { + if (Checks.CHECKS) { + check(window); + } + + try { + for (Field callback : GLFW.class.getFields()) { + if (callback.getName().startsWith("mGLFW") && callback.getName().endsWith("Callback")) { + callback.set(null, null); + } + } + } catch (IllegalAccessException|NullPointerException e) { + throw new RuntimeException("org.lwjgl.GLFW.mGLFWxxxCallbacks must be set to public and static", e); + } + +/* + for (long callback : new long[] { + GLFW.Functions.SetWindowPosCallback, + GLFW.Functions.SetWindowSizeCallback, + GLFW.Functions.SetWindowCloseCallback, + GLFW.Functions.SetWindowRefreshCallback, + GLFW.Functions.SetWindowFocusCallback, + GLFW.Functions.SetWindowIconifyCallback, + GLFW.Functions.SetWindowMaximizeCallback, + GLFW.Functions.SetFramebufferSizeCallback, + GLFW.Functions.SetWindowContentScaleCallback, + GLFW.Functions.SetKeyCallback, + GLFW.Functions.SetCharCallback, + GLFW.Functions.SetCharModsCallback, + GLFW.Functions.SetMouseButtonCallback, + GLFW.Functions.SetCursorPosCallback, + GLFW.Functions.SetCursorEnterCallback, + GLFW.Functions.SetScrollCallback, + GLFW.Functions.SetDropCallback + }) { + long prevCB = invokePPP(window, NULL, callback); + if (prevCB != NULL) { + Callback.free(prevCB); + } + } +*/ + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/EventLoop.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/EventLoop.java new file mode 100644 index 000000000..8f8113f1a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/EventLoop.java @@ -0,0 +1,85 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; +import org.lwjgl.system.macosx.*; + +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.macosx.LibC.*; +import static org.lwjgl.system.macosx.ObjCRuntime.*; + +/** + * Contains checks for the event loop issues on OS X. + * + *

On-screen GLFW windows can only be used in the main thread and only if that thread is the first thread in the process. This requires running the JVM with + * {@code -XstartOnFirstThread}, which means that other window toolkits (AWT/Swing, JavaFX, etc.) cannot be used at the same time.

+ * + *

Another window toolkit can be used if GLFW windows are never shown (created with {@link GLFW#GLFW_VISIBLE GLFW_VISIBLE} equal to + * {@link GLFW#GLFW_FALSE GLFW_FALSE}) and only used as contexts for offscreen rendering. This is possible if the window toolkit has initialized and created + * the shared application (NSApp) before a GLFW window is created.

+ */ +final class EventLoop { + + static final class OffScreen { + static { + if (Platform.get() == Platform.MACOSX && !isMainThread()) { + // The only way to avoid a crash is if the shared application (NSApp) has been created by something else + throw new IllegalStateException( + isJavaStartedOnFirstThread() + ? "GLFW windows may only be created on the main thread." + : "GLFW windows may only be created on the main thread and that thread must be the first thread in the process. Please run " + + "the JVM with -XstartOnFirstThread. For offscreen rendering, make sure another window toolkit (e.g. AWT or JavaFX) is " + + "initialized before GLFW and Configuration.GLFW_CHECK_THREAD0 is set to false." + ); + } + } + + private OffScreen() { + } + + static void check() { + // intentionally empty to trigger the static initializer + } + } + + static final class OnScreen { + static { + if (Platform.get() == Platform.MACOSX && !isMainThread()) { + throw new IllegalStateException( + "Please run the JVM with -XstartOnFirstThread and make sure a window toolkit other than GLFW (e.g. AWT or JavaFX) is not initialized." + ); + } + } + + private OnScreen() { + } + + static void check() { + // intentionally empty to trigger the static initializer + } + } + + private EventLoop() { + } + + private static boolean isMainThread() { + if (!Configuration.GLFW_CHECK_THREAD0.get(true)) { + return true; + } + + long objc_msgSend = ObjCRuntime.getLibrary().getFunctionAddress("objc_msgSend"); + + long NSThread = objc_getClass("NSThread"); + long currentThread = invokePPP(NSThread, sel_getUid("currentThread"), objc_msgSend); + + return invokePPZ(currentThread, sel_getUid("isMainThread"), objc_msgSend); + } + + private static boolean isJavaStartedOnFirstThread() { + return "1".equals(System.getenv().get("JAVA_STARTED_ON_FIRST_THREAD_" + getpid())); + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java new file mode 100644 index 000000000..641aa1e9e --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -0,0 +1,1224 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + */ +package org.lwjgl.glfw; + +import android.util.*; + +import java.lang.reflect.*; +import java.nio.*; + +import javax.annotation.*; + +import org.lwjgl.*; +import org.lwjgl.opengl.GL; +import org.lwjgl.system.*; + +import static org.lwjgl.system.APIUtil.*; +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.MemoryUtil.*; +import java.util.*; + +public class GLFW +{ + /** The major version number of the GLFW library. This is incremented when the API is changed in non-compatible ways. */ + public static final int GLFW_VERSION_MAJOR = 3; + + /** The minor version number of the GLFW library. This is incremented when features are added to the API but it remains backward-compatible. */ + public static final int GLFW_VERSION_MINOR = 4; + + /** The revision number of the GLFW library. This is incremented when a bug fix release is made that does not contain any API changes. */ + public static final int GLFW_VERSION_REVISION = 0; + + /** Boolean values. */ + public static final int + GLFW_TRUE = 1, + GLFW_FALSE = 0; + + /** The key or button was released. */ + public static final int GLFW_RELEASE = 0; + + /** The key or button was pressed. */ + public static final int GLFW_PRESS = 1; + + /** The key was held down until it repeated. */ + public static final int GLFW_REPEAT = 2; + + /** Joystick hat states. */ + public static final int + GLFW_HAT_CENTERED = 0, + GLFW_HAT_UP = 1, + GLFW_HAT_RIGHT = 2, + GLFW_HAT_DOWN = 4, + GLFW_HAT_LEFT = 8, + GLFW_HAT_RIGHT_UP = (GLFW_HAT_RIGHT | GLFW_HAT_UP), + GLFW_HAT_RIGHT_DOWN = (GLFW_HAT_RIGHT | GLFW_HAT_DOWN), + GLFW_HAT_LEFT_UP = (GLFW_HAT_LEFT | GLFW_HAT_UP), + GLFW_HAT_LEFT_DOWN = (GLFW_HAT_LEFT | GLFW_HAT_DOWN); + + /** The unknown key. */ + public static final int GLFW_KEY_UNKNOWN = -1; + + /** Printable keys. */ + public static final int + GLFW_KEY_SPACE = 32, + GLFW_KEY_APOSTROPHE = 39, + GLFW_KEY_COMMA = 44, + GLFW_KEY_MINUS = 45, + GLFW_KEY_PERIOD = 46, + GLFW_KEY_SLASH = 47, + GLFW_KEY_0 = 48, + GLFW_KEY_1 = 49, + GLFW_KEY_2 = 50, + GLFW_KEY_3 = 51, + GLFW_KEY_4 = 52, + GLFW_KEY_5 = 53, + GLFW_KEY_6 = 54, + GLFW_KEY_7 = 55, + GLFW_KEY_8 = 56, + GLFW_KEY_9 = 57, + GLFW_KEY_SEMICOLON = 59, + GLFW_KEY_EQUAL = 61, + GLFW_KEY_A = 65, + GLFW_KEY_B = 66, + GLFW_KEY_C = 67, + GLFW_KEY_D = 68, + GLFW_KEY_E = 69, + GLFW_KEY_F = 70, + GLFW_KEY_G = 71, + GLFW_KEY_H = 72, + GLFW_KEY_I = 73, + GLFW_KEY_J = 74, + GLFW_KEY_K = 75, + GLFW_KEY_L = 76, + GLFW_KEY_M = 77, + GLFW_KEY_N = 78, + GLFW_KEY_O = 79, + GLFW_KEY_P = 80, + GLFW_KEY_Q = 81, + GLFW_KEY_R = 82, + GLFW_KEY_S = 83, + GLFW_KEY_T = 84, + GLFW_KEY_U = 85, + GLFW_KEY_V = 86, + GLFW_KEY_W = 87, + GLFW_KEY_X = 88, + GLFW_KEY_Y = 89, + GLFW_KEY_Z = 90, + GLFW_KEY_LEFT_BRACKET = 91, + GLFW_KEY_BACKSLASH = 92, + GLFW_KEY_RIGHT_BRACKET = 93, + GLFW_KEY_GRAVE_ACCENT = 96, + GLFW_KEY_WORLD_1 = 161, + GLFW_KEY_WORLD_2 = 162; + + /** Function keys. */ + public static final int + GLFW_KEY_ESCAPE = 256, + GLFW_KEY_ENTER = 257, + GLFW_KEY_TAB = 258, + GLFW_KEY_BACKSPACE = 259, + GLFW_KEY_INSERT = 260, + GLFW_KEY_DELETE = 261, + GLFW_KEY_RIGHT = 262, + GLFW_KEY_LEFT = 263, + GLFW_KEY_DOWN = 264, + GLFW_KEY_UP = 265, + GLFW_KEY_PAGE_UP = 266, + GLFW_KEY_PAGE_DOWN = 267, + GLFW_KEY_HOME = 268, + GLFW_KEY_END = 269, + GLFW_KEY_CAPS_LOCK = 280, + GLFW_KEY_SCROLL_LOCK = 281, + GLFW_KEY_NUM_LOCK = 282, + GLFW_KEY_PRINT_SCREEN = 283, + GLFW_KEY_PAUSE = 284, + GLFW_KEY_F1 = 290, + GLFW_KEY_F2 = 291, + GLFW_KEY_F3 = 292, + GLFW_KEY_F4 = 293, + GLFW_KEY_F5 = 294, + GLFW_KEY_F6 = 295, + GLFW_KEY_F7 = 296, + GLFW_KEY_F8 = 297, + GLFW_KEY_F9 = 298, + GLFW_KEY_F10 = 299, + GLFW_KEY_F11 = 300, + GLFW_KEY_F12 = 301, + GLFW_KEY_F13 = 302, + GLFW_KEY_F14 = 303, + GLFW_KEY_F15 = 304, + GLFW_KEY_F16 = 305, + GLFW_KEY_F17 = 306, + GLFW_KEY_F18 = 307, + GLFW_KEY_F19 = 308, + GLFW_KEY_F20 = 309, + GLFW_KEY_F21 = 310, + GLFW_KEY_F22 = 311, + GLFW_KEY_F23 = 312, + GLFW_KEY_F24 = 313, + GLFW_KEY_F25 = 314, + GLFW_KEY_KP_0 = 320, + GLFW_KEY_KP_1 = 321, + GLFW_KEY_KP_2 = 322, + GLFW_KEY_KP_3 = 323, + GLFW_KEY_KP_4 = 324, + GLFW_KEY_KP_5 = 325, + GLFW_KEY_KP_6 = 326, + GLFW_KEY_KP_7 = 327, + GLFW_KEY_KP_8 = 328, + GLFW_KEY_KP_9 = 329, + GLFW_KEY_KP_DECIMAL = 330, + GLFW_KEY_KP_DIVIDE = 331, + GLFW_KEY_KP_MULTIPLY = 332, + GLFW_KEY_KP_SUBTRACT = 333, + GLFW_KEY_KP_ADD = 334, + GLFW_KEY_KP_ENTER = 335, + GLFW_KEY_KP_EQUAL = 336, + GLFW_KEY_LEFT_SHIFT = 340, + GLFW_KEY_LEFT_CONTROL = 341, + GLFW_KEY_LEFT_ALT = 342, + GLFW_KEY_LEFT_SUPER = 343, + GLFW_KEY_RIGHT_SHIFT = 344, + GLFW_KEY_RIGHT_CONTROL = 345, + GLFW_KEY_RIGHT_ALT = 346, + GLFW_KEY_RIGHT_SUPER = 347, + GLFW_KEY_MENU = 348, + GLFW_KEY_LAST = GLFW_KEY_MENU; + + /** If this bit is set one or more Shift keys were held down. */ + public static final int GLFW_MOD_SHIFT = 0x1; + + /** If this bit is set one or more Control keys were held down. */ + public static final int GLFW_MOD_CONTROL = 0x2; + + /** If this bit is set one or more Alt keys were held down. */ + public static final int GLFW_MOD_ALT = 0x4; + + /** If this bit is set one or more Super keys were held down. */ + public static final int GLFW_MOD_SUPER = 0x8; + + /** If this bit is set the Caps Lock key is enabled and the {@link #GLFW_LOCK_KEY_MODS LOCK_KEY_MODS} input mode is set. */ + public static final int GLFW_MOD_CAPS_LOCK = 0x10; + + /** If this bit is set the Num Lock key is enabled and the {@link #GLFW_LOCK_KEY_MODS LOCK_KEY_MODS} input mode is set. */ + public static final int GLFW_MOD_NUM_LOCK = 0x20; + + + /** Mouse buttons. See
mouse button input for how these are used. */ + public static final int + GLFW_MOUSE_BUTTON_1 = 0, + GLFW_MOUSE_BUTTON_2 = 1, + GLFW_MOUSE_BUTTON_3 = 2, + GLFW_MOUSE_BUTTON_4 = 3, + GLFW_MOUSE_BUTTON_5 = 4, + GLFW_MOUSE_BUTTON_6 = 5, + GLFW_MOUSE_BUTTON_7 = 6, + GLFW_MOUSE_BUTTON_8 = 7, + GLFW_MOUSE_BUTTON_LAST = GLFW_MOUSE_BUTTON_8, + GLFW_MOUSE_BUTTON_LEFT = GLFW_MOUSE_BUTTON_1, + GLFW_MOUSE_BUTTON_RIGHT = GLFW_MOUSE_BUTTON_2, + GLFW_MOUSE_BUTTON_MIDDLE = GLFW_MOUSE_BUTTON_3; + + /** Joysticks. See joystick input for how these are used. */ + public static final int + GLFW_JOYSTICK_1 = 0, + GLFW_JOYSTICK_2 = 1, + GLFW_JOYSTICK_3 = 2, + GLFW_JOYSTICK_4 = 3, + GLFW_JOYSTICK_5 = 4, + GLFW_JOYSTICK_6 = 5, + GLFW_JOYSTICK_7 = 6, + GLFW_JOYSTICK_8 = 7, + GLFW_JOYSTICK_9 = 8, + GLFW_JOYSTICK_10 = 9, + GLFW_JOYSTICK_11 = 10, + GLFW_JOYSTICK_12 = 11, + GLFW_JOYSTICK_13 = 12, + GLFW_JOYSTICK_14 = 13, + GLFW_JOYSTICK_15 = 14, + GLFW_JOYSTICK_16 = 15, + GLFW_JOYSTICK_LAST = GLFW_JOYSTICK_16; + + /** Gamepad buttons. See gamepad for how these are used. */ + public static final int + GLFW_GAMEPAD_BUTTON_A = 0, + GLFW_GAMEPAD_BUTTON_B = 1, + GLFW_GAMEPAD_BUTTON_X = 2, + GLFW_GAMEPAD_BUTTON_Y = 3, + GLFW_GAMEPAD_BUTTON_LEFT_BUMPER = 4, + GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER = 5, + GLFW_GAMEPAD_BUTTON_BACK = 6, + GLFW_GAMEPAD_BUTTON_START = 7, + GLFW_GAMEPAD_BUTTON_GUIDE = 8, + GLFW_GAMEPAD_BUTTON_LEFT_THUMB = 9, + GLFW_GAMEPAD_BUTTON_RIGHT_THUMB = 10, + GLFW_GAMEPAD_BUTTON_DPAD_UP = 11, + GLFW_GAMEPAD_BUTTON_DPAD_RIGHT = 12, + GLFW_GAMEPAD_BUTTON_DPAD_DOWN = 13, + GLFW_GAMEPAD_BUTTON_DPAD_LEFT = 14, + GLFW_GAMEPAD_BUTTON_LAST = GLFW_GAMEPAD_BUTTON_DPAD_LEFT, + GLFW_GAMEPAD_BUTTON_CROSS = GLFW_GAMEPAD_BUTTON_A, + GLFW_GAMEPAD_BUTTON_CIRCLE = GLFW_GAMEPAD_BUTTON_B, + GLFW_GAMEPAD_BUTTON_SQUARE = GLFW_GAMEPAD_BUTTON_X, + GLFW_GAMEPAD_BUTTON_TRIANGLE = GLFW_GAMEPAD_BUTTON_Y; + + /** Gamepad axes. See gamepad for how these are used. */ + public static final int + GLFW_GAMEPAD_AXIS_LEFT_X = 0, + GLFW_GAMEPAD_AXIS_LEFT_Y = 1, + GLFW_GAMEPAD_AXIS_RIGHT_X = 2, + GLFW_GAMEPAD_AXIS_RIGHT_Y = 3, + GLFW_GAMEPAD_AXIS_LEFT_TRIGGER = 4, + GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER = 5, + GLFW_GAMEPAD_AXIS_LAST = GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER; + + public static final int + GLFW_NO_ERROR = 0, + GLFW_NOT_INITIALIZED = 0x10001, + GLFW_NO_CURRENT_CONTEXT = 0x10002, + GLFW_INVALID_ENUM = 0x10003, + GLFW_INVALID_VALUE = 0x10004, + GLFW_OUT_OF_MEMORY = 0x10005, + GLFW_API_UNAVAILABLE = 0x10006, + GLFW_VERSION_UNAVAILABLE = 0x10007, + GLFW_PLATFORM_ERROR = 0x10008, + GLFW_FORMAT_UNAVAILABLE = 0x10009, + GLFW_NO_WINDOW_CONTEXT = 0x1000A, + GLFW_CURSOR_UNAVAILABLE = 0x1000B, + GLFW_FEATURE_UNAVAILABLE = 0x1000C, + GLFW_FEATURE_UNIMPLEMENTED = 0x1000D; + + public static final int + GLFW_FOCUSED = 0x20001, + GLFW_ICONIFIED = 0x20002, + GLFW_RESIZABLE = 0x20003, + GLFW_VISIBLE = 0x20004, + GLFW_DECORATED = 0x20005, + GLFW_AUTO_ICONIFY = 0x20006, + GLFW_FLOATING = 0x20007, + GLFW_MAXIMIZED = 0x20008, + GLFW_CENTER_CURSOR = 0x20009, + GLFW_TRANSPARENT_FRAMEBUFFER = 0x2000A, + GLFW_HOVERED = 0x2000B, + GLFW_FOCUS_ON_SHOW = 0x2000C; + + /** Input options. */ + public static final int + GLFW_CURSOR = 0x33001, + GLFW_STICKY_KEYS = 0x33002, + GLFW_STICKY_MOUSE_BUTTONS = 0x33003, + GLFW_LOCK_KEY_MODS = 0x33004, + GLFW_RAW_MOUSE_MOTION = 0x33005; + + /** Cursor state. */ + public static final int + GLFW_CURSOR_NORMAL = 0x34001, + GLFW_CURSOR_HIDDEN = 0x34002, + GLFW_CURSOR_DISABLED = 0x34003; + + /** The regular arrow cursor shape. */ + public static final int GLFW_ARROW_CURSOR = 0x36001; + + /** The text input I-beam cursor shape. */ + public static final int GLFW_IBEAM_CURSOR = 0x36002; + + /** The crosshair cursor shape. */ + public static final int GLFW_CROSSHAIR_CURSOR = 0x36003; + + /** The pointing hand cursor shape. */ + public static final int GLFW_POINTING_HAND_CURSOR = 0x36004; + + public static final int GLFW_RESIZE_EW_CURSOR = 0x36005; + public static final int GLFW_RESIZE_NS_CURSOR = 0x36006; + public static final int GLFW_RESIZE_NWSE_CURSOR = 0x36007; + public static final int GLFW_RESIZE_NESW_CURSOR = 0x36008; + + /** + * The omni-directional resize cursor/move shape. + * + *

This is usually either a combined horizontal and vertical double-headed arrow or a grabbing hand.

+ */ + public static final int GLFW_RESIZE_ALL_CURSOR = 0x36009; + + public static final int GLFW_NOT_ALLOWED_CURSOR = 0x3600A; + + /** Legacy name for compatibility. */ + public static final int GLFW_HRESIZE_CURSOR = GLFW_RESIZE_EW_CURSOR; + + /** Legacy name for compatibility. */ + public static final int GLFW_VRESIZE_CURSOR = GLFW_RESIZE_NS_CURSOR; + + /** Legacy name for compatibility. */ + public static final int GLFW_HAND_CURSOR = GLFW_POINTING_HAND_CURSOR; + + /** Monitor events. */ + public static final int + GLFW_CONNECTED = 0x40001, + GLFW_DISCONNECTED = 0x40002; + + /** Init hints. */ + public static final int + GLFW_JOYSTICK_HAT_BUTTONS = 0x50001, + GLFW_COCOA_CHDIR_RESOURCES = 0x51001, + GLFW_COCOA_MENUBAR = 0x51002; + + /** Don't care value. */ + public static final int GLFW_DONT_CARE = -1; + + /** PixelFormat hints. */ + public static final int + GLFW_RED_BITS = 0x21001, + GLFW_GREEN_BITS = 0x21002, + GLFW_BLUE_BITS = 0x21003, + GLFW_ALPHA_BITS = 0x21004, + GLFW_DEPTH_BITS = 0x21005, + GLFW_STENCIL_BITS = 0x21006, + GLFW_ACCUM_RED_BITS = 0x21007, + GLFW_ACCUM_GREEN_BITS = 0x21008, + GLFW_ACCUM_BLUE_BITS = 0x21009, + GLFW_ACCUM_ALPHA_BITS = 0x2100A, + GLFW_AUX_BUFFERS = 0x2100B, + GLFW_STEREO = 0x2100C, + GLFW_SAMPLES = 0x2100D, + GLFW_SRGB_CAPABLE = 0x2100E, + GLFW_REFRESH_RATE = 0x2100F, + GLFW_DOUBLEBUFFER = 0x21010; + + public static final int + GLFW_CLIENT_API = 0x22001, + GLFW_CONTEXT_VERSION_MAJOR = 0x22002, + GLFW_CONTEXT_VERSION_MINOR = 0x22003, + GLFW_CONTEXT_REVISION = 0x22004, + GLFW_CONTEXT_ROBUSTNESS = 0x22005, + GLFW_OPENGL_FORWARD_COMPAT = 0x22006, + GLFW_OPENGL_DEBUG_CONTEXT = 0x22007, + GLFW_OPENGL_PROFILE = 0x22008, + GLFW_CONTEXT_RELEASE_BEHAVIOR = 0x22009, + GLFW_CONTEXT_NO_ERROR = 0x2200A, + GLFW_CONTEXT_CREATION_API = 0x2200B, + GLFW_SCALE_TO_MONITOR = 0x2200C; + + /** Specifies whether to use full resolution framebuffers on Retina displays. This is ignored on other platforms. */ + public static final int GLFW_COCOA_RETINA_FRAMEBUFFER = 0x23001; + + /** + * Specifies the UTF-8 encoded name to use for autosaving the window frame, or if empty disables frame autosaving for the window. This is ignored on other + * platforms. This is set with {@link #glfwWindowHintString WindowHintString}. + */ + public static final int GLFW_COCOA_FRAME_NAME = 0x23002; + + /** + * Specifies whether to enable Automatic Graphics Switching, i.e. to allow the system to choose the integrated GPU for the OpenGL context and move it + * between GPUs if necessary or whether to force it to always run on the discrete GPU. This only affects systems with both integrated and discrete GPUs. + * This is ignored on other platforms. + */ + public static final int GLFW_COCOA_GRAPHICS_SWITCHING = 0x23003; + + /** The desired ASCII encoded class and instance parts of the ICCCM {@code WM_CLASS} window property. These are set with {@link #glfwWindowHintString WindowHintString}. */ + public static final int + GLFW_X11_CLASS_NAME = 0x24001, + GLFW_X11_INSTANCE_NAME = 0x24002; + + /** + * Specifies whether to allow access to the window menu via the Alt+Space and Alt-and-then-Space keyboard shortcuts. + * + *

This is ignored on other platforms.

+ */ + public static final int GLFW_WIN32_KEYBOARD_MENU = 0x25001; + + /** Values for the {@link #GLFW_CLIENT_API CLIENT_API} hint. */ + public static final int + GLFW_NO_API = 0, + GLFW_OPENGL_API = 0x30001, + GLFW_OPENGL_ES_API = 0x30002; + + /** Values for the {@link #GLFW_CONTEXT_ROBUSTNESS CONTEXT_ROBUSTNESS} hint. */ + public static final int + GLFW_NO_ROBUSTNESS = 0, + GLFW_NO_RESET_NOTIFICATION = 0x31001, + GLFW_LOSE_CONTEXT_ON_RESET = 0x31002; + + /** Values for the {@link #GLFW_OPENGL_PROFILE OPENGL_PROFILE} hint. */ + public static final int + GLFW_OPENGL_ANY_PROFILE = 0, + GLFW_OPENGL_CORE_PROFILE = 0x32001, + GLFW_OPENGL_COMPAT_PROFILE = 0x32002; + + /** Values for the {@link #GLFW_CONTEXT_RELEASE_BEHAVIOR CONTEXT_RELEASE_BEHAVIOR} hint. */ + public static final int + GLFW_ANY_RELEASE_BEHAVIOR = 0, + GLFW_RELEASE_BEHAVIOR_FLUSH = 0x35001, + GLFW_RELEASE_BEHAVIOR_NONE = 0x35002; + + /** Values for the {@link #GLFW_CONTEXT_CREATION_API CONTEXT_CREATION_API} hint. */ + public static final int + GLFW_NATIVE_CONTEXT_API = 0x36001, + GLFW_EGL_CONTEXT_API = 0x36002, + GLFW_OSMESA_CONTEXT_API = 0x36003; + + // GLFW Callbacks + /* volatile */ public static GLFWCharCallback mGLFWCharCallback; + /* volatile */ public static GLFWCharModsCallback mGLFWCharModsCallback; + /* volatile */ public static GLFWCursorEnterCallback mGLFWCursorEnterCallback; + /* volatile */ public static GLFWCursorPosCallback mGLFWCursorPosCallback; + /* volatile */ public static GLFWDropCallback mGLFWDropCallback; + /* volatile */ public static GLFWErrorCallback mGLFWErrorCallback; + /* volatile */ public static GLFWFramebufferSizeCallback mGLFWFramebufferSizeCallback; + /* volatile */ public static GLFWJoystickCallback mGLFWJoystickCallback; + /* volatile */ public static GLFWKeyCallback mGLFWKeyCallback; + /* volatile */ public static GLFWMonitorCallback mGLFWMonitorCallback; + /* volatile */ public static GLFWMouseButtonCallback mGLFWMouseButtonCallback; + /* volatile */ public static GLFWScrollCallback mGLFWScrollCallback; + /* volatile */ public static GLFWWindowCloseCallback mGLFWWindowCloseCallback; + /* volatile */ public static GLFWWindowContentScaleCallback mGLFWWindowContentScaleCallback; + /* volatile */ public static GLFWWindowFocusCallback mGLFWWindowFocusCallback; + /* volatile */ public static GLFWWindowIconifyCallback mGLFWWindowIconifyCallback; + /* volatile */ public static GLFWWindowMaximizeCallback mGLFWWindowMaximizeCallback; + /* volatile */ public static GLFWWindowPosCallback mGLFWWindowPosCallback; + /* volatile */ public static GLFWWindowRefreshCallback mGLFWWindowRefreshCallback; + /* volatile */ public static GLFWWindowSizeCallback mGLFWWindowSizeCallback; + + volatile public static int mGLFWWindowWidth, mGLFWWindowHeight; + volatile public static double mGLFWCursorX, mGLFWCursorY, mGLFWCursorLastX, mGLFWCursorLastY; + + private static GLFWGammaRamp mGLFWGammaRamp; + private static Map mGLFWKeyCodes; + private static GLFWVidMode mGLFWVideoMode; + private static long mGLFWWindowMonitor; + + private static double mGLFWInitialTime; + + private static ArrayMap mGLFWWindowMap; + + public static boolean mGLFWIsGrabbing, mGLFWIsInputReady, mGLFWIsUseStackQueue = false; + + private static final String PROP_WINDOW_WIDTH = "glfwstub.windowWidth"; + private static final String PROP_WINDOW_HEIGHT= "glfwstub.windowHeight"; + + static { + String windowWidth = System.getProperty(PROP_WINDOW_WIDTH); + String windowHeight = System.getProperty(PROP_WINDOW_HEIGHT); + if (windowWidth == null || windowHeight == null) { + System.err.println("Warning: Property " + PROP_WINDOW_WIDTH + " or " + PROP_WINDOW_HEIGHT + " not set, defaulting to 1280 and 720"); + + mGLFWWindowWidth = 1280; + mGLFWWindowHeight = 720; + } else { + mGLFWWindowWidth = Integer.parseInt(windowWidth); + mGLFWWindowHeight = Integer.parseInt(windowHeight); + } + + // Minecraft triggers a glfwPollEvents() on splash screen, so update window size there. + CallbackBridge.receiveCallback(CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE, mGLFWWindowWidth, mGLFWWindowHeight, 0, 0); + CallbackBridge.receiveCallback(CallbackBridge.EVENT_TYPE_WINDOW_SIZE, mGLFWWindowWidth, mGLFWWindowHeight, 0, 0); + + try { + System.loadLibrary("pojavexec"); + } catch (UnsatisfiedLinkError e) { + e.printStackTrace(); + } + + mGLFWErrorCallback = GLFWErrorCallback.createPrint(); + mGLFWKeyCodes = new ArrayMap<>(); + + mGLFWWindowMap = new ArrayMap<>(); + + mGLFWVideoMode = new GLFWVidMode(ByteBuffer.allocateDirect(GLFWVidMode.SIZEOF)); + memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.WIDTH, mGLFWWindowWidth); + memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.HEIGHT, mGLFWWindowHeight); + memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.REDBITS, 8); + memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.GREENBITS, 8); + memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.BLUEBITS, 8); + memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.REFRESHRATE, 60); + + // A way to generate key code names + Field[] thisFieldArr = GLFW.class.getFields(); + try { + for (Field thisField : thisFieldArr) { + if (thisField.getName().startsWith("GLFW_KEY_")) { + mGLFWKeyCodes.put( + (int) thisField.get(null), + thisField.getName().substring(9, 10).toUpperCase() + + thisField.getName().substring(10).replace("_", " ").toLowerCase() + ); + } + } + } catch (IllegalAccessException e) { + // This will never happend since this is accessing itself + } + + /* + mGLFWMonitorCallback = new GLFWMonitorCallback(){ + + // Fake one!!! + @Override + public void free() {} + + @Override + public void callback(long args) { + // TODO: Implement this method + } + }; + */ + } + + private static native long nativeEglGetCurrentContext(); + private static native boolean nativeEglInit(); + public static native boolean nativeEglMakeCurrent(long window); + private static native boolean nativeEglTerminate(); + private static native boolean nativeEglSwapBuffers(); + private static native boolean nativeEglSwapInterval(int inverval); + + private static native long nglfwSetCharCallback(long window, long ptr); + private static native long nglfwSetCharModsCallback(long window, long ptr); + private static native long nglfwSetCursorEnterCallback(long window, long ptr); + private static native long nglfwSetCursorPosCallback(long window, long ptr); + private static native long nglfwSetFramebufferSizeCallback(long window, long ptr); + private static native long nglfwSetKeyCallback(long window, long ptr); + private static native long nglfwSetMouseButtonCallback(long window, long ptr); + private static native long nglfwSetScrollCallback(long window, long ptr); + private static native long nglfwSetWindowSizeCallback(long window, long ptr); + // private static native void nglfwSetInputReady(); + private static native void nglfwSetShowingWindow(long window); + + /* + private static void priGlfwSetError(int error) { + mGLFW_currentError = error; + if (error != GLFW_NO_ERROR && mGLFWErrorCallback != null) { + mGLFWErrorCallback.invoke(error, 0); + } + } + + private static void priGlfwNoError() { + priGlfwSetError(GLFW_NO_ERROR); + } + */ + protected GLFW() { + throw new UnsupportedOperationException(); + } + + private static final SharedLibrary GLFW = new SharedLibrary() { + @java.lang.Override + public String getName() { + return "GLFW"; + } + + @Nullable + @java.lang.Override + public String getPath() { + return null; + } + + @java.lang.Override + public long getFunctionAddress(ByteBuffer functionName) { + return 1; + } + + @java.lang.Override + public void free() { + + } + + @java.lang.Override + public long address() { + return 1; + } + }; + // Library.loadNative(GLFW.class, "org.lwjgl.glfw", Configuration.GLFW_LIBRARY_NAME.get(Platform.mapLibraryNameBundled("glfw")), true); + + public static SharedLibrary getLibrary() { + return GLFW; + } + + public static GLFWWindowProperties internalGetWindow(long window) { + GLFWWindowProperties win = mGLFWWindowMap.get(window); + if (win == null) { + throw new IllegalArgumentException("No window pointer found: " + window); + } + return win; + } + +// Generated stub callback methods + public static GLFWCharCallback glfwSetCharCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcharfun") GLFWCharCallbackI cbfun) { + return mGLFWCharCallback = GLFWCharCallback.createSafe(nglfwSetCharCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWCharModsCallback glfwSetCharModsCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcharmodsfun") GLFWCharModsCallbackI cbfun) { + return mGLFWCharModsCallback = GLFWCharModsCallback.createSafe(nglfwSetCharModsCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWCursorEnterCallback glfwSetCursorEnterCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcursorenterfun") GLFWCursorEnterCallbackI cbfun) { + return mGLFWCursorEnterCallback = GLFWCursorEnterCallback.createSafe(nglfwSetCursorEnterCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWCursorPosCallback glfwSetCursorPosCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWcursorposfun") GLFWCursorPosCallbackI cbfun) { + return mGLFWCursorPosCallback = GLFWCursorPosCallback.createSafe(nglfwSetCursorPosCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWDropCallback glfwSetDropCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWdropfun") GLFWDropCallbackI cbfun) { + GLFWDropCallback lastCallback = mGLFWDropCallback; + if (cbfun == null) mGLFWDropCallback = null; + else mGLFWDropCallback = GLFWDropCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWErrorCallback glfwSetErrorCallback(@Nullable @NativeType("GLFWerrorfun") GLFWErrorCallbackI cbfun) { + GLFWErrorCallback lastCallback = mGLFWErrorCallback; + if (cbfun == null) mGLFWErrorCallback = null; + else mGLFWErrorCallback = GLFWErrorCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWFramebufferSizeCallback glfwSetFramebufferSizeCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWframebuffersizefun") GLFWFramebufferSizeCallbackI cbfun) { + return mGLFWFramebufferSizeCallback = GLFWFramebufferSizeCallback.createSafe(nglfwSetFramebufferSizeCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWJoystickCallback glfwSetJoystickCallback(/* @NativeType("GLFWwindow *") long window, */ @Nullable @NativeType("GLFWjoystickfun") GLFWJoystickCallbackI cbfun) { + GLFWJoystickCallback lastCallback = mGLFWJoystickCallback; + if (cbfun == null) mGLFWJoystickCallback = null; + else mGLFWJoystickCallback = GLFWJoystickCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWKeyCallback glfwSetKeyCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWkeyfun") GLFWKeyCallbackI cbfun) { + return mGLFWKeyCallback = GLFWKeyCallback.createSafe(nglfwSetKeyCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWMonitorCallback glfwSetMonitorCallback(@Nullable @NativeType("GLFWmonitorfun") GLFWMonitorCallbackI cbfun) { + GLFWMonitorCallback lastCallback = mGLFWMonitorCallback; + if (cbfun == null) mGLFWMonitorCallback = null; + else mGLFWMonitorCallback = GLFWMonitorCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWMouseButtonCallback glfwSetMouseButtonCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWmousebuttonfun") GLFWMouseButtonCallbackI cbfun) { + return mGLFWMouseButtonCallback = GLFWMouseButtonCallback.createSafe(nglfwSetMouseButtonCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWScrollCallback glfwSetScrollCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWscrollfun") GLFWScrollCallbackI cbfun) { + return mGLFWScrollCallback = GLFWScrollCallback.createSafe(nglfwSetScrollCallback(window, memAddressSafe(cbfun))); + } + + public static GLFWWindowCloseCallback glfwSetWindowCloseCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowclosefun") GLFWWindowCloseCallbackI cbfun) { + GLFWWindowCloseCallback lastCallback = mGLFWWindowCloseCallback; + if (cbfun == null) mGLFWWindowCloseCallback = null; + else mGLFWWindowCloseCallback = GLFWWindowCloseCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWWindowContentScaleCallback glfwSetWindowContentScaleCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowcontentscalefun") GLFWWindowContentScaleCallbackI cbfun) { + GLFWWindowContentScaleCallback lastCallback = mGLFWWindowContentScaleCallback; + if (cbfun == null) mGLFWWindowContentScaleCallback = null; + else mGLFWWindowContentScaleCallback = GLFWWindowContentScaleCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWWindowFocusCallback glfwSetWindowFocusCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowfocusfun") GLFWWindowFocusCallbackI cbfun) { + GLFWWindowFocusCallback lastCallback = mGLFWWindowFocusCallback; + if (cbfun == null) mGLFWWindowFocusCallback = null; + else mGLFWWindowFocusCallback = GLFWWindowFocusCallback.create(cbfun); + return lastCallback; + } + + public static GLFWWindowIconifyCallback glfwSetWindowIconifyCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowiconifyfun") GLFWWindowIconifyCallbackI cbfun) { + GLFWWindowIconifyCallback lastCallback = mGLFWWindowIconifyCallback; + if (cbfun == null) mGLFWWindowIconifyCallback = null; + else mGLFWWindowIconifyCallback = GLFWWindowIconifyCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWWindowMaximizeCallback glfwSetWindowMaximizeCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowmaximizefun") GLFWWindowMaximizeCallbackI cbfun) { + GLFWWindowMaximizeCallback lastCallback = mGLFWWindowMaximizeCallback; + if (cbfun == null) mGLFWWindowMaximizeCallback = null; + else mGLFWWindowMaximizeCallback = GLFWWindowMaximizeCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWWindowPosCallback glfwSetWindowPosCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowposfun") GLFWWindowPosCallbackI cbfun) { + GLFWWindowPosCallback lastCallback = mGLFWWindowPosCallback; + if (cbfun == null) mGLFWWindowPosCallback = null; + else mGLFWWindowPosCallback = GLFWWindowPosCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWWindowRefreshCallback glfwSetWindowRefreshCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowrefreshfun") GLFWWindowRefreshCallbackI cbfun) { + GLFWWindowRefreshCallback lastCallback = mGLFWWindowRefreshCallback; + if (cbfun == null) mGLFWWindowRefreshCallback = null; + else mGLFWWindowRefreshCallback = GLFWWindowRefreshCallback.create(cbfun); + + return lastCallback; + } + + public static GLFWWindowSizeCallback glfwSetWindowSizeCallback(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWwindowsizefun") GLFWWindowSizeCallbackI cbfun) { + return mGLFWWindowSizeCallback = GLFWWindowSizeCallback.createSafe(nglfwSetWindowSizeCallback(window, memAddressSafe(cbfun))); + } + + public static boolean glfwInit() { + mGLFWInitialTime = (double) System.nanoTime(); + return nativeEglInit(); + } + + public static void glfwTerminate() { + mGLFWIsInputReady = false; + CallbackBridge.nativeSetInputReady(false); + + nativeEglTerminate(); + } + + public static void glfwInitHint(int hint, int value) { } + + @NativeType("GLFWwindow *") + public static long glfwGetCurrentContext() { + // Stub prevent NULL check + return nativeEglGetCurrentContext(); + } + + public static void glfwGetFramebufferSize(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("int *") IntBuffer width, @Nullable @NativeType("int *") IntBuffer height) { + if (CHECKS) { + checkSafe(width, 1); + checkSafe(height, 1); + } + width.put(internalGetWindow(window).width); + height.put(internalGetWindow(window).height); + } + + public static void glfwGetFramebufferSize(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("int *") int[] width, @Nullable @NativeType("int *") int[] height) { + if (CHECKS) { + // check(window); + checkSafe(width, 1); + checkSafe(height, 1); + } + + width[0] = internalGetWindow(window).width; + height[0] = internalGetWindow(window).height; + } + + @Nullable + @NativeType("GLFWmonitor **") + public static PointerBuffer glfwGetMonitors() { + PointerBuffer pBuffer = PointerBuffer.allocateDirect(1); + pBuffer.put(glfwGetPrimaryMonitor()); + return pBuffer; + } + + public static long glfwGetPrimaryMonitor() { + // Prevent NULL check + return 1L; + } + + public static void glfwGetMonitorPos(@NativeType("GLFWmonitor *") long monitor, @Nullable @NativeType("int *") IntBuffer xpos, @Nullable @NativeType("int *") IntBuffer ypos) { + if (CHECKS) { + checkSafe(xpos, 1); + checkSafe(ypos, 1); + } + + xpos.put(0); + ypos.put(0); + } + + public static void glfwGetMonitorWorkarea(@NativeType("GLFWmonitor *") long monitor, @Nullable @NativeType("int *") IntBuffer xpos, @Nullable @NativeType("int *") IntBuffer ypos, @Nullable @NativeType("int *") IntBuffer width, @Nullable @NativeType("int *") IntBuffer height) { + if (CHECKS) { + checkSafe(xpos, 1); + checkSafe(ypos, 1); + checkSafe(width, 1); + checkSafe(height, 1); + } + + xpos.put(0); + ypos.put(0); + width.put(mGLFWWindowWidth); + height.put(mGLFWWindowHeight); + } + + public static void glfwGetMonitorPos(@NativeType("GLFWmonitor *") long monitor, @Nullable @NativeType("int *") int[] xpos, @Nullable @NativeType("int *") int[] ypos) { + if (CHECKS) { + // check(monitor); + checkSafe(xpos, 1); + checkSafe(ypos, 1); + } + + xpos[0] = 0; + ypos[0] = 0; + } + + /** Array version of: {@link #glfwGetMonitorWorkarea GetMonitorWorkarea} */ + public static void glfwGetMonitorWorkarea(@NativeType("GLFWmonitor *") long monitor, @Nullable @NativeType("int *") int[] xpos, @Nullable @NativeType("int *") int[] ypos, @Nullable @NativeType("int *") int[] width, @Nullable @NativeType("int *") int[] height) { + if (CHECKS) { + // check(monitor); + checkSafe(xpos, 1); + checkSafe(ypos, 1); + checkSafe(width, 1); + checkSafe(height, 1); + } + + xpos[0] = 0; + ypos[0] = 0; + width[0] = mGLFWWindowWidth; + height[0] = mGLFWWindowHeight; + } + + @NativeType("GLFWmonitor *") + public static long glfwGetWindowMonitor(@NativeType("GLFWwindow *") long window) { + return mGLFWWindowMonitor; + } + + public static void glfwSetWindowMonitor(@NativeType("GLFWwindow *") long window, @NativeType("GLFWmonitor *") long monitor, int xpos, int ypos, int width, int height, int refreshRate) { + // weird calculation to fake pointer + mGLFWWindowMonitor = window * monitor; + } + + public static int glfwGetWindowAttrib(@NativeType("GLFWwindow *") long window, int attrib) { + return internalGetWindow(window).windowAttribs.get(attrib); + } + + public static void glfwSetWindowAttrib(@NativeType("GLFWwindow *") long window, int attrib, int value) { + internalGetWindow(window).windowAttribs.put(attrib, value); + } + + public static void glfwGetVersion(IntBuffer major, IntBuffer minor, IntBuffer rev) { + if (CHECKS) { + checkSafe(major, 1); + checkSafe(minor, 1); + checkSafe(rev, 1); + } + + major.put(GLFW_VERSION_MAJOR); + minor.put(GLFW_VERSION_MINOR); + rev.put(GLFW_VERSION_REVISION); + } + + public static String glfwGetVersionString() { + return GLFW_VERSION_MAJOR + "." + GLFW_VERSION_MINOR + "." + GLFW_VERSION_REVISION; + } + + public static int glfwGetError(@Nullable PointerBuffer description) { + return GLFW_NO_ERROR; + } + + @Nullable + @NativeType("GLFWvidmode const *") + public static GLFWVidMode.Buffer glfwGetVideoModes(@NativeType("GLFWmonitor *") long monitor) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + IntBuffer count = stack.callocInt(1); + try { + // long __result = nglfwGetVideoModes(monitor, memAddress(count)); + long __result = memAddress(stack.callocLong(1)); + return GLFWVidMode.createSafe(__result, 1); + } finally { + stack.setPointer(stackPointer); + } + } + + @Nullable + public static GLFWVidMode glfwGetVideoMode(long monitor) { + return mGLFWVideoMode; + } + + public static GLFWGammaRamp glfwGetGammaRamp(@NativeType("GLFWmonitor *") long monitor) { + return mGLFWGammaRamp; + } + public static void glfwSetGammaRamp(@NativeType("GLFWmonitor *") long monitor, @NativeType("const GLFWgammaramp *") GLFWGammaRamp ramp) { + mGLFWGammaRamp = ramp; + } + + public static void glfwMakeContextCurrent(long window) { + long currentGLThreadId = Thread.currentThread().getId(); + // Long.parseLong(System.getProperty("glfwstub.internal.glthreadid", "-1")); + System.out.println("GLFW: glfwMakeContextCurrent() calling from thread ID " + currentGLThreadId + ", name: " + Thread.currentThread().getName()); + if (currentGLThreadId != -1 && currentGLThreadId != Thread.currentThread().getId()) { + System.out.println("GLFW: Current context is set, creating shared context"); + if (!nativeEglMakeCurrent(window)) { + throw new RuntimeException("eglMakeCurrent() failed, check log file for more details"); + } + } else { + System.out.println("GLFW: glfwMakeContextCurrent() request is skipped"); + } + } + + public static void glfwSwapBuffers(long window) { + nativeEglSwapBuffers(); + } + + public static void glfwSwapInterval(int interval) { + nativeEglSwapInterval(interval); + } + + // private static double mTime = 0d; + public static double glfwGetTime() { + // Boardwalk: just use system timer + // System.out.println("glfwGetTime"); + return (System.nanoTime() - mGLFWInitialTime) / 1.e9; + } + + public static void glfwSetTime(double time) { + mGLFWInitialTime = System.nanoTime() - (long) time; + } + + public static long glfwGetTimerValue() { + return System.currentTimeMillis(); + } + + public static long glfwGetTimerFrequency() { + // FIXME set correct value!! + return 60; + } + + // GLFW Window functions + public static long glfwCreateWindow(int width, int height, CharSequence title, long monitor, long share) { + EventLoop.OffScreen.check(); + + // A good idea to fake pointer + long ptr = System.currentTimeMillis(); + + GLFWWindowProperties win = new GLFWWindowProperties(); + // win.width = width; + // win.height = height; + + win.width = mGLFWWindowWidth; + win.height = mGLFWWindowHeight; + + win.title = title; + + mGLFWWindowMap.put(ptr, win); + + // Prevent NULL check + return ptr; + } + + public static void glfwDestroyWindow(long window) { + // Check window exists + internalGetWindow(window); + mGLFWWindowMap.remove(window); + nglfwSetShowingWindow(mGLFWWindowMap.size() == 0 ? 0 : mGLFWWindowMap.keyAt(mGLFWWindowMap.size() - 1)); + } + + public static void glfwDefaultWindowHints() {} + + public static void glfwGetWindowSize(long window, IntBuffer width, IntBuffer height) { + if (width != null) width.put(internalGetWindow(window).width); + if (height != null) height.put(internalGetWindow(window).height); + } + + public static void glfwSetWindowPos(long window, int x, int y) { + internalGetWindow(window).x = x; + internalGetWindow(window).y = y; + } + + public static void glfwSetWindowSize(long window, int width, int height) { + internalGetWindow(window).width = width; + internalGetWindow(window).height = height; + + System.out.println("GLFW: Set size for window " + window + ", width=" + width + ", height=" + height); + } + + public static void glfwShowWindow(long window) { + nglfwSetShowingWindow(window); + } + public static void glfwWindowHint(int hint, int value) {} + public static void glfwWindowHintString(int hint, @NativeType("const char *") ByteBuffer value) {} + public static void glfwWindowHintString(int hint, @NativeType("const char *") CharSequence value) {} + + public static boolean glfwWindowShouldClose(long window) { + return internalGetWindow(window).shouldClose; + } + + public static void glfwSetWindowShouldClose(long window, boolean close) { + internalGetWindow(window).shouldClose = close; + } + + + public static void glfwSetWindowTitle(@NativeType("GLFWwindow *") long window, @NativeType("char const *") ByteBuffer title) { + + } + public static void glfwSetWindowTitle(@NativeType("GLFWwindow *") long window, @NativeType("char const *") CharSequence title) { + internalGetWindow(window).title = title; + } + + public static void glfwSetWindowIcon(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("GLFWimage const *") GLFWImage.Buffer images) {} + + public static void glfwPollEvents() { + if (!mGLFWIsInputReady) { + mGLFWIsInputReady = true; + mGLFWIsUseStackQueue = CallbackBridge.nativeSetInputReady(true); + } + + if (!CallbackBridge.PENDING_EVENT_READY) { + CallbackBridge.PENDING_EVENT_READY = true; + // nglfwSetInputReady(); + } + + // Indirect event + while (CallbackBridge.PENDING_EVENT_LIST.size() > 0) { + Integer[] dataArr = CallbackBridge.PENDING_EVENT_LIST.remove(0); + + if (dataArr == null) { // It should not be null, but still should be catched + // System.out.println("GLFW: popped callback is null, skipping"); + continue; + } + + for (Long ptr : mGLFWWindowMap.keySet()) { + switch (dataArr[0]) { + case CallbackBridge.EVENT_TYPE_CHAR: + if (mGLFWCharCallback != null) { + mGLFWCharCallback.invoke(ptr, dataArr[1]); + } + break; + case CallbackBridge.EVENT_TYPE_CHAR_MODS: + if (mGLFWCharModsCallback != null) { + mGLFWCharModsCallback.invoke(ptr, dataArr[1], dataArr[2]); + } + break; + case CallbackBridge.EVENT_TYPE_CURSOR_ENTER: + if (mGLFWCursorEnterCallback != null) { + mGLFWCursorEnterCallback.invoke(ptr, dataArr[1] == 1); + } + break; + case CallbackBridge.EVENT_TYPE_KEY: + if (mGLFWKeyCallback != null) { + mGLFWKeyCallback.invoke(ptr, dataArr[1], dataArr[2], dataArr[3], dataArr[4]); + } + break; + case CallbackBridge.EVENT_TYPE_MOUSE_BUTTON: + if (mGLFWMouseButtonCallback != null) { + mGLFWMouseButtonCallback.invoke(ptr, dataArr[1], dataArr[2], dataArr[3]); + } + break; + case CallbackBridge.EVENT_TYPE_SCROLL: + if (mGLFWScrollCallback != null) { + mGLFWScrollCallback.invoke(ptr, dataArr[1], dataArr[2]); + } + break; + case CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE: + case CallbackBridge.EVENT_TYPE_WINDOW_SIZE: + mGLFWWindowWidth = dataArr[1]; + mGLFWWindowHeight = dataArr[2]; + glfwSetWindowSize(ptr, mGLFWWindowWidth, mGLFWWindowHeight); + if (dataArr[0] == CallbackBridge.EVENT_TYPE_FRAMEBUFFER_SIZE && mGLFWFramebufferSizeCallback != null) { + mGLFWFramebufferSizeCallback.invoke(ptr, mGLFWWindowWidth, mGLFWWindowHeight); + } else if (dataArr[0] == CallbackBridge.EVENT_TYPE_WINDOW_SIZE && mGLFWWindowSizeCallback != null) { + mGLFWWindowSizeCallback.invoke(ptr, mGLFWWindowWidth, mGLFWWindowHeight); + } + break; + default: + System.err.println("GLFWEvent: unknown callback type " + dataArr[0]); + break; + } + } + } + + if ((mGLFWCursorX != mGLFWCursorLastX || mGLFWCursorY != mGLFWCursorLastY) && mGLFWCursorPosCallback != null) { + mGLFWCursorLastX = mGLFWCursorX; + mGLFWCursorLastY = mGLFWCursorY; + for (Long ptr : mGLFWWindowMap.keySet()) { + mGLFWCursorPosCallback.invoke(ptr, mGLFWCursorX, mGLFWCursorY); + } + // System.out.println("CursorPos updated to x=" + mGLFWCursorX + ",y=" + mGLFWCursorY); + } + } + + public static void glfwWaitEvents() {} + + public static void glfwWaitEventsTimeout(double timeout) { + // Boardwalk: this isn't how you do a frame limiter, but oh well + // System.out.println("Frame limiter"); + /* + try { + Thread.sleep((long)(timeout * 1000)); + } catch (InterruptedException ie) { + } + */ + // System.out.println("Out of the frame limiter"); + + } + + public static void glfwPostEmptyEvent() {} + + public static int glfwGetInputMode(@NativeType("GLFWwindow *") long window, int mode) { + return internalGetWindow(window).inputModes.get(mode); + } + + public static void glfwSetInputMode(@NativeType("GLFWwindow *") long window, int mode, int value) { + if (mode == GLFW_CURSOR) { + switch (value) { + case GLFW_CURSOR_DISABLED: + CallbackBridge.sendGrabbing(true, (int) mGLFWCursorX, (int) mGLFWCursorY); + break; + default: CallbackBridge.sendGrabbing(false, (int) mGLFWCursorX, (int) mGLFWCursorY); + } + } + + internalGetWindow(window).inputModes.put(mode, value); + } + public static String glfwGetKeyName(int key, int scancode) { + // TODO keyname list from GLFW + return mGLFWKeyCodes.get(key); + } + + public static int glfwGetKeyScancode(int key) { + return 0; + } + + public static int glfwGetKey(@NativeType("GLFWwindow *") long window, int key) { + return 0; + } + + public static int glfwGetMouseButton(@NativeType("GLFWwindow *") long window, int button) { + return 0; + } + + public static void glfwGetCursorPos(@NativeType("GLFWwindow *") long window, @Nullable @NativeType("double *") DoubleBuffer xpos, @Nullable @NativeType("double *") DoubleBuffer ypos) { + if (CHECKS) { + checkSafe(xpos, 1); + checkSafe(ypos, 1); + } + + xpos.put(mGLFWCursorX); + ypos.put(mGLFWCursorY); + } + + public static void glfwSetCursorPos(@NativeType("GLFWwindow *") long window, double xpos, double ypos) { + mGLFWCursorX = mGLFWCursorLastX = xpos; + mGLFWCursorY = mGLFWCursorLastY = ypos; + + CallbackBridge.sendGrabbing(mGLFWIsGrabbing, (int) xpos, (int) ypos); + } + + public static long glfwCreateCursor(@NativeType("const GLFWimage *") GLFWImage image, int xhot, int yhot) { + return 4L; + } + public static long glfwCreateStandardCursor(int shape) { + return 4L; + } + public static void glfwDestroyCursor(@NativeType("GLFWcursor *") long cursor) {} + public static void glfwSetCursor(@NativeType("GLFWwindow *") long window, @NativeType("GLFWcursor *") long cursor) {} + + public static boolean glfwRawMouseMotionSupported() { + // Should be not supported? + return false; + } + + public static void glfwSetClipboardString(@NativeType("GLFWwindow *") long window, @NativeType("char const *") ByteBuffer string) { + glfwSetClipboardString(window, memUTF8Safe(string)); + } + + public static void glfwSetClipboardString(@NativeType("GLFWwindow *") long window, @NativeType("char const *") CharSequence string) { + CallbackBridge.nativeClipboard(CallbackBridge.CLIPBOARD_COPY, string.toString()); + } + + public static String glfwGetClipboardString(@NativeType("GLFWwindow *") long window) { + return CallbackBridge.nativeClipboard(CallbackBridge.CLIPBOARD_PASTE, null); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallback.java new file mode 100644 index 000000000..a349d2253 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetCharCallback SetCharCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     unsigned int codepoint
+ * )
+ * + * @since version 2.4 + */ +public abstract class GLFWCharCallback extends Callback implements GLFWCharCallbackI { + + /** + * Creates a {@code GLFWCharCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWCharCallback} + */ + public static GLFWCharCallback create(long functionPointer) { + GLFWCharCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWCharCallback + ? (GLFWCharCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWCharCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWCharCallback} instance that delegates to the specified {@code GLFWCharCallbackI} instance. */ + public static GLFWCharCallback create(GLFWCharCallbackI instance) { + return instance instanceof GLFWCharCallback + ? (GLFWCharCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWCharCallback() { + super(SIGNATURE); + } + + GLFWCharCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetCharCallback SetCharCallback}. */ + public GLFWCharCallback set(long window) { + glfwSetCharCallback(window, this); + return this; + } + + private static final class Container extends GLFWCharCallback { + + private final GLFWCharCallbackI delegate; + + Container(long functionPointer, GLFWCharCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int codepoint) { + delegate.invoke(window, codepoint); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallbackI.java new file mode 100644 index 000000000..338b05c5f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetCharCallback SetCharCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     unsigned int codepoint
+ * )
+ * + * @since version 2.4 + */ +@FunctionalInterface +@NativeType("GLFWcharfun") +public interface GLFWCharCallbackI extends CallbackI.V { + + String SIGNATURE = "(pi)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when a Unicode character is input. + * + * @param window the window that received the event + * @param codepoint the Unicode code point of the character + */ + void invoke(@NativeType("GLFWwindow *") long window, @NativeType("unsigned int") int codepoint); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallback.java new file mode 100644 index 000000000..c9edc08fa --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallback.java @@ -0,0 +1,89 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetCharModsCallback SetCharModsCallback} method. + * + *

Deprecared: scheduled for removal in version 4.0.

+ * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     unsigned int codepoint,
+ *     int mods
+ * )
+ * + * @since version 3.1 + */ +public abstract class GLFWCharModsCallback extends Callback implements GLFWCharModsCallbackI { + + /** + * Creates a {@code GLFWCharModsCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWCharModsCallback} + */ + public static GLFWCharModsCallback create(long functionPointer) { + GLFWCharModsCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWCharModsCallback + ? (GLFWCharModsCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWCharModsCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWCharModsCallback} instance that delegates to the specified {@code GLFWCharModsCallbackI} instance. */ + public static GLFWCharModsCallback create(GLFWCharModsCallbackI instance) { + return instance instanceof GLFWCharModsCallback + ? (GLFWCharModsCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWCharModsCallback() { + super(SIGNATURE); + } + + GLFWCharModsCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetCharModsCallback SetCharModsCallback}. */ + public GLFWCharModsCallback set(long window) { + glfwSetCharModsCallback(window, this); + return this; + } + + private static final class Container extends GLFWCharModsCallback { + + private final GLFWCharModsCallbackI delegate; + + Container(long functionPointer, GLFWCharModsCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int codepoint, int mods) { + delegate.invoke(window, codepoint, mods); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallbackI.java new file mode 100644 index 000000000..3008caad3 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCharModsCallbackI.java @@ -0,0 +1,55 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetCharModsCallback SetCharModsCallback} method. + * + *

Deprecared: scheduled for removal in version 4.0.

+ * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     unsigned int codepoint,
+ *     int mods
+ * )
+ * + * @since version 3.1 + */ +@FunctionalInterface +@NativeType("GLFWcharmodsfun") +public interface GLFWCharModsCallbackI extends CallbackI.V { + + String SIGNATURE = "(pii)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when a Unicode character is input regardless of what modifier keys are used. + * + * @param window the window that received the event + * @param codepoint the Unicode code point of the character + * @param mods bitfield describing which modifier keys were held down + */ + void invoke(@NativeType("GLFWwindow *") long window, @NativeType("unsigned int") int codepoint, int mods); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallback.java new file mode 100644 index 000000000..bd02ce774 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetCursorEnterCallback SetCursorEnterCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int entered
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWCursorEnterCallback extends Callback implements GLFWCursorEnterCallbackI { + + /** + * Creates a {@code GLFWCursorEnterCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWCursorEnterCallback} + */ + public static GLFWCursorEnterCallback create(long functionPointer) { + GLFWCursorEnterCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWCursorEnterCallback + ? (GLFWCursorEnterCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWCursorEnterCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWCursorEnterCallback} instance that delegates to the specified {@code GLFWCursorEnterCallbackI} instance. */ + public static GLFWCursorEnterCallback create(GLFWCursorEnterCallbackI instance) { + return instance instanceof GLFWCursorEnterCallback + ? (GLFWCursorEnterCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWCursorEnterCallback() { + super(SIGNATURE); + } + + GLFWCursorEnterCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetCursorEnterCallback SetCursorEnterCallback}. */ + public GLFWCursorEnterCallback set(long window) { + glfwSetCursorEnterCallback(window, this); + return this; + } + + private static final class Container extends GLFWCursorEnterCallback { + + private final GLFWCursorEnterCallbackI delegate; + + Container(long functionPointer, GLFWCursorEnterCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, boolean entered) { + delegate.invoke(window, entered); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallbackI.java new file mode 100644 index 000000000..9be574b09 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorEnterCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetCursorEnterCallback SetCursorEnterCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int entered
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWcursorenterfun") +public interface GLFWCursorEnterCallbackI extends CallbackI.V { + + String SIGNATURE = "(pi)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args) != 0 + ); + } + + /** + * Will be called when the cursor enters or leaves the client area of the window. + * + * @param window the window that received the event + * @param entered {@link GLFW#GLFW_TRUE TRUE} if the cursor entered the window's content area, or {@link GLFW#GLFW_FALSE FALSE} if it left it + */ + void invoke(@NativeType("GLFWwindow *") long window, @NativeType("int") boolean entered); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallback.java new file mode 100644 index 000000000..1a4fa68d9 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetCursorPosCallback SetCursorPosCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     double xpos,
+ *     double ypos
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWCursorPosCallback extends Callback implements GLFWCursorPosCallbackI { + + /** + * Creates a {@code GLFWCursorPosCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWCursorPosCallback} + */ + public static GLFWCursorPosCallback create(long functionPointer) { + GLFWCursorPosCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWCursorPosCallback + ? (GLFWCursorPosCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWCursorPosCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWCursorPosCallback} instance that delegates to the specified {@code GLFWCursorPosCallbackI} instance. */ + public static GLFWCursorPosCallback create(GLFWCursorPosCallbackI instance) { + return instance instanceof GLFWCursorPosCallback + ? (GLFWCursorPosCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWCursorPosCallback() { + super(SIGNATURE); + } + + GLFWCursorPosCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetCursorPosCallback SetCursorPosCallback}. */ + public GLFWCursorPosCallback set(long window) { + glfwSetCursorPosCallback(window, this); + return this; + } + + private static final class Container extends GLFWCursorPosCallback { + + private final GLFWCursorPosCallbackI delegate; + + Container(long functionPointer, GLFWCursorPosCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, double xpos, double ypos) { + delegate.invoke(window, xpos, ypos); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallbackI.java new file mode 100644 index 000000000..8e4f717c2 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWCursorPosCallbackI.java @@ -0,0 +1,56 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetCursorPosCallback SetCursorPosCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     double xpos,
+ *     double ypos
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWcursorposfun") +public interface GLFWCursorPosCallbackI extends CallbackI.V { + + String SIGNATURE = "(pdd)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgDouble(args), + dcbArgDouble(args) + ); + } + + /** + * Will be called when the cursor is moved. + * + *

The callback function receives the cursor position, measured in screen coordinates but relative to the top-left corner of the window client area. On + * platforms that provide it, the full sub-pixel cursor position is passed on.

+ * + * @param window the window that received the event + * @param xpos the new cursor x-coordinate, relative to the left edge of the content area + * @param ypos the new cursor y-coordinate, relative to the top edge of the content area + */ + void invoke(@NativeType("GLFWwindow *") long window, double xpos, double ypos); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallback.java new file mode 100644 index 000000000..eaf831c2d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallback.java @@ -0,0 +1,101 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetDropCallback SetDropCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int count,
+ *     char const **names
+ * )
+ * + * @since version 3.1 + */ +public abstract class GLFWDropCallback extends Callback implements GLFWDropCallbackI { + + /** + * Creates a {@code GLFWDropCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWDropCallback} + */ + public static GLFWDropCallback create(long functionPointer) { + GLFWDropCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWDropCallback + ? (GLFWDropCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWDropCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWDropCallback} instance that delegates to the specified {@code GLFWDropCallbackI} instance. */ + public static GLFWDropCallback create(GLFWDropCallbackI instance) { + return instance instanceof GLFWDropCallback + ? (GLFWDropCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWDropCallback() { + super(SIGNATURE); + } + + GLFWDropCallback(long functionPointer) { + super(functionPointer); + } + + /** + * Decodes the specified {@link GLFWDropCallback} arguments to a String. + * + *

This method may only be used inside a {@code GLFWDropCallback} invocation.

+ * + * @param names pointer to the array of UTF-8 encoded path names of the dropped files + * @param index the index to decode + * + * @return the name at the specified index as a String + */ + public static String getName(long names, int index) { + return memUTF8(memGetAddress(names + Pointer.POINTER_SIZE * index)); + } + + /** See {@link GLFW#glfwSetDropCallback SetDropCallback}. */ + public GLFWDropCallback set(long window) { + glfwSetDropCallback(window, this); + return this; + } + + private static final class Container extends GLFWDropCallback { + + private final GLFWDropCallbackI delegate; + + Container(long functionPointer, GLFWDropCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int count, long names) { + delegate.invoke(window, count, names); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallbackI.java new file mode 100644 index 000000000..7528629e1 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWDropCallbackI.java @@ -0,0 +1,53 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetDropCallback SetDropCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int count,
+ *     char const **names
+ * )
+ * + * @since version 3.1 + */ +@FunctionalInterface +@NativeType("GLFWdropfun") +public interface GLFWDropCallbackI extends CallbackI.V { + + String SIGNATURE = "(pip)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args), + dcbArgPointer(args) + ); + } + + /** + * Will be called when one or more dragged files are dropped on the window. + * + * @param window the window that received the event + * @param count the number of dropped files + * @param names pointer to the array of UTF-8 encoded path names of the dropped files + */ + void invoke(@NativeType("GLFWwindow *") long window, int count, @NativeType("char const **") long names); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallback.java new file mode 100644 index 000000000..1c52cca51 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallback.java @@ -0,0 +1,156 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import java.io.PrintStream; +import java.util.Map; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetErrorCallback SetErrorCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     int error,
+ *     char *description
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWErrorCallback extends Callback implements GLFWErrorCallbackI { + + /** + * Creates a {@code GLFWErrorCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWErrorCallback} + */ + public static GLFWErrorCallback create(long functionPointer) { + GLFWErrorCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWErrorCallback + ? (GLFWErrorCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWErrorCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWErrorCallback} instance that delegates to the specified {@code GLFWErrorCallbackI} instance. */ + public static GLFWErrorCallback create(GLFWErrorCallbackI instance) { + return instance instanceof GLFWErrorCallback + ? (GLFWErrorCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWErrorCallback() { + super(SIGNATURE); + } + + GLFWErrorCallback(long functionPointer) { + super(functionPointer); + } + + /** + * Converts the specified {@link GLFWErrorCallback} argument to a String. + * + *

This method may only be used inside a GLFWErrorCallback invocation.

+ * + * @param description pointer to the UTF-8 encoded description string + * + * @return the description as a String + */ + public static String getDescription(long description) { + try { + return memUTF8(description); + } catch (NullPointerException e) { + return "null (unknown " + Long.toHexString(description) + ")"; + } + } + + /** + * Returns a {@link GLFWErrorCallback} instance that prints the error to the {@link APIUtil#DEBUG_STREAM}. + * + * @return the GLFWerrorCallback + */ + public static GLFWErrorCallback createPrint() { + return createPrint(APIUtil.DEBUG_STREAM); + } + + /** + * Returns a {@link GLFWErrorCallback} instance that prints the error in the specified {@link PrintStream}. + * + * @param stream the PrintStream to use + * + * @return the GLFWerrorCallback + */ + public static GLFWErrorCallback createPrint(PrintStream stream) { + return new GLFWErrorCallback() { + private Map ERROR_CODES = APIUtil.apiClassTokens((field, value) -> 0x10000 < value && value < 0x20000, null, GLFW.class); + + @Override + public void invoke(int error, long description) { + String msg = getDescription(description); + + stream.printf("[LWJGL] %s error\n", ERROR_CODES.get(error)); + stream.println("\tDescription : " + msg); + stream.println("\tStacktrace :"); + StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + for ( int i = 4; i < stack.length; i++ ) { + stream.print("\t\t"); + stream.println(stack[i].toString()); + } + } + }; + } + + /** + * Returns a {@link GLFWErrorCallback} instance that throws an {@link IllegalStateException} when an error occurs. + * + * @return the GLFWerrorCallback + */ + public static GLFWErrorCallback createThrow() { + return new GLFWErrorCallback() { + @Override + public void invoke(int error, long description) { + throw new IllegalStateException(String.format("GLFW error [0x%X]: %s", error, getDescription(description))); + } + }; + } + + /** See {@link GLFW#glfwSetErrorCallback SetErrorCallback}. */ + public GLFWErrorCallback set() { + glfwSetErrorCallback(this); + return this; + } + + private static final class Container extends GLFWErrorCallback { + + private final GLFWErrorCallbackI delegate; + + Container(long functionPointer, GLFWErrorCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(int error, long description) { + delegate.invoke(error, description); + } + + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallbackI.java new file mode 100644 index 000000000..62841da17 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWErrorCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetErrorCallback SetErrorCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     int error,
+ *     char *description
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWerrorfun") +public interface GLFWErrorCallbackI extends CallbackI.V { + + String SIGNATURE = "(ip)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgInt(args), + dcbArgPointer(args) + ); + } + + /** + * Will be called with an error code and a human-readable description when a GLFW error occurs. + * + * @param error the error code + * @param description a pointer to a UTF-8 encoded string describing the error + */ + void invoke(int error, @NativeType("char *") long description); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallback.java new file mode 100644 index 000000000..2e66f76f2 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetFramebufferSizeCallback SetFramebufferSizeCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int width,
+ *     int height
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWFramebufferSizeCallback extends Callback implements GLFWFramebufferSizeCallbackI { + + /** + * Creates a {@code GLFWFramebufferSizeCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWFramebufferSizeCallback} + */ + public static GLFWFramebufferSizeCallback create(long functionPointer) { + GLFWFramebufferSizeCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWFramebufferSizeCallback + ? (GLFWFramebufferSizeCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWFramebufferSizeCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWFramebufferSizeCallback} instance that delegates to the specified {@code GLFWFramebufferSizeCallbackI} instance. */ + public static GLFWFramebufferSizeCallback create(GLFWFramebufferSizeCallbackI instance) { + return instance instanceof GLFWFramebufferSizeCallback + ? (GLFWFramebufferSizeCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWFramebufferSizeCallback() { + super(SIGNATURE); + } + + GLFWFramebufferSizeCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetFramebufferSizeCallback SetFramebufferSizeCallback}. */ + public GLFWFramebufferSizeCallback set(long window) { + glfwSetFramebufferSizeCallback(window, this); + return this; + } + + private static final class Container extends GLFWFramebufferSizeCallback { + + private final GLFWFramebufferSizeCallbackI delegate; + + Container(long functionPointer, GLFWFramebufferSizeCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int width, int height) { + delegate.invoke(window, width, height); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallbackI.java new file mode 100644 index 000000000..098e2b2c5 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWFramebufferSizeCallbackI.java @@ -0,0 +1,53 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetFramebufferSizeCallback SetFramebufferSizeCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int width,
+ *     int height
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWframebuffersizefun") +public interface GLFWFramebufferSizeCallbackI extends CallbackI.V { + + String SIGNATURE = "(pii)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when the framebuffer of the specified window is resized. + * + * @param window the window whose framebuffer was resized + * @param width the new width, in pixels, of the framebuffer + * @param height the new height, in pixels, of the framebuffer + */ + void invoke(@NativeType("GLFWwindow *") long window, int width, int height); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGamepadState.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGamepadState.java new file mode 100644 index 000000000..17792e416 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGamepadState.java @@ -0,0 +1,359 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.*; +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.MemoryUtil.*; +import static org.lwjgl.system.MemoryStack.*; + +/** + * Describes the input state of a gamepad. + * + *

Member documentation

+ * + *
    + *
  • {@code buttons[15]} – the states of each gamepad button, {@link GLFW#GLFW_PRESS PRESS} or {@link GLFW#GLFW_RELEASE RELEASE}
  • + *
  • {@code axes[6]} – the states of each gamepad axis, in the range -1.0 to 1.0 inclusive
  • + *
+ * + *

Layout

+ * + *

+ * struct GLFWgamepadstate {
+ *     unsigned char buttons[15];
+ *     float axes[6];
+ * }
+ * + * @since version 3.3 + */ +@NativeType("struct GLFWgamepadstate") +public class GLFWGamepadState extends Struct implements NativeResource { + + /** The struct size in bytes. */ + public static final int SIZEOF; + + /** The struct alignment in bytes. */ + public static final int ALIGNOF; + + /** The struct member offsets. */ + public static final int + BUTTONS, + AXES; + + static { + Layout layout = __struct( + __array(1, 15), + __array(4, 6) + ); + + SIZEOF = layout.getSize(); + ALIGNOF = layout.getAlignment(); + + BUTTONS = layout.offsetof(0); + AXES = layout.offsetof(1); + } + + /** + * Creates a {@code GLFWGamepadState} instance at the current position of the specified {@link ByteBuffer} container. Changes to the buffer's content will be + * visible to the struct instance and vice versa. + * + *

The created instance holds a strong reference to the container object.

+ */ + public GLFWGamepadState(ByteBuffer container) { + super(memAddress(container), __checkContainer(container, SIZEOF)); + } + + @Override + public int sizeof() { return SIZEOF; } + + /** Returns a {@link ByteBuffer} view of the {@code buttons} field. */ + @NativeType("unsigned char[15]") + public ByteBuffer buttons() { return nbuttons(address()); } + /** Returns the value at the specified index of the {@code buttons} field. */ + @NativeType("unsigned char") + public byte buttons(int index) { return nbuttons(address(), index); } + /** Returns a {@link FloatBuffer} view of the {@code axes} field. */ + @NativeType("float[6]") + public FloatBuffer axes() { return naxes(address()); } + /** Returns the value at the specified index of the {@code axes} field. */ + public float axes(int index) { return naxes(address(), index); } + + /** Copies the specified {@link ByteBuffer} to the {@code buttons} field. */ + public GLFWGamepadState buttons(@NativeType("unsigned char[15]") ByteBuffer value) { nbuttons(address(), value); return this; } + /** Sets the specified value at the specified index of the {@code buttons} field. */ + public GLFWGamepadState buttons(int index, @NativeType("unsigned char") byte value) { nbuttons(address(), index, value); return this; } + /** Copies the specified {@link FloatBuffer} to the {@code axes} field. */ + public GLFWGamepadState axes(@NativeType("float[6]") FloatBuffer value) { naxes(address(), value); return this; } + /** Sets the specified value at the specified index of the {@code axes} field. */ + public GLFWGamepadState axes(int index, float value) { naxes(address(), index, value); return this; } + + /** Initializes this struct with the specified values. */ + public GLFWGamepadState set( + ByteBuffer buttons, + FloatBuffer axes + ) { + buttons(buttons); + axes(axes); + + return this; + } + + /** + * Copies the specified struct data to this struct. + * + * @param src the source struct + * + * @return this struct + */ + public GLFWGamepadState set(GLFWGamepadState src) { + memCopy(src.address(), address(), SIZEOF); + return this; + } + + // ----------------------------------- + + /** Returns a new {@code GLFWGamepadState} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. */ + public static GLFWGamepadState malloc() { + return wrap(GLFWGamepadState.class, nmemAllocChecked(SIZEOF)); + } + + /** Returns a new {@code GLFWGamepadState} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. */ + public static GLFWGamepadState calloc() { + return wrap(GLFWGamepadState.class, nmemCallocChecked(1, SIZEOF)); + } + + /** Returns a new {@code GLFWGamepadState} instance allocated with {@link BufferUtils}. */ + public static GLFWGamepadState create() { + ByteBuffer container = BufferUtils.createByteBuffer(SIZEOF); + return wrap(GLFWGamepadState.class, memAddress(container), container); + } + + /** Returns a new {@code GLFWGamepadState} instance for the specified memory address. */ + public static GLFWGamepadState create(long address) { + return wrap(GLFWGamepadState.class, address); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWGamepadState createSafe(long address) { + return address == NULL ? null : wrap(GLFWGamepadState.class, address); + } + + /** + * Returns a new {@link GLFWGamepadState.Buffer} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. + * + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer malloc(int capacity) { + return wrap(Buffer.class, nmemAllocChecked(__checkMalloc(capacity, SIZEOF)), capacity); + } + + /** + * Returns a new {@link GLFWGamepadState.Buffer} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. + * + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer calloc(int capacity) { + return wrap(Buffer.class, nmemCallocChecked(capacity, SIZEOF), capacity); + } + + /** + * Returns a new {@link GLFWGamepadState.Buffer} instance allocated with {@link BufferUtils}. + * + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer create(int capacity) { + ByteBuffer container = __create(capacity, SIZEOF); + return wrap(Buffer.class, memAddress(container), capacity, container); + } + + /** + * Create a {@link GLFWGamepadState.Buffer} instance at the specified memory. + * + * @param address the memory address + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer create(long address, int capacity) { + return wrap(Buffer.class, address, capacity); + } + + /** Like {@link #create(long, int) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWGamepadState.Buffer createSafe(long address, int capacity) { + return address == NULL ? null : wrap(Buffer.class, address, capacity); + } + + // ----------------------------------- + + /** Returns a new {@code GLFWGamepadState} instance allocated on the thread-local {@link MemoryStack}. */ + public static GLFWGamepadState mallocStack() { + return mallocStack(stackGet()); + } + + /** Returns a new {@code GLFWGamepadState} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. */ + public static GLFWGamepadState callocStack() { + return callocStack(stackGet()); + } + + /** + * Returns a new {@code GLFWGamepadState} instance allocated on the specified {@link MemoryStack}. + * + * @param stack the stack from which to allocate + */ + public static GLFWGamepadState mallocStack(MemoryStack stack) { + return wrap(GLFWGamepadState.class, stack.nmalloc(ALIGNOF, SIZEOF)); + } + + /** + * Returns a new {@code GLFWGamepadState} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. + * + * @param stack the stack from which to allocate + */ + public static GLFWGamepadState callocStack(MemoryStack stack) { + return wrap(GLFWGamepadState.class, stack.ncalloc(ALIGNOF, 1, SIZEOF)); + } + + /** + * Returns a new {@link GLFWGamepadState.Buffer} instance allocated on the thread-local {@link MemoryStack}. + * + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer mallocStack(int capacity) { + return mallocStack(capacity, stackGet()); + } + + /** + * Returns a new {@link GLFWGamepadState.Buffer} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. + * + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer callocStack(int capacity) { + return callocStack(capacity, stackGet()); + } + + /** + * Returns a new {@link GLFWGamepadState.Buffer} instance allocated on the specified {@link MemoryStack}. + * + * @param stack the stack from which to allocate + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer mallocStack(int capacity, MemoryStack stack) { + return wrap(Buffer.class, stack.nmalloc(ALIGNOF, capacity * SIZEOF), capacity); + } + + /** + * Returns a new {@link GLFWGamepadState.Buffer} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. + * + * @param stack the stack from which to allocate + * @param capacity the buffer capacity + */ + public static GLFWGamepadState.Buffer callocStack(int capacity, MemoryStack stack) { + return wrap(Buffer.class, stack.ncalloc(ALIGNOF, capacity, SIZEOF), capacity); + } + + // ----------------------------------- + + /** Unsafe version of {@link #buttons}. */ + public static ByteBuffer nbuttons(long struct) { return memByteBuffer(struct + GLFWGamepadState.BUTTONS, 15); } + /** Unsafe version of {@link #buttons(int) buttons}. */ + public static byte nbuttons(long struct, int index) { + return UNSAFE.getByte(null, struct + GLFWGamepadState.BUTTONS + check(index, 15) * 1); + } + /** Unsafe version of {@link #axes}. */ + public static FloatBuffer naxes(long struct) { return memFloatBuffer(struct + GLFWGamepadState.AXES, 6); } + /** Unsafe version of {@link #axes(int) axes}. */ + public static float naxes(long struct, int index) { + return UNSAFE.getFloat(null, struct + GLFWGamepadState.AXES + check(index, 6) * 4); + } + + /** Unsafe version of {@link #buttons(ByteBuffer) buttons}. */ + public static void nbuttons(long struct, ByteBuffer value) { + if (CHECKS) { checkGT(value, 15); } + memCopy(memAddress(value), struct + GLFWGamepadState.BUTTONS, value.remaining() * 1); + } + /** Unsafe version of {@link #buttons(int, byte) buttons}. */ + public static void nbuttons(long struct, int index, byte value) { + UNSAFE.putByte(null, struct + GLFWGamepadState.BUTTONS + check(index, 15) * 1, value); + } + /** Unsafe version of {@link #axes(FloatBuffer) axes}. */ + public static void naxes(long struct, FloatBuffer value) { + if (CHECKS) { checkGT(value, 6); } + memCopy(memAddress(value), struct + GLFWGamepadState.AXES, value.remaining() * 4); + } + /** Unsafe version of {@link #axes(int, float) axes}. */ + public static void naxes(long struct, int index, float value) { + UNSAFE.putFloat(null, struct + GLFWGamepadState.AXES + check(index, 6) * 4, value); + } + + // ----------------------------------- + + /** An array of {@link GLFWGamepadState} structs. */ + public static class Buffer extends StructBuffer implements NativeResource { + + private static final GLFWGamepadState ELEMENT_FACTORY = GLFWGamepadState.create(-1L); + + /** + * Creates a new {@code GLFWGamepadState.Buffer} instance backed by the specified container. + * + * Changes to the container's content will be visible to the struct buffer instance and vice versa. The two buffers' position, limit, and mark values + * will be independent. The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer divided + * by {@link GLFWGamepadState#SIZEOF}, and its mark will be undefined. + * + *

The created buffer instance holds a strong reference to the container object.

+ */ + public Buffer(ByteBuffer container) { + super(container, container.remaining() / SIZEOF); + } + + public Buffer(long address, int cap) { + super(address, null, -1, 0, cap, cap); + } + + Buffer(long address, @Nullable ByteBuffer container, int mark, int pos, int lim, int cap) { + super(address, container, mark, pos, lim, cap); + } + + @Override + protected Buffer self() { + return this; + } + + @Override + protected GLFWGamepadState getElementFactory() { + return ELEMENT_FACTORY; + } + + /** Returns a {@link ByteBuffer} view of the {@code buttons} field. */ + @NativeType("unsigned char[15]") + public ByteBuffer buttons() { return GLFWGamepadState.nbuttons(address()); } + /** Returns the value at the specified index of the {@code buttons} field. */ + @NativeType("unsigned char") + public byte buttons(int index) { return GLFWGamepadState.nbuttons(address(), index); } + /** Returns a {@link FloatBuffer} view of the {@code axes} field. */ + @NativeType("float[6]") + public FloatBuffer axes() { return GLFWGamepadState.naxes(address()); } + /** Returns the value at the specified index of the {@code axes} field. */ + public float axes(int index) { return GLFWGamepadState.naxes(address(), index); } + + /** Copies the specified {@link ByteBuffer} to the {@code buttons} field. */ + public GLFWGamepadState.Buffer buttons(@NativeType("unsigned char[15]") ByteBuffer value) { GLFWGamepadState.nbuttons(address(), value); return this; } + /** Sets the specified value at the specified index of the {@code buttons} field. */ + public GLFWGamepadState.Buffer buttons(int index, @NativeType("unsigned char") byte value) { GLFWGamepadState.nbuttons(address(), index, value); return this; } + /** Copies the specified {@link FloatBuffer} to the {@code axes} field. */ + public GLFWGamepadState.Buffer axes(@NativeType("float[6]") FloatBuffer value) { GLFWGamepadState.naxes(address(), value); return this; } + /** Sets the specified value at the specified index of the {@code axes} field. */ + public GLFWGamepadState.Buffer axes(int index, float value) { GLFWGamepadState.naxes(address(), index, value); return this; } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGammaRamp.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGammaRamp.java new file mode 100644 index 000000000..b0c051bfd --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWGammaRamp.java @@ -0,0 +1,384 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.*; +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.MemoryUtil.*; +import static org.lwjgl.system.MemoryStack.*; + +/** + * Describes the gamma ramp for a monitor. + * + *

Member documentation

+ * + *
    + *
  • {@code red} – an array of values describing the response of the red channel
  • + *
  • {@code green} – an array of values describing the response of the green channel
  • + *
  • {@code blue} – an array of values describing the response of the blue channel
  • + *
  • {@code size} – the number of elements in each array
  • + *
+ * + *

Layout

+ * + *

+ * struct GLFWgammaramp {
+ *     unsigned short * red;
+ *     unsigned short * green;
+ *     unsigned short * blue;
+ *     unsigned int size;
+ * }
+ * + * @since version 3.0 + */ +@NativeType("struct GLFWgammaramp") +public class GLFWGammaRamp extends Struct implements NativeResource { + + /** The struct size in bytes. */ + public static final int SIZEOF; + + /** The struct alignment in bytes. */ + public static final int ALIGNOF; + + /** The struct member offsets. */ + public static final int + RED, + GREEN, + BLUE, + SIZE; + + static { + Layout layout = __struct( + __member(POINTER_SIZE), + __member(POINTER_SIZE), + __member(POINTER_SIZE), + __member(4) + ); + + SIZEOF = layout.getSize(); + ALIGNOF = layout.getAlignment(); + + RED = layout.offsetof(0); + GREEN = layout.offsetof(1); + BLUE = layout.offsetof(2); + SIZE = layout.offsetof(3); + } + + /** + * Creates a {@code GLFWGammaRamp} instance at the current position of the specified {@link ByteBuffer} container. Changes to the buffer's content will be + * visible to the struct instance and vice versa. + * + *

The created instance holds a strong reference to the container object.

+ */ + public GLFWGammaRamp(ByteBuffer container) { + super(memAddress(container), __checkContainer(container, SIZEOF)); + } + + @Override + public int sizeof() { return SIZEOF; } + + /** Returns a {@link ShortBuffer} view of the data pointed to by the {@code red} field. */ + @NativeType("unsigned short *") + public ShortBuffer red() { return nred(address()); } + /** Returns a {@link ShortBuffer} view of the data pointed to by the {@code green} field. */ + @NativeType("unsigned short *") + public ShortBuffer green() { return ngreen(address()); } + /** Returns a {@link ShortBuffer} view of the data pointed to by the {@code blue} field. */ + @NativeType("unsigned short *") + public ShortBuffer blue() { return nblue(address()); } + /** Returns the value of the {@code size} field. */ + @NativeType("unsigned int") + public int size() { return nsize(address()); } + + /** Sets the address of the specified {@link ShortBuffer} to the {@code red} field. */ + public GLFWGammaRamp red(@NativeType("unsigned short *") ShortBuffer value) { nred(address(), value); return this; } + /** Sets the address of the specified {@link ShortBuffer} to the {@code green} field. */ + public GLFWGammaRamp green(@NativeType("unsigned short *") ShortBuffer value) { ngreen(address(), value); return this; } + /** Sets the address of the specified {@link ShortBuffer} to the {@code blue} field. */ + public GLFWGammaRamp blue(@NativeType("unsigned short *") ShortBuffer value) { nblue(address(), value); return this; } + /** Sets the specified value to the {@code size} field. */ + public GLFWGammaRamp size(@NativeType("unsigned int") int value) { nsize(address(), value); return this; } + + /** Initializes this struct with the specified values. */ + public GLFWGammaRamp set( + ShortBuffer red, + ShortBuffer green, + ShortBuffer blue, + int size + ) { + red(red); + green(green); + blue(blue); + size(size); + + return this; + } + + /** + * Copies the specified struct data to this struct. + * + * @param src the source struct + * + * @return this struct + */ + public GLFWGammaRamp set(GLFWGammaRamp src) { + memCopy(src.address(), address(), SIZEOF); + return this; + } + + // ----------------------------------- + + /** Returns a new {@code GLFWGammaRamp} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. */ + public static GLFWGammaRamp malloc() { + return wrap(GLFWGammaRamp.class, nmemAllocChecked(SIZEOF)); + } + + /** Returns a new {@code GLFWGammaRamp} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. */ + public static GLFWGammaRamp calloc() { + return wrap(GLFWGammaRamp.class, nmemCallocChecked(1, SIZEOF)); + } + + /** Returns a new {@code GLFWGammaRamp} instance allocated with {@link BufferUtils}. */ + public static GLFWGammaRamp create() { + ByteBuffer container = BufferUtils.createByteBuffer(SIZEOF); + return wrap(GLFWGammaRamp.class, memAddress(container), container); + } + + /** Returns a new {@code GLFWGammaRamp} instance for the specified memory address. */ + public static GLFWGammaRamp create(long address) { + return wrap(GLFWGammaRamp.class, address); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWGammaRamp createSafe(long address) { + return address == NULL ? null : wrap(GLFWGammaRamp.class, address); + } + + /** + * Returns a new {@link GLFWGammaRamp.Buffer} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. + * + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer malloc(int capacity) { + return wrap(Buffer.class, nmemAllocChecked(__checkMalloc(capacity, SIZEOF)), capacity); + } + + /** + * Returns a new {@link GLFWGammaRamp.Buffer} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. + * + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer calloc(int capacity) { + return wrap(Buffer.class, nmemCallocChecked(capacity, SIZEOF), capacity); + } + + /** + * Returns a new {@link GLFWGammaRamp.Buffer} instance allocated with {@link BufferUtils}. + * + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer create(int capacity) { + ByteBuffer container = __create(capacity, SIZEOF); + return wrap(Buffer.class, memAddress(container), capacity, container); + } + + /** + * Create a {@link GLFWGammaRamp.Buffer} instance at the specified memory. + * + * @param address the memory address + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer create(long address, int capacity) { + return wrap(Buffer.class, address, capacity); + } + + /** Like {@link #create(long, int) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWGammaRamp.Buffer createSafe(long address, int capacity) { + return address == NULL ? null : wrap(Buffer.class, address, capacity); + } + + // ----------------------------------- + + /** Returns a new {@code GLFWGammaRamp} instance allocated on the thread-local {@link MemoryStack}. */ + public static GLFWGammaRamp mallocStack() { + return mallocStack(stackGet()); + } + + /** Returns a new {@code GLFWGammaRamp} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. */ + public static GLFWGammaRamp callocStack() { + return callocStack(stackGet()); + } + + /** + * Returns a new {@code GLFWGammaRamp} instance allocated on the specified {@link MemoryStack}. + * + * @param stack the stack from which to allocate + */ + public static GLFWGammaRamp mallocStack(MemoryStack stack) { + return wrap(GLFWGammaRamp.class, stack.nmalloc(ALIGNOF, SIZEOF)); + } + + /** + * Returns a new {@code GLFWGammaRamp} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. + * + * @param stack the stack from which to allocate + */ + public static GLFWGammaRamp callocStack(MemoryStack stack) { + return wrap(GLFWGammaRamp.class, stack.ncalloc(ALIGNOF, 1, SIZEOF)); + } + + /** + * Returns a new {@link GLFWGammaRamp.Buffer} instance allocated on the thread-local {@link MemoryStack}. + * + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer mallocStack(int capacity) { + return mallocStack(capacity, stackGet()); + } + + /** + * Returns a new {@link GLFWGammaRamp.Buffer} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. + * + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer callocStack(int capacity) { + return callocStack(capacity, stackGet()); + } + + /** + * Returns a new {@link GLFWGammaRamp.Buffer} instance allocated on the specified {@link MemoryStack}. + * + * @param stack the stack from which to allocate + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer mallocStack(int capacity, MemoryStack stack) { + return wrap(Buffer.class, stack.nmalloc(ALIGNOF, capacity * SIZEOF), capacity); + } + + /** + * Returns a new {@link GLFWGammaRamp.Buffer} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. + * + * @param stack the stack from which to allocate + * @param capacity the buffer capacity + */ + public static GLFWGammaRamp.Buffer callocStack(int capacity, MemoryStack stack) { + return wrap(Buffer.class, stack.ncalloc(ALIGNOF, capacity, SIZEOF), capacity); + } + + // ----------------------------------- + + /** Unsafe version of {@link #red() red}. */ + public static ShortBuffer nred(long struct) { return memShortBuffer(memGetAddress(struct + GLFWGammaRamp.RED), nsize(struct)); } + /** Unsafe version of {@link #green() green}. */ + public static ShortBuffer ngreen(long struct) { return memShortBuffer(memGetAddress(struct + GLFWGammaRamp.GREEN), nsize(struct)); } + /** Unsafe version of {@link #blue() blue}. */ + public static ShortBuffer nblue(long struct) { return memShortBuffer(memGetAddress(struct + GLFWGammaRamp.BLUE), nsize(struct)); } + /** Unsafe version of {@link #size}. */ + public static int nsize(long struct) { return UNSAFE.getInt(null, struct + GLFWGammaRamp.SIZE); } + + /** Unsafe version of {@link #red(ShortBuffer) red}. */ + public static void nred(long struct, ShortBuffer value) { memPutAddress(struct + GLFWGammaRamp.RED, memAddress(value)); } + /** Unsafe version of {@link #green(ShortBuffer) green}. */ + public static void ngreen(long struct, ShortBuffer value) { memPutAddress(struct + GLFWGammaRamp.GREEN, memAddress(value)); } + /** Unsafe version of {@link #blue(ShortBuffer) blue}. */ + public static void nblue(long struct, ShortBuffer value) { memPutAddress(struct + GLFWGammaRamp.BLUE, memAddress(value)); } + /** Sets the specified value to the {@code size} field of the specified {@code struct}. */ + public static void nsize(long struct, int value) { UNSAFE.putInt(null, struct + GLFWGammaRamp.SIZE, value); } + + /** + * Validates pointer members that should not be {@code NULL}. + * + * @param struct the struct to validate + */ + public static void validate(long struct) { + check(memGetAddress(struct + GLFWGammaRamp.RED)); + check(memGetAddress(struct + GLFWGammaRamp.GREEN)); + check(memGetAddress(struct + GLFWGammaRamp.BLUE)); + } + + /** + * Calls {@link #validate(long)} for each struct contained in the specified struct array. + * + * @param array the struct array to validate + * @param count the number of structs in {@code array} + */ + public static void validate(long array, int count) { + for (int i = 0; i < count; i++) { + validate(array + Integer.toUnsignedLong(i) * SIZEOF); + } + } + + // ----------------------------------- + + /** An array of {@link GLFWGammaRamp} structs. */ + public static class Buffer extends StructBuffer implements NativeResource { + + private static final GLFWGammaRamp ELEMENT_FACTORY = GLFWGammaRamp.create(-1L); + + /** + * Creates a new {@code GLFWGammaRamp.Buffer} instance backed by the specified container. + * + * Changes to the container's content will be visible to the struct buffer instance and vice versa. The two buffers' position, limit, and mark values + * will be independent. The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer divided + * by {@link GLFWGammaRamp#SIZEOF}, and its mark will be undefined. + * + *

The created buffer instance holds a strong reference to the container object.

+ */ + public Buffer(ByteBuffer container) { + super(container, container.remaining() / SIZEOF); + } + + public Buffer(long address, int cap) { + super(address, null, -1, 0, cap, cap); + } + + Buffer(long address, @Nullable ByteBuffer container, int mark, int pos, int lim, int cap) { + super(address, container, mark, pos, lim, cap); + } + + @Override + protected Buffer self() { + return this; + } + + @Override + protected GLFWGammaRamp getElementFactory() { + return ELEMENT_FACTORY; + } + + /** Returns a {@link ShortBuffer} view of the data pointed to by the {@code red} field. */ + @NativeType("unsigned short *") + public ShortBuffer red() { return GLFWGammaRamp.nred(address()); } + /** Returns a {@link ShortBuffer} view of the data pointed to by the {@code green} field. */ + @NativeType("unsigned short *") + public ShortBuffer green() { return GLFWGammaRamp.ngreen(address()); } + /** Returns a {@link ShortBuffer} view of the data pointed to by the {@code blue} field. */ + @NativeType("unsigned short *") + public ShortBuffer blue() { return GLFWGammaRamp.nblue(address()); } + /** Returns the value of the {@code size} field. */ + @NativeType("unsigned int") + public int size() { return GLFWGammaRamp.nsize(address()); } + + /** Sets the address of the specified {@link ShortBuffer} to the {@code red} field. */ + public GLFWGammaRamp.Buffer red(@NativeType("unsigned short *") ShortBuffer value) { GLFWGammaRamp.nred(address(), value); return this; } + /** Sets the address of the specified {@link ShortBuffer} to the {@code green} field. */ + public GLFWGammaRamp.Buffer green(@NativeType("unsigned short *") ShortBuffer value) { GLFWGammaRamp.ngreen(address(), value); return this; } + /** Sets the address of the specified {@link ShortBuffer} to the {@code blue} field. */ + public GLFWGammaRamp.Buffer blue(@NativeType("unsigned short *") ShortBuffer value) { GLFWGammaRamp.nblue(address(), value); return this; } + /** Sets the specified value to the {@code size} field. */ + public GLFWGammaRamp.Buffer size(@NativeType("unsigned int") int value) { GLFWGammaRamp.nsize(address(), value); return this; } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWImage.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWImage.java new file mode 100644 index 000000000..c6feeb53a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWImage.java @@ -0,0 +1,367 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.*; +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.MemoryUtil.*; +import static org.lwjgl.system.MemoryStack.*; + +/** + * Image data. + * + *

This describes a single 2D image. See the documentation for each related function to see what the expected pixel format is.

+ * + *

Member documentation

+ * + *
    + *
  • {@code width} – the width, in pixels, of this image
  • + *
  • {@code height} – the height, in pixels, of this image
  • + *
  • {@code pixels} – the pixel data of this image, arranged left-to-right, top-to-bottom
  • + *
+ * + *

Layout

+ * + *

+ * struct GLFWimage {
+ *     int width;
+ *     int height;
+ *     unsigned char * pixels;
+ * }
+ * + * @since version 2.1 + */ +@NativeType("struct GLFWimage") +public class GLFWImage extends Struct implements NativeResource { + + /** The struct size in bytes. */ + public static final int SIZEOF; + + /** The struct alignment in bytes. */ + public static final int ALIGNOF; + + /** The struct member offsets. */ + public static final int + WIDTH, + HEIGHT, + PIXELS; + + static { + Layout layout = __struct( + __member(4), + __member(4), + __member(POINTER_SIZE) + ); + + SIZEOF = layout.getSize(); + ALIGNOF = layout.getAlignment(); + + WIDTH = layout.offsetof(0); + HEIGHT = layout.offsetof(1); + PIXELS = layout.offsetof(2); + } + + /** + * Creates a {@code GLFWImage} instance at the current position of the specified {@link ByteBuffer} container. Changes to the buffer's content will be + * visible to the struct instance and vice versa. + * + *

The created instance holds a strong reference to the container object.

+ */ + public GLFWImage(ByteBuffer container) { + super(memAddress(container), __checkContainer(container, SIZEOF)); + } + + @Override + public int sizeof() { return SIZEOF; } + + /** Returns the value of the {@code width} field. */ + public int width() { return nwidth(address()); } + /** Returns the value of the {@code height} field. */ + public int height() { return nheight(address()); } + /** + * Returns a {@link ByteBuffer} view of the data pointed to by the {@code pixels} field. + * + * @param capacity the number of elements in the returned buffer + */ + @NativeType("unsigned char *") + public ByteBuffer pixels(int capacity) { return npixels(address(), capacity); } + + /** Sets the specified value to the {@code width} field. */ + public GLFWImage width(int value) { nwidth(address(), value); return this; } + /** Sets the specified value to the {@code height} field. */ + public GLFWImage height(int value) { nheight(address(), value); return this; } + /** Sets the address of the specified {@link ByteBuffer} to the {@code pixels} field. */ + public GLFWImage pixels(@NativeType("unsigned char *") ByteBuffer value) { npixels(address(), value); return this; } + + /** Initializes this struct with the specified values. */ + public GLFWImage set( + int width, + int height, + ByteBuffer pixels + ) { + width(width); + height(height); + pixels(pixels); + + return this; + } + + /** + * Copies the specified struct data to this struct. + * + * @param src the source struct + * + * @return this struct + */ + public GLFWImage set(GLFWImage src) { + memCopy(src.address(), address(), SIZEOF); + return this; + } + + // ----------------------------------- + + /** Returns a new {@code GLFWImage} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. */ + public static GLFWImage malloc() { + return wrap(GLFWImage.class, nmemAllocChecked(SIZEOF)); + } + + /** Returns a new {@code GLFWImage} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. */ + public static GLFWImage calloc() { + return wrap(GLFWImage.class, nmemCallocChecked(1, SIZEOF)); + } + + /** Returns a new {@code GLFWImage} instance allocated with {@link BufferUtils}. */ + public static GLFWImage create() { + ByteBuffer container = BufferUtils.createByteBuffer(SIZEOF); + return wrap(GLFWImage.class, memAddress(container), container); + } + + /** Returns a new {@code GLFWImage} instance for the specified memory address. */ + public static GLFWImage create(long address) { + return wrap(GLFWImage.class, address); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWImage createSafe(long address) { + return address == NULL ? null : wrap(GLFWImage.class, address); + } + + /** + * Returns a new {@link GLFWImage.Buffer} instance allocated with {@link MemoryUtil#memAlloc memAlloc}. The instance must be explicitly freed. + * + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer malloc(int capacity) { + return wrap(Buffer.class, nmemAllocChecked(__checkMalloc(capacity, SIZEOF)), capacity); + } + + /** + * Returns a new {@link GLFWImage.Buffer} instance allocated with {@link MemoryUtil#memCalloc memCalloc}. The instance must be explicitly freed. + * + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer calloc(int capacity) { + return wrap(Buffer.class, nmemCallocChecked(capacity, SIZEOF), capacity); + } + + /** + * Returns a new {@link GLFWImage.Buffer} instance allocated with {@link BufferUtils}. + * + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer create(int capacity) { + ByteBuffer container = __create(capacity, SIZEOF); + return wrap(Buffer.class, memAddress(container), capacity, container); + } + + /** + * Create a {@link GLFWImage.Buffer} instance at the specified memory. + * + * @param address the memory address + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer create(long address, int capacity) { + return wrap(Buffer.class, address, capacity); + } + + /** Like {@link #create(long, int) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWImage.Buffer createSafe(long address, int capacity) { + return address == NULL ? null : wrap(Buffer.class, address, capacity); + } + + // ----------------------------------- + + /** Returns a new {@code GLFWImage} instance allocated on the thread-local {@link MemoryStack}. */ + public static GLFWImage mallocStack() { + return mallocStack(stackGet()); + } + + /** Returns a new {@code GLFWImage} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. */ + public static GLFWImage callocStack() { + return callocStack(stackGet()); + } + + /** + * Returns a new {@code GLFWImage} instance allocated on the specified {@link MemoryStack}. + * + * @param stack the stack from which to allocate + */ + public static GLFWImage mallocStack(MemoryStack stack) { + return wrap(GLFWImage.class, stack.nmalloc(ALIGNOF, SIZEOF)); + } + + /** + * Returns a new {@code GLFWImage} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. + * + * @param stack the stack from which to allocate + */ + public static GLFWImage callocStack(MemoryStack stack) { + return wrap(GLFWImage.class, stack.ncalloc(ALIGNOF, 1, SIZEOF)); + } + + /** + * Returns a new {@link GLFWImage.Buffer} instance allocated on the thread-local {@link MemoryStack}. + * + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer mallocStack(int capacity) { + return mallocStack(capacity, stackGet()); + } + + /** + * Returns a new {@link GLFWImage.Buffer} instance allocated on the thread-local {@link MemoryStack} and initializes all its bits to zero. + * + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer callocStack(int capacity) { + return callocStack(capacity, stackGet()); + } + + /** + * Returns a new {@link GLFWImage.Buffer} instance allocated on the specified {@link MemoryStack}. + * + * @param stack the stack from which to allocate + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer mallocStack(int capacity, MemoryStack stack) { + return wrap(Buffer.class, stack.nmalloc(ALIGNOF, capacity * SIZEOF), capacity); + } + + /** + * Returns a new {@link GLFWImage.Buffer} instance allocated on the specified {@link MemoryStack} and initializes all its bits to zero. + * + * @param stack the stack from which to allocate + * @param capacity the buffer capacity + */ + public static GLFWImage.Buffer callocStack(int capacity, MemoryStack stack) { + return wrap(Buffer.class, stack.ncalloc(ALIGNOF, capacity, SIZEOF), capacity); + } + + // ----------------------------------- + + /** Unsafe version of {@link #width}. */ + public static int nwidth(long struct) { return UNSAFE.getInt(null, struct + GLFWImage.WIDTH); } + /** Unsafe version of {@link #height}. */ + public static int nheight(long struct) { return UNSAFE.getInt(null, struct + GLFWImage.HEIGHT); } + /** Unsafe version of {@link #pixels(int) pixels}. */ + public static ByteBuffer npixels(long struct, int capacity) { return memByteBuffer(memGetAddress(struct + GLFWImage.PIXELS), capacity); } + + /** Unsafe version of {@link #width(int) width}. */ + public static void nwidth(long struct, int value) { UNSAFE.putInt(null, struct + GLFWImage.WIDTH, value); } + /** Unsafe version of {@link #height(int) height}. */ + public static void nheight(long struct, int value) { UNSAFE.putInt(null, struct + GLFWImage.HEIGHT, value); } + /** Unsafe version of {@link #pixels(ByteBuffer) pixels}. */ + public static void npixels(long struct, ByteBuffer value) { memPutAddress(struct + GLFWImage.PIXELS, memAddress(value)); } + + /** + * Validates pointer members that should not be {@code NULL}. + * + * @param struct the struct to validate + */ + public static void validate(long struct) { + check(memGetAddress(struct + GLFWImage.PIXELS)); + } + + /** + * Calls {@link #validate(long)} for each struct contained in the specified struct array. + * + * @param array the struct array to validate + * @param count the number of structs in {@code array} + */ + public static void validate(long array, int count) { + for (int i = 0; i < count; i++) { + validate(array + Integer.toUnsignedLong(i) * SIZEOF); + } + } + + // ----------------------------------- + + /** An array of {@link GLFWImage} structs. */ + public static class Buffer extends StructBuffer implements NativeResource { + + private static final GLFWImage ELEMENT_FACTORY = GLFWImage.create(-1L); + + /** + * Creates a new {@code GLFWImage.Buffer} instance backed by the specified container. + * + * Changes to the container's content will be visible to the struct buffer instance and vice versa. The two buffers' position, limit, and mark values + * will be independent. The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer divided + * by {@link GLFWImage#SIZEOF}, and its mark will be undefined. + * + *

The created buffer instance holds a strong reference to the container object.

+ */ + public Buffer(ByteBuffer container) { + super(container, container.remaining() / SIZEOF); + } + + public Buffer(long address, int cap) { + super(address, null, -1, 0, cap, cap); + } + + Buffer(long address, @Nullable ByteBuffer container, int mark, int pos, int lim, int cap) { + super(address, container, mark, pos, lim, cap); + } + + @Override + protected Buffer self() { + return this; + } + + @Override + protected GLFWImage getElementFactory() { + return ELEMENT_FACTORY; + } + + /** Returns the value of the {@code width} field. */ + public int width() { return GLFWImage.nwidth(address()); } + /** Returns the value of the {@code height} field. */ + public int height() { return GLFWImage.nheight(address()); } + /** + * Returns a {@link ByteBuffer} view of the data pointed to by the {@code pixels} field. + * + * @param capacity the number of elements in the returned buffer + */ + @NativeType("unsigned char *") + public ByteBuffer pixels(int capacity) { return GLFWImage.npixels(address(), capacity); } + + /** Sets the specified value to the {@code width} field. */ + public GLFWImage.Buffer width(int value) { GLFWImage.nwidth(address(), value); return this; } + /** Sets the specified value to the {@code height} field. */ + public GLFWImage.Buffer height(int value) { GLFWImage.nheight(address(), value); return this; } + /** Sets the address of the specified {@link ByteBuffer} to the {@code pixels} field. */ + public GLFWImage.Buffer pixels(@NativeType("unsigned char *") ByteBuffer value) { GLFWImage.npixels(address(), value); return this; } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallback.java new file mode 100644 index 000000000..85efe06eb --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetJoystickCallback SetJoystickCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     int jid,
+ *     int event
+ * )
+ * + * @since version 3.2 + */ +public abstract class GLFWJoystickCallback extends Callback implements GLFWJoystickCallbackI { + + /** + * Creates a {@code GLFWJoystickCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWJoystickCallback} + */ + public static GLFWJoystickCallback create(long functionPointer) { + GLFWJoystickCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWJoystickCallback + ? (GLFWJoystickCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWJoystickCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWJoystickCallback} instance that delegates to the specified {@code GLFWJoystickCallbackI} instance. */ + public static GLFWJoystickCallback create(GLFWJoystickCallbackI instance) { + return instance instanceof GLFWJoystickCallback + ? (GLFWJoystickCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWJoystickCallback() { + super(SIGNATURE); + } + + GLFWJoystickCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetJoystickCallback SetJoystickCallback}. */ + public GLFWJoystickCallback set() { + glfwSetJoystickCallback(this); + return this; + } + + private static final class Container extends GLFWJoystickCallback { + + private final GLFWJoystickCallbackI delegate; + + Container(long functionPointer, GLFWJoystickCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(int jid, int event) { + delegate.invoke(jid, event); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallbackI.java new file mode 100644 index 000000000..2bea9c27a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWJoystickCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetJoystickCallback SetJoystickCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     int jid,
+ *     int event
+ * )
+ * + * @since version 3.2 + */ +@FunctionalInterface +@NativeType("GLFWjoystickfun") +public interface GLFWJoystickCallbackI extends CallbackI.V { + + String SIGNATURE = "(ii)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgInt(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when a joystick is connected to or disconnected from the system. + * + * @param jid the joystick that was connected or disconnected + * @param event one of {@link GLFW#GLFW_CONNECTED CONNECTED} or {@link GLFW#GLFW_DISCONNECTED DISCONNECTED}. Remaining values reserved for future use. + */ + void invoke(int jid, int event); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallback.java new file mode 100644 index 000000000..eb7703342 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetKeyCallback SetKeyCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int key,
+ *     int scancode,
+ *     int action,
+ *     int mods
+ * )
+ */ +public abstract class GLFWKeyCallback extends Callback implements GLFWKeyCallbackI { + + /** + * Creates a {@code GLFWKeyCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWKeyCallback} + */ + public static GLFWKeyCallback create(long functionPointer) { + GLFWKeyCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWKeyCallback + ? (GLFWKeyCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWKeyCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWKeyCallback} instance that delegates to the specified {@code GLFWKeyCallbackI} instance. */ + public static GLFWKeyCallback create(GLFWKeyCallbackI instance) { + return instance instanceof GLFWKeyCallback + ? (GLFWKeyCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWKeyCallback() { + super(SIGNATURE); + } + + GLFWKeyCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetKeyCallback SetKeyCallback}. */ + public GLFWKeyCallback set(long window) { + glfwSetKeyCallback(window, this); + return this; + } + + private static final class Container extends GLFWKeyCallback { + + private final GLFWKeyCallbackI delegate; + + Container(long functionPointer, GLFWKeyCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int key, int scancode, int action, int mods) { + delegate.invoke(window, key, scancode, action, mods); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallbackI.java new file mode 100644 index 000000000..ed506cf34 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWKeyCallbackI.java @@ -0,0 +1,57 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetKeyCallback SetKeyCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int key,
+ *     int scancode,
+ *     int action,
+ *     int mods
+ * )
+ */ +@FunctionalInterface +@NativeType("GLFWkeyfun") +public interface GLFWKeyCallbackI extends CallbackI.V { + + String SIGNATURE = "(piiii)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args), + dcbArgInt(args), + dcbArgInt(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when a key is pressed, repeated or released. + * + * @param window the window that received the event + * @param key the keyboard key that was pressed or released + * @param scancode the system-specific scancode of the key + * @param action the key action. One of:
{@link GLFW#GLFW_PRESS PRESS}{@link GLFW#GLFW_RELEASE RELEASE}{@link GLFW#GLFW_REPEAT REPEAT}
+ * @param mods bitfield describing which modifiers keys were held down + */ + void invoke(@NativeType("GLFWwindow *") long window, int key, int scancode, int action, int mods); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallback.java new file mode 100644 index 000000000..a67265e27 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetMonitorCallback SetMonitorCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWmonitor *monitor,
+ *     int event
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWMonitorCallback extends Callback implements GLFWMonitorCallbackI { + + /** + * Creates a {@code GLFWMonitorCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWMonitorCallback} + */ + public static GLFWMonitorCallback create(long functionPointer) { + GLFWMonitorCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWMonitorCallback + ? (GLFWMonitorCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWMonitorCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWMonitorCallback} instance that delegates to the specified {@code GLFWMonitorCallbackI} instance. */ + public static GLFWMonitorCallback create(GLFWMonitorCallbackI instance) { + return instance instanceof GLFWMonitorCallback + ? (GLFWMonitorCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWMonitorCallback() { + super(SIGNATURE); + } + + GLFWMonitorCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetMonitorCallback SetMonitorCallback}. */ + public GLFWMonitorCallback set() { + glfwSetMonitorCallback(this); + return this; + } + + private static final class Container extends GLFWMonitorCallback { + + private final GLFWMonitorCallbackI delegate; + + Container(long functionPointer, GLFWMonitorCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long monitor, int event) { + delegate.invoke(monitor, event); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallbackI.java new file mode 100644 index 000000000..b0a215afd --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMonitorCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetMonitorCallback SetMonitorCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWmonitor *monitor,
+ *     int event
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWmonitorfun") +public interface GLFWMonitorCallbackI extends CallbackI.V { + + String SIGNATURE = "(pi)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when a monitor is connected to or disconnected from the system. + * + * @param monitor the monitor that was connected or disconnected + * @param event one of {@link GLFW#GLFW_CONNECTED CONNECTED} or {@link GLFW#GLFW_DISCONNECTED DISCONNECTED}. Remaining values reserved for future use. + */ + void invoke(@NativeType("GLFWmonitor *") long monitor, int event); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallback.java new file mode 100644 index 000000000..0edc6ff30 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetMouseButtonCallback SetMouseButtonCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int button,
+ *     int action,
+ *     int mods
+ * )
+ */ +public abstract class GLFWMouseButtonCallback extends Callback implements GLFWMouseButtonCallbackI { + + /** + * Creates a {@code GLFWMouseButtonCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWMouseButtonCallback} + */ + public static GLFWMouseButtonCallback create(long functionPointer) { + GLFWMouseButtonCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWMouseButtonCallback + ? (GLFWMouseButtonCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWMouseButtonCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWMouseButtonCallback} instance that delegates to the specified {@code GLFWMouseButtonCallbackI} instance. */ + public static GLFWMouseButtonCallback create(GLFWMouseButtonCallbackI instance) { + return instance instanceof GLFWMouseButtonCallback + ? (GLFWMouseButtonCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWMouseButtonCallback() { + super(SIGNATURE); + } + + GLFWMouseButtonCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetMouseButtonCallback SetMouseButtonCallback}. */ + public GLFWMouseButtonCallback set(long window) { + glfwSetMouseButtonCallback(window, this); + return this; + } + + private static final class Container extends GLFWMouseButtonCallback { + + private final GLFWMouseButtonCallbackI delegate; + + Container(long functionPointer, GLFWMouseButtonCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int button, int action, int mods) { + delegate.invoke(window, button, action, mods); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallbackI.java new file mode 100644 index 000000000..e010c1c1a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWMouseButtonCallbackI.java @@ -0,0 +1,54 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetMouseButtonCallback SetMouseButtonCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int button,
+ *     int action,
+ *     int mods
+ * )
+ */ +@FunctionalInterface +@NativeType("GLFWmousebuttonfun") +public interface GLFWMouseButtonCallbackI extends CallbackI.V { + + String SIGNATURE = "(piii)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args), + dcbArgInt(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when a mouse button is pressed or released. + * + * @param window the window that received the event + * @param button the mouse button that was pressed or released + * @param action the button action. One of:
{@link GLFW#GLFW_PRESS PRESS}{@link GLFW#GLFW_RELEASE RELEASE}
+ * @param mods bitfield describing which modifiers keys were held down + */ + void invoke(@NativeType("GLFWwindow *") long window, int button, int action, int mods); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWNativeGLX.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWNativeGLX.java new file mode 100644 index 000000000..eaf7c2a2a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWNativeGLX.java @@ -0,0 +1,125 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.APIUtil.*; +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; + +import javax.annotation.*; +import org.lwjgl.opengl.GL; + +import static org.lwjgl.system.MemoryUtil.*; + +/** Native bindings to the GLFW library's GLX native access functions. */ +public class GLFWNativeGLX { + + protected GLFWNativeGLX() { + throw new UnsupportedOperationException(); + } + + /** Contains the function pointers loaded from {@code GLFW.getLibrary()}. */ + public static final class Functions { + + private Functions() {} + + /** Function address. */ + public static final long + GetGLXContext = apiGetFunctionAddress(GLFW.getLibrary(), "glfwGetGLXContext"), + GetGLXWindow = apiGetFunctionAddress(GLFW.getLibrary(), "glfwGetGLXWindow"); + + } + + // --- [ glfwGetGLXContext ] --- + + /** + * Returns the {@code GLXContext} of the specified window. + * + *

This function may be called from any thread. Access is not synchronized.

+ * + * @param window a GLFW window + * + * @return the {@code GLXContext} of the specified window, or {@code NULL} if an error occurred. + * + * @since version 3.0 + */ + @NativeType("GLXContext") + public static long glfwGetGLXContext(@NativeType("GLFWwindow *") long window) { + long __functionAddress = Functions.GetGLXContext; + if (CHECKS) { + check(window); + } + return invokePP(window, __functionAddress); + } + + // --- [ glfwGetGLXWindow ] --- + + /** + * Returns the {@code GLXWindow} of the specified window. + * + *

This function may be called from any thread. Access is not synchronized.

+ * + * @param window a GLFW window + * + * @return the {@code GLXWindow} of the specified window, or {@code None} if an error occurred. + * + * @since version 3.2 + */ + @NativeType("GLXWindow") + public static long glfwGetGLXWindow(@NativeType("GLFWwindow *") long window) { + long __functionAddress = Functions.GetGLXWindow; + if (CHECKS) { + check(window); + } + return invokePP(window, __functionAddress); + } + + /** Calls {@link #setPath(String)} with the path of the OpenGL shared library loaded by LWJGL. */ + public static void setPathLWJGL() { + FunctionProvider fp = GL.getFunctionProvider(); + if (!(fp instanceof SharedLibrary)) { + apiLog("GLFW OpenGL path override not set: OpenGL function provider is not a shared library."); + return; + + } + + String path = ((SharedLibrary)fp).getPath(); + if (path == null) { + apiLog("GLFW OpenGL path override not set: Could not resolve the OpenGL shared library path."); + return; + + } + + setPath(path); + } + + /** + * Overrides the OpenGL shared library that GLFW loads internally. + * + *

This is useful when there's a mismatch between the shared libraries loaded by LWJGL and GLFW.

+ * + *

This method must be called before GLFW initializes OpenGL. The override is available only in the default GLFW build bundled with LWJGL. Using the + * override with a custom GLFW build will produce a warning in {@code DEBUG} mode (but not an error).

+ * + * @param path the OpenGL shared library path, or {@code null} to remove the override. + */ + public static void setPath(@Nullable String path) { + long override = GLFW.getLibrary().getFunctionAddress("_glfw_opengl_library"); + if (override == NULL) { + apiLog("GLFW OpenGL path override not set: Could not resolve override symbol."); + return; + } + + long a = memGetAddress(override); + if (a != NULL) { + nmemFree(a); + } + memPutAddress(override, path == null ? NULL : memAddress(memUTF8(path))); + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallback.java new file mode 100644 index 000000000..4a305a8bd --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetScrollCallback SetScrollCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     double xoffset,
+ *     double yoffset
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWScrollCallback extends Callback implements GLFWScrollCallbackI { + + /** + * Creates a {@code GLFWScrollCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWScrollCallback} + */ + public static GLFWScrollCallback create(long functionPointer) { + GLFWScrollCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWScrollCallback + ? (GLFWScrollCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWScrollCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWScrollCallback} instance that delegates to the specified {@code GLFWScrollCallbackI} instance. */ + public static GLFWScrollCallback create(GLFWScrollCallbackI instance) { + return instance instanceof GLFWScrollCallback + ? (GLFWScrollCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWScrollCallback() { + super(SIGNATURE); + } + + GLFWScrollCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetScrollCallback SetScrollCallback}. */ + public GLFWScrollCallback set(long window) { + glfwSetScrollCallback(window, this); + return this; + } + + private static final class Container extends GLFWScrollCallback { + + private final GLFWScrollCallbackI delegate; + + Container(long functionPointer, GLFWScrollCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, double xoffset, double yoffset) { + delegate.invoke(window, xoffset, yoffset); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallbackI.java new file mode 100644 index 000000000..b467832a0 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWScrollCallbackI.java @@ -0,0 +1,53 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetScrollCallback SetScrollCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     double xoffset,
+ *     double yoffset
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWscrollfun") +public interface GLFWScrollCallbackI extends CallbackI.V { + + String SIGNATURE = "(pdd)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgDouble(args), + dcbArgDouble(args) + ); + } + + /** + * Will be called when a scrolling device is used, such as a mouse wheel or scrolling area of a touchpad. + * + * @param window the window that received the event + * @param xoffset the scroll offset along the x-axis + * @param yoffset the scroll offset along the y-axis + */ + void invoke(@NativeType("GLFWwindow *") long window, double xoffset, double yoffset); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWVidMode.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWVidMode.java new file mode 100644 index 000000000..5e06259dc --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWVidMode.java @@ -0,0 +1,204 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +/** + * Describes a single video mode. + * + *

Member documentation

+ * + *
    + *
  • {@code width} – the width, in screen coordinates, of the video mode
  • + *
  • {@code height} – the height, in screen coordinates, of the video mode
  • + *
  • {@code redBits} – the bit depth of the red channel of the video mode
  • + *
  • {@code greenBits} – the bit depth of the green channel of the video mode
  • + *
  • {@code blueBits} – the bit depth of the blue channel of the video mode
  • + *
  • {@code refreshRate} – the refresh rate, in Hz, of the video mode
  • + *
+ * + *

Layout

+ * + *

+ * struct GLFWvidmode {
+ *     int width;
+ *     int height;
+ *     int redBits;
+ *     int greenBits;
+ *     int blueBits;
+ *     int refreshRate;
+ * }
+ */ +@NativeType("struct GLFWvidmode") +public class GLFWVidMode extends Struct { + + /** The struct size in bytes. */ + public static final int SIZEOF; + + /** The struct alignment in bytes. */ + public static final int ALIGNOF; + + /** The struct member offsets. */ + public static final int + WIDTH, + HEIGHT, + REDBITS, + GREENBITS, + BLUEBITS, + REFRESHRATE; + + static { + Layout layout = __struct( + __member(4), + __member(4), + __member(4), + __member(4), + __member(4), + __member(4) + ); + + SIZEOF = layout.getSize(); + ALIGNOF = layout.getAlignment(); + + WIDTH = layout.offsetof(0); + HEIGHT = layout.offsetof(1); + REDBITS = layout.offsetof(2); + GREENBITS = layout.offsetof(3); + BLUEBITS = layout.offsetof(4); + REFRESHRATE = layout.offsetof(5); + } + + /** + * Creates a {@code GLFWVidMode} instance at the current position of the specified {@link ByteBuffer} container. Changes to the buffer's content will be + * visible to the struct instance and vice versa. + * + *

The created instance holds a strong reference to the container object.

+ */ + public GLFWVidMode(ByteBuffer container) { + super(memAddress(container), __checkContainer(container, SIZEOF)); + } + + @Override + public int sizeof() { return SIZEOF; } + + /** Returns the value of the {@code width} field. */ + public int width() { return nwidth(address()); } + /** Returns the value of the {@code height} field. */ + public int height() { return nheight(address()); } + /** Returns the value of the {@code redBits} field. */ + public int redBits() { return nredBits(address()); } + /** Returns the value of the {@code greenBits} field. */ + public int greenBits() { return ngreenBits(address()); } + /** Returns the value of the {@code blueBits} field. */ + public int blueBits() { return nblueBits(address()); } + /** Returns the value of the {@code refreshRate} field. */ + public int refreshRate() { return nrefreshRate(address()); } + + // ----------------------------------- + + /** Returns a new {@code GLFWVidMode} instance for the specified memory address. */ + public static GLFWVidMode create(long address) { + return wrap(GLFWVidMode.class, address); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWVidMode createSafe(long address) { + return address == NULL ? null : wrap(GLFWVidMode.class, address); + } + + /** + * Create a {@link GLFWVidMode.Buffer} instance at the specified memory. + * + * @param address the memory address + * @param capacity the buffer capacity + */ + public static GLFWVidMode.Buffer create(long address, int capacity) { + return wrap(Buffer.class, address, capacity); + } + + /** Like {@link #create(long, int) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWVidMode.Buffer createSafe(long address, int capacity) { + return address == NULL ? null : wrap(Buffer.class, address, capacity); + } + + // ----------------------------------- + + /** Unsafe version of {@link #width}. */ + public static int nwidth(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.WIDTH); } + /** Unsafe version of {@link #height}. */ + public static int nheight(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.HEIGHT); } + /** Unsafe version of {@link #redBits}. */ + public static int nredBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.REDBITS); } + /** Unsafe version of {@link #greenBits}. */ + public static int ngreenBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.GREENBITS); } + /** Unsafe version of {@link #blueBits}. */ + public static int nblueBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.BLUEBITS); } + /** Unsafe version of {@link #refreshRate}. */ + public static int nrefreshRate(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.REFRESHRATE); } + + // ----------------------------------- + + /** An array of {@link GLFWVidMode} structs. */ + public static class Buffer extends StructBuffer { + + private static final GLFWVidMode ELEMENT_FACTORY = GLFWVidMode.create(-1L); + + /** + * Creates a new {@code GLFWVidMode.Buffer} instance backed by the specified container. + * + * Changes to the container's content will be visible to the struct buffer instance and vice versa. The two buffers' position, limit, and mark values + * will be independent. The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer divided + * by {@link GLFWVidMode#SIZEOF}, and its mark will be undefined. + * + *

The created buffer instance holds a strong reference to the container object.

+ */ + public Buffer(ByteBuffer container) { + super(container, container.remaining() / SIZEOF); + } + + public Buffer(long address, int cap) { + super(address, null, -1, 0, cap, cap); + } + + Buffer(long address, @Nullable ByteBuffer container, int mark, int pos, int lim, int cap) { + super(address, container, mark, pos, lim, cap); + } + + @Override + protected Buffer self() { + return this; + } + + @Override + protected GLFWVidMode getElementFactory() { + return ELEMENT_FACTORY; + } + + /** Returns the value of the {@code width} field. */ + public int width() { return GLFWVidMode.nwidth(address()); } + /** Returns the value of the {@code height} field. */ + public int height() { return GLFWVidMode.nheight(address()); } + /** Returns the value of the {@code redBits} field. */ + public int redBits() { return GLFWVidMode.nredBits(address()); } + /** Returns the value of the {@code greenBits} field. */ + public int greenBits() { return GLFWVidMode.ngreenBits(address()); } + /** Returns the value of the {@code blueBits} field. */ + public int blueBits() { return GLFWVidMode.nblueBits(address()); } + /** Returns the value of the {@code refreshRate} field. */ + public int refreshRate() { return GLFWVidMode.nrefreshRate(address()); } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallback.java new file mode 100644 index 000000000..da74a99c6 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallback.java @@ -0,0 +1,85 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowCloseCallback SetWindowCloseCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window
+ * )
+ * + * @since version 2.5 + */ +public abstract class GLFWWindowCloseCallback extends Callback implements GLFWWindowCloseCallbackI { + + /** + * Creates a {@code GLFWWindowCloseCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowCloseCallback} + */ + public static GLFWWindowCloseCallback create(long functionPointer) { + GLFWWindowCloseCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowCloseCallback + ? (GLFWWindowCloseCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowCloseCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowCloseCallback} instance that delegates to the specified {@code GLFWWindowCloseCallbackI} instance. */ + public static GLFWWindowCloseCallback create(GLFWWindowCloseCallbackI instance) { + return instance instanceof GLFWWindowCloseCallback + ? (GLFWWindowCloseCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowCloseCallback() { + super(SIGNATURE); + } + + GLFWWindowCloseCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowCloseCallback SetWindowCloseCallback}. */ + public GLFWWindowCloseCallback set(long window) { + glfwSetWindowCloseCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowCloseCallback { + + private final GLFWWindowCloseCallbackI delegate; + + Container(long functionPointer, GLFWWindowCloseCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window) { + delegate.invoke(window); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallbackI.java new file mode 100644 index 000000000..f4357e29f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowCloseCallbackI.java @@ -0,0 +1,47 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowCloseCallback SetWindowCloseCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window
+ * )
+ * + * @since version 2.5 + */ +@FunctionalInterface +@NativeType("GLFWwindowclosefun") +public interface GLFWWindowCloseCallbackI extends CallbackI.V { + + String SIGNATURE = "(p)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args) + ); + } + + /** + * Will be called when the user attempts to close the specified window, for example by clicking the close widget in the title bar. + * + * @param window the window that the user attempted to close + */ + void invoke(@NativeType("GLFWwindow *") long window); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallback.java new file mode 100644 index 000000000..8b61d6377 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowContentScaleCallback SetWindowContentScaleCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     float xscale,
+ *     float yscale
+ * )
+ * + * @since version 3.3 + */ +public abstract class GLFWWindowContentScaleCallback extends Callback implements GLFWWindowContentScaleCallbackI { + + /** + * Creates a {@code GLFWWindowContentScaleCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowContentScaleCallback} + */ + public static GLFWWindowContentScaleCallback create(long functionPointer) { + GLFWWindowContentScaleCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowContentScaleCallback + ? (GLFWWindowContentScaleCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowContentScaleCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowContentScaleCallback} instance that delegates to the specified {@code GLFWWindowContentScaleCallbackI} instance. */ + public static GLFWWindowContentScaleCallback create(GLFWWindowContentScaleCallbackI instance) { + return instance instanceof GLFWWindowContentScaleCallback + ? (GLFWWindowContentScaleCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowContentScaleCallback() { + super(SIGNATURE); + } + + GLFWWindowContentScaleCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowContentScaleCallback SetWindowContentScaleCallback}. */ + public GLFWWindowContentScaleCallback set(long window) { + glfwSetWindowContentScaleCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowContentScaleCallback { + + private final GLFWWindowContentScaleCallbackI delegate; + + Container(long functionPointer, GLFWWindowContentScaleCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, float xscale, float yscale) { + delegate.invoke(window, xscale, yscale); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallbackI.java new file mode 100644 index 000000000..d3c979f63 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowContentScaleCallbackI.java @@ -0,0 +1,53 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowContentScaleCallback SetWindowContentScaleCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     float xscale,
+ *     float yscale
+ * )
+ * + * @since version 3.3 + */ +@FunctionalInterface +@NativeType("GLFWwindowcontentscalefun") +public interface GLFWWindowContentScaleCallbackI extends CallbackI.V { + + String SIGNATURE = "(pff)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgFloat(args), + dcbArgFloat(args) + ); + } + + /** + * Will be called when the window content scale changes. + * + * @param window the window whose content scale changed + * @param xscale the new x-axis content scale of the window + * @param yscale the new y-axis content scale of the window + */ + void invoke(@NativeType("GLFWwindow *") long window, float xscale, float yscale); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallback.java new file mode 100644 index 000000000..74b466658 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowFocusCallback SetWindowFocusCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int focused
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWWindowFocusCallback extends Callback implements GLFWWindowFocusCallbackI { + + /** + * Creates a {@code GLFWWindowFocusCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowFocusCallback} + */ + public static GLFWWindowFocusCallback create(long functionPointer) { + GLFWWindowFocusCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowFocusCallback + ? (GLFWWindowFocusCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowFocusCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowFocusCallback} instance that delegates to the specified {@code GLFWWindowFocusCallbackI} instance. */ + public static GLFWWindowFocusCallback create(GLFWWindowFocusCallbackI instance) { + return instance instanceof GLFWWindowFocusCallback + ? (GLFWWindowFocusCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowFocusCallback() { + super(SIGNATURE); + } + + GLFWWindowFocusCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowFocusCallback SetWindowFocusCallback}. */ + public GLFWWindowFocusCallback set(long window) { + glfwSetWindowFocusCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowFocusCallback { + + private final GLFWWindowFocusCallbackI delegate; + + Container(long functionPointer, GLFWWindowFocusCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, boolean focused) { + delegate.invoke(window, focused); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallbackI.java new file mode 100644 index 000000000..6ea92b122 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowFocusCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowFocusCallback SetWindowFocusCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int focused
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWwindowfocusfun") +public interface GLFWWindowFocusCallbackI extends CallbackI.V { + + String SIGNATURE = "(pi)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args) != 0 + ); + } + + /** + * Will be called when the specified window gains or loses focus. + * + * @param window the window that was focused or defocused + * @param focused {@link GLFW#GLFW_TRUE TRUE} if the window was focused, or {@link GLFW#GLFW_FALSE FALSE} if it was defocused + */ + void invoke(@NativeType("GLFWwindow *") long window, @NativeType("int") boolean focused); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallback.java new file mode 100644 index 000000000..a9616a17f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowIconifyCallback SetWindowIconifyCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int iconified
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWWindowIconifyCallback extends Callback implements GLFWWindowIconifyCallbackI { + + /** + * Creates a {@code GLFWWindowIconifyCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowIconifyCallback} + */ + public static GLFWWindowIconifyCallback create(long functionPointer) { + GLFWWindowIconifyCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowIconifyCallback + ? (GLFWWindowIconifyCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowIconifyCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowIconifyCallback} instance that delegates to the specified {@code GLFWWindowIconifyCallbackI} instance. */ + public static GLFWWindowIconifyCallback create(GLFWWindowIconifyCallbackI instance) { + return instance instanceof GLFWWindowIconifyCallback + ? (GLFWWindowIconifyCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowIconifyCallback() { + super(SIGNATURE); + } + + GLFWWindowIconifyCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowIconifyCallback SetWindowIconifyCallback}. */ + public GLFWWindowIconifyCallback set(long window) { + glfwSetWindowIconifyCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowIconifyCallback { + + private final GLFWWindowIconifyCallbackI delegate; + + Container(long functionPointer, GLFWWindowIconifyCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, boolean iconified) { + delegate.invoke(window, iconified); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallbackI.java new file mode 100644 index 000000000..b21159683 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowIconifyCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowIconifyCallback SetWindowIconifyCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int iconified
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWwindowiconifyfun") +public interface GLFWWindowIconifyCallbackI extends CallbackI.V { + + String SIGNATURE = "(pi)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args) != 0 + ); + } + + /** + * Will be called when the specified window is iconified or restored. + * + * @param window the window that was iconified or restored. + * @param iconified {@link GLFW#GLFW_TRUE TRUE} if the window was iconified, or {@link GLFW#GLFW_FALSE FALSE} if it was restored + */ + void invoke(@NativeType("GLFWwindow *") long window, @NativeType("int") boolean iconified); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallback.java new file mode 100644 index 000000000..b8e93649f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallback.java @@ -0,0 +1,86 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowMaximizeCallback SetWindowMaximizeCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int maximized
+ * )
+ * + * @since version 3.3 + */ +public abstract class GLFWWindowMaximizeCallback extends Callback implements GLFWWindowMaximizeCallbackI { + + /** + * Creates a {@code GLFWWindowMaximizeCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowMaximizeCallback} + */ + public static GLFWWindowMaximizeCallback create(long functionPointer) { + GLFWWindowMaximizeCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowMaximizeCallback + ? (GLFWWindowMaximizeCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowMaximizeCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowMaximizeCallback} instance that delegates to the specified {@code GLFWWindowMaximizeCallbackI} instance. */ + public static GLFWWindowMaximizeCallback create(GLFWWindowMaximizeCallbackI instance) { + return instance instanceof GLFWWindowMaximizeCallback + ? (GLFWWindowMaximizeCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowMaximizeCallback() { + super(SIGNATURE); + } + + GLFWWindowMaximizeCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowMaximizeCallback SetWindowMaximizeCallback}. */ + public GLFWWindowMaximizeCallback set(long window) { + glfwSetWindowMaximizeCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowMaximizeCallback { + + private final GLFWWindowMaximizeCallbackI delegate; + + Container(long functionPointer, GLFWWindowMaximizeCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, boolean maximized) { + delegate.invoke(window, maximized); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallbackI.java new file mode 100644 index 000000000..a698aaf27 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowMaximizeCallbackI.java @@ -0,0 +1,50 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowMaximizeCallback SetWindowMaximizeCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int maximized
+ * )
+ * + * @since version 3.3 + */ +@FunctionalInterface +@NativeType("GLFWwindowmaximizefun") +public interface GLFWWindowMaximizeCallbackI extends CallbackI.V { + + String SIGNATURE = "(pi)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args) != 0 + ); + } + + /** + * Will be called when the specified window is maximized or restored. + * + * @param window the window that was maximized or restored. + * @param maximized {@link GLFW#GLFW_TRUE TRUE} if the window was maximized, or {@link GLFW#GLFW_FALSE FALSE} if it was restored + */ + void invoke(@NativeType("GLFWwindow *") long window, @NativeType("int") boolean maximized); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallback.java new file mode 100644 index 000000000..e4e1ee3d5 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallback.java @@ -0,0 +1,87 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowPosCallback SetWindowPosCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int xpos,
+ *     int ypos
+ * )
+ * + * @since version 3.0 + */ +public abstract class GLFWWindowPosCallback extends Callback implements GLFWWindowPosCallbackI { + + /** + * Creates a {@code GLFWWindowPosCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowPosCallback} + */ + public static GLFWWindowPosCallback create(long functionPointer) { + GLFWWindowPosCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowPosCallback + ? (GLFWWindowPosCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowPosCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowPosCallback} instance that delegates to the specified {@code GLFWWindowPosCallbackI} instance. */ + public static GLFWWindowPosCallback create(GLFWWindowPosCallbackI instance) { + return instance instanceof GLFWWindowPosCallback + ? (GLFWWindowPosCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowPosCallback() { + super(SIGNATURE); + } + + GLFWWindowPosCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowPosCallback SetWindowPosCallback}. */ + public GLFWWindowPosCallback set(long window) { + glfwSetWindowPosCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowPosCallback { + + private final GLFWWindowPosCallbackI delegate; + + Container(long functionPointer, GLFWWindowPosCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int xpos, int ypos) { + delegate.invoke(window, xpos, ypos); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallbackI.java new file mode 100644 index 000000000..a945a27d8 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowPosCallbackI.java @@ -0,0 +1,53 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowPosCallback SetWindowPosCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int xpos,
+ *     int ypos
+ * )
+ * + * @since version 3.0 + */ +@FunctionalInterface +@NativeType("GLFWwindowposfun") +public interface GLFWWindowPosCallbackI extends CallbackI.V { + + String SIGNATURE = "(pii)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when the specified window moves. + * + * @param window the window that was moved + * @param xpos the new x-coordinate, in screen coordinates, of the upper-left corner of the content area of the window + * @param ypos the new y-coordinate, in screen coordinates, of the upper-left corner of the content area of the window + */ + void invoke(@NativeType("GLFWwindow *") long window, int xpos, int ypos); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowProperties.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowProperties.java new file mode 100644 index 000000000..0596bad1f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowProperties.java @@ -0,0 +1,13 @@ +package org.lwjgl.glfw; + +import java.util.*; + +public class GLFWWindowProperties { + public int width = GLFW.mGLFWWindowWidth; + public int height = GLFW.mGLFWWindowHeight; + public int x, y; + public CharSequence title; + public boolean shouldClose, isInitialSizeCalled, isCursorEntered; + public Map inputModes = new HashMap<>(); + public Map windowAttribs = new HashMap<>(); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallback.java new file mode 100644 index 000000000..11ea1ed99 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallback.java @@ -0,0 +1,85 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowRefreshCallback SetWindowRefreshCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window
+ * )
+ * + * @since version 2.5 + */ +public abstract class GLFWWindowRefreshCallback extends Callback implements GLFWWindowRefreshCallbackI { + + /** + * Creates a {@code GLFWWindowRefreshCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowRefreshCallback} + */ + public static GLFWWindowRefreshCallback create(long functionPointer) { + GLFWWindowRefreshCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowRefreshCallback + ? (GLFWWindowRefreshCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowRefreshCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowRefreshCallback} instance that delegates to the specified {@code GLFWWindowRefreshCallbackI} instance. */ + public static GLFWWindowRefreshCallback create(GLFWWindowRefreshCallbackI instance) { + return instance instanceof GLFWWindowRefreshCallback + ? (GLFWWindowRefreshCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowRefreshCallback() { + super(SIGNATURE); + } + + GLFWWindowRefreshCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowRefreshCallback SetWindowRefreshCallback}. */ + public GLFWWindowRefreshCallback set(long window) { + glfwSetWindowRefreshCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowRefreshCallback { + + private final GLFWWindowRefreshCallbackI delegate; + + Container(long functionPointer, GLFWWindowRefreshCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window) { + delegate.invoke(window); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallbackI.java new file mode 100644 index 000000000..0fae18261 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowRefreshCallbackI.java @@ -0,0 +1,48 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowRefreshCallback SetWindowRefreshCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window
+ * )
+ * + * @since version 2.5 + */ +@FunctionalInterface +@NativeType("GLFWwindowrefreshfun") +public interface GLFWWindowRefreshCallbackI extends CallbackI.V { + + String SIGNATURE = "(p)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args) + ); + } + + /** + * Will be called when the client area of the specified window needs to be redrawn, for example if the window has been exposed after having been covered by + * another window. + * + * @param window the window whose content needs to be refreshed + */ + void invoke(@NativeType("GLFWwindow *") long window); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallback.java new file mode 100644 index 000000000..f630ab395 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallback.java @@ -0,0 +1,85 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +import static org.lwjgl.glfw.GLFW.*; + +/** + * Instances of this class may be passed to the {@link GLFW#glfwSetWindowSizeCallback SetWindowSizeCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int width,
+ *     int height
+ * )
+ */ +public abstract class GLFWWindowSizeCallback extends Callback implements GLFWWindowSizeCallbackI { + + /** + * Creates a {@code GLFWWindowSizeCallback} instance from the specified function pointer. + * + * @return the new {@code GLFWWindowSizeCallback} + */ + public static GLFWWindowSizeCallback create(long functionPointer) { + GLFWWindowSizeCallbackI instance = Callback.get(functionPointer); + return instance instanceof GLFWWindowSizeCallback + ? (GLFWWindowSizeCallback)instance + : new Container(functionPointer, instance); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code functionPointer} is {@code NULL}. */ + @Nullable + public static GLFWWindowSizeCallback createSafe(long functionPointer) { + return functionPointer == NULL ? null : create(functionPointer); + } + + /** Creates a {@code GLFWWindowSizeCallback} instance that delegates to the specified {@code GLFWWindowSizeCallbackI} instance. */ + public static GLFWWindowSizeCallback create(GLFWWindowSizeCallbackI instance) { + return instance instanceof GLFWWindowSizeCallback + ? (GLFWWindowSizeCallback)instance + : new Container(instance.address(), instance); + } + + protected GLFWWindowSizeCallback() { + super(SIGNATURE); + } + + GLFWWindowSizeCallback(long functionPointer) { + super(functionPointer); + } + + /** See {@link GLFW#glfwSetWindowSizeCallback SetWindowSizeCallback}. */ + public GLFWWindowSizeCallback set(long window) { + glfwSetWindowSizeCallback(window, this); + return this; + } + + private static final class Container extends GLFWWindowSizeCallback { + + private final GLFWWindowSizeCallbackI delegate; + + Container(long functionPointer, GLFWWindowSizeCallbackI delegate) { + super(functionPointer); + this.delegate = delegate; + } + + @Override + public void invoke(long window, int width, int height) { + delegate.invoke(window, width, height); + } + + } + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallbackI.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallbackI.java new file mode 100644 index 000000000..9e1d4f023 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFWWindowSizeCallbackI.java @@ -0,0 +1,51 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.dyncall.DynCallback.*; + +/** + * Instances of this interface may be passed to the {@link GLFW#glfwSetWindowSizeCallback SetWindowSizeCallback} method. + * + *

Type

+ * + *

+ * void (*) (
+ *     GLFWwindow *window,
+ *     int width,
+ *     int height
+ * )
+ */ +@FunctionalInterface +@NativeType("GLFWwindowsizefun") +public interface GLFWWindowSizeCallbackI extends CallbackI.V { + + String SIGNATURE = "(pii)v"; + + @Override + default String getSignature() { return SIGNATURE; } + + @Override + default void callback(long args) { + invoke( + dcbArgPointer(args), + dcbArgInt(args), + dcbArgInt(args) + ); + } + + /** + * Will be called when the specified window is resized. + * + * @param window the window that was resized + * @param width the new width, in screen coordinates, of the window + * @param height the new height, in screen coordinates, of the window + */ + void invoke(@NativeType("GLFWwindow *") long window, int width, int height); + +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/package-info.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/package-info.java new file mode 100644 index 000000000..d3c700296 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ + +/** + * Contains bindings to the GLFW library. + * + *

GLFW comes with extensive documentation, which you can read online here. The + * Frequently Asked Questions are also useful.

+ * + *

On macOS the JVM must be started with the {@code -XstartOnFirstThread} argument for GLFW to work. This is necessary because most GLFW functions must be + * called on the main thread and the Cocoa API on macOS requires that thread to be the first thread in the process. For this reason, on-screen GLFW + * windows and the GLFW event loop are incompatible with other window toolkits (such as AWT/Swing or JavaFX) on macOS. Off-screen GLFW windows can be used + * with other window toolkits, but only if the window toolkit is initialized before GLFW.

+ */ +@org.lwjgl.system.NonnullDefault +package org.lwjgl.glfw; + diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Cursor.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Cursor.java new file mode 100644 index 000000000..9604aea47 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Cursor.java @@ -0,0 +1,270 @@ +package org.lwjgl.input; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.glfw.GLFW; +import org.lwjgl.glfw.GLFWImage; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.LWJGLException; + +public class Cursor { + + /** 1 bit transparency for native cursor */ + public static final int CURSOR_ONE_BIT_TRANSPARENCY = 1; + + /** 8 bit alpha native cursor */ + public static final int CURSOR_8_BIT_ALPHA = 2; + + /** Animation native cursor */ + public static final int CURSOR_ANIMATION = 4; + + /** Elements to display */ + private final CursorElement[] cursors; + + /** Index into list of cursors */ + private int index; + + /** Flag set when the cursor has been destroyed */ + private boolean destroyed; + + /** + * Constructs a new Cursor, with the given parameters. Mouse must have been + * created before you can create Cursor objects. Cursor images are in ARGB + * format, but only one bit transparency is guaranteed to be supported. So + * to maximize portability, LWJGL applications should only create cursor + * images with 0x00 or 0xff as alpha values. The constructor will copy the + * images and delays, so there's no need to keep them around. + * + * @param width + * cursor image width + * @param height + * cursor image height + * @param xHotspot + * the x coordinate of the cursor hotspot + * @param yHotspot + * the y coordinate of the cursor hotspot + * @param numImages + * number of cursor images specified. Must be 1 if animations are + * not supported. + * @param images + * A buffer containing the images. The origin is at the lower + * left corner, like OpenGL. + * @param delays + * An int buffer of animation frame delays, if numImages is + * greater than 1, else null + * @throws LWJGLException + * if the cursor could not be created for any reason + */ + public Cursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) + throws LWJGLException { + + cursors = new CursorElement[numImages]; + + IntBuffer flippedImages = BufferUtils.createIntBuffer(images.limit()); + flipImages(width, height, numImages, images, flippedImages); + + ByteBuffer pixels = convertARGBIntBuffertoRGBAByteBuffer(width, height, flippedImages); + + for (int i = 0; i < numImages; i++) { + int size = width * height; + ByteBuffer image = BufferUtils.createByteBuffer(size); + for (int j = 0; j < size; j++) + image.put(pixels.get()); + + GLFWImage cursorImage = GLFWImage.malloc(); + cursorImage.width(width); + cursorImage.height(height); + cursorImage.pixels(image); + + long delay = (delays != null) ? delays.get(i) : 0; + long timeout = GLFW.glfwGetTimerValue(); + cursors[i] = new CursorElement(xHotspot, yHotspot, delay, timeout, cursorImage); + } + } + + private static ByteBuffer convertARGBIntBuffertoRGBAByteBuffer(int width, int height, IntBuffer imageBuffer) { + ByteBuffer pixels = BufferUtils.createByteBuffer(width * height * 4); + + for (int i = 0; i < imageBuffer.limit(); i++) { + int argbColor = imageBuffer.get(i); + + byte alpha = (byte) (argbColor >>> 24); + byte blue = (byte) (argbColor >>> 16); + byte green = (byte) (argbColor >>> 8); + byte red = (byte) argbColor; + + pixels.put(red); + pixels.put(green); + pixels.put(blue); + pixels.put(alpha); + } + + pixels.flip(); + + return pixels; + } + + /** + * Gets the minimum size of a native cursor. Can only be called if The Mouse + * is created and cursor caps includes at least CURSOR_ONE_BIT_TRANSPARANCY. + * + * @return the minimum size of a native cursor + */ + public static int getMinCursorSize() { + return 1; + } + + /** + * Gets the maximum size of a native cursor. Can only be called if the + * cursor caps includes at least {@link #CURSOR_ONE_BIT_TRANSPARENCY}. + * + * @return the maximum size of a native cursor + */ + public static int getMaxCursorSize() { + return 512; + } + + /** + * Get the capabilities of the native cursor. Return a bit mask of the + * native cursor capabilities. + *
    + *
  • CURSOR_ONE_BIT_TRANSPARENCY indicates support for + * cursors with one bit transparency.
  • + * + *
  • CURSOR_8_BIT_ALPHA indicates support for 8 bit + * alpha.
  • + * + *
  • CURSOR_ANIMATION indicates support for cursor + * animations.
  • + *
+ * + * @return A bit mask with native cursor capabilities. + */ + public static int getCapabilities() { + return CURSOR_8_BIT_ALPHA | CURSOR_ANIMATION; + } + + /** + * Flips the images so they're oriented according to OpenGL + * + * @param width + * Width of image + * @param height + * Height of images + * @param numImages + * How many images to flip + * @param images + * Source images + * @param images_copy + * Destination images + */ + private static void flipImages(int width, int height, int numImages, IntBuffer images, IntBuffer images_copy) { + for (int i = 0; i < numImages; i++) { + int start_index = i * width * height; + flipImage(width, height, start_index, images, images_copy); + } + } + + /** + * @param width + * Width of image + * @param height + * Height of images + * @param start_index + * index into source buffer to copy to + * @param images + * Source images + * @param images_copy + * Destination images + */ + private static void flipImage(int width, int height, int start_index, IntBuffer images, IntBuffer images_copy) { + for (int y = 0; y < height >> 1; y++) { + int index_y_1 = y * width + start_index; + int index_y_2 = (height - y - 1) * width + start_index; + for (int x = 0; x < width; x++) { + int index1 = index_y_1 + x; + int index2 = index_y_2 + x; + int temp_pixel = images.get(index1 + images.position()); + images_copy.put(index1, images.get(index2 + images.position())); + images_copy.put(index2, temp_pixel); + } + } + } + + /** + * Gets the native handle associated with the cursor object. + */ + long getHandle() { + checkValid(); + return cursors[index].cursorHandle; + } + + /** + * Checks whether the cursor is still active and not yet destroyed. + */ + private void checkValid() { + if (destroyed) + throw new IllegalStateException("The cursor is already destroyed"); + } + + /** + * Destroy the current cursor. If the cursor is current, the current native + * cursor is set to null (the default OS cursor) + */ + public void destroy() { + for (CursorElement cursor : cursors) + GLFW.glfwDestroyCursor(cursor.cursorHandle); + + destroyed = true; + } + + /** + * Sets the timout property to the time it should be changed + */ + + protected void setTimeout() { + checkValid(); + cursors[index].timeout = GLFW.glfwGetTimerValue() + cursors[index].delay; + } + + /** + * Determines whether this cursor has timed out + * + * @return true if the this cursor has timed out, false if not + */ + + protected boolean hasTimedOut() { + checkValid(); + return cursors.length > 1 && cursors[index].timeout < GLFW.glfwGetTimerValue(); + } + + /** + * Changes to the next cursor + */ + protected void nextCursor() { + checkValid(); + index = ++index % cursors.length; + } + + /** + * A single cursor element, used when animating + */ + private static class CursorElement { + + final long cursorHandle; + long delay; + long timeout; + + CursorElement(int xHotspot, int yHotspot, long delay, long timeout, GLFWImage image) { + this.delay = delay; + this.timeout = timeout; + + this.cursorHandle = GLFW.glfwCreateCursor(image, xHotspot, yHotspot); + if (cursorHandle == MemoryUtil.NULL) + throw new RuntimeException("Error creating GLFW cursor"); + } + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/EventQueue.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/EventQueue.java new file mode 100644 index 000000000..c498facfb --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/EventQueue.java @@ -0,0 +1,61 @@ +package org.lwjgl.input; + +/** + * Internal utility class to keep track of event positions in an array. When the + * array is full the position will wrap to the beginning. + */ +class EventQueue { + + private int maxEvents = 32; + private int currentEventPos = -1; + private int nextEventPos = 0; + + EventQueue(int maxEvents) { + this.maxEvents = maxEvents; + } + + /** + * add event to the queue + */ + void add() { + nextEventPos++; // increment next event position + if (nextEventPos == maxEvents) + nextEventPos = 0; // wrap next event position + + if (nextEventPos == currentEventPos) { + currentEventPos++; // skip oldest event is queue full + if (currentEventPos == maxEvents) + currentEventPos = 0; // wrap current event position + } + } + + /** + * Increment the event queue + * + * @return - true if there is an event available + */ + boolean next() { + if (currentEventPos == nextEventPos - 1) + return false; + if (nextEventPos == 0 && currentEventPos == maxEvents - 1) + return false; + + currentEventPos++; // increment current event position + if (currentEventPos == maxEvents) + currentEventPos = 0; // wrap current event position + + return true; + } + + int getMaxEvents() { + return maxEvents; + } + + int getCurrentPos() { + return currentEventPos; + } + + int getNextPos() { + return nextEventPos; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/KeyCodes.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/KeyCodes.java new file mode 100644 index 000000000..55fa70649 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/KeyCodes.java @@ -0,0 +1,321 @@ +package org.lwjgl.input; + +import org.lwjgl.glfw.GLFW; + +public class KeyCodes { + + public static int toLwjglKey(int glfwKeyCode) { + + switch(glfwKeyCode) { + + case GLFW.GLFW_KEY_ESCAPE : return Keyboard.KEY_ESCAPE; + case GLFW.GLFW_KEY_BACKSPACE: return Keyboard.KEY_BACK; + case GLFW.GLFW_KEY_TAB : return Keyboard.KEY_TAB; + case GLFW.GLFW_KEY_ENTER : return Keyboard.KEY_RETURN; + case GLFW.GLFW_KEY_SPACE : return Keyboard.KEY_SPACE; + + case GLFW.GLFW_KEY_LEFT_CONTROL : return Keyboard.KEY_LCONTROL; + case GLFW.GLFW_KEY_LEFT_SHIFT : return Keyboard.KEY_LSHIFT; + case GLFW.GLFW_KEY_LEFT_ALT : return Keyboard.KEY_LMENU; + case GLFW.GLFW_KEY_LEFT_SUPER : return Keyboard.KEY_LMETA; + + case GLFW.GLFW_KEY_RIGHT_CONTROL: return Keyboard.KEY_RCONTROL; + case GLFW.GLFW_KEY_RIGHT_SHIFT : return Keyboard.KEY_RSHIFT; + case GLFW.GLFW_KEY_RIGHT_ALT : return Keyboard.KEY_RMENU; + case GLFW.GLFW_KEY_RIGHT_SUPER : return Keyboard.KEY_RMETA; + + case GLFW.GLFW_KEY_1 : return Keyboard.KEY_1; + case GLFW.GLFW_KEY_2 : return Keyboard.KEY_2; + case GLFW.GLFW_KEY_3 : return Keyboard.KEY_3; + case GLFW.GLFW_KEY_4 : return Keyboard.KEY_4; + case GLFW.GLFW_KEY_5 : return Keyboard.KEY_5; + case GLFW.GLFW_KEY_6 : return Keyboard.KEY_6; + case GLFW.GLFW_KEY_7 : return Keyboard.KEY_7; + case GLFW.GLFW_KEY_8 : return Keyboard.KEY_8; + case GLFW.GLFW_KEY_9 : return Keyboard.KEY_9; + case GLFW.GLFW_KEY_0 : return Keyboard.KEY_0; + + case GLFW.GLFW_KEY_A : return Keyboard.KEY_A; + case GLFW.GLFW_KEY_B : return Keyboard.KEY_B; + case GLFW.GLFW_KEY_C : return Keyboard.KEY_C; + case GLFW.GLFW_KEY_D : return Keyboard.KEY_D; + case GLFW.GLFW_KEY_E : return Keyboard.KEY_E; + case GLFW.GLFW_KEY_F : return Keyboard.KEY_F; + case GLFW.GLFW_KEY_G : return Keyboard.KEY_G; + case GLFW.GLFW_KEY_H : return Keyboard.KEY_H; + case GLFW.GLFW_KEY_I : return Keyboard.KEY_I; + case GLFW.GLFW_KEY_J : return Keyboard.KEY_J; + case GLFW.GLFW_KEY_K : return Keyboard.KEY_K; + case GLFW.GLFW_KEY_L : return Keyboard.KEY_L; + case GLFW.GLFW_KEY_M : return Keyboard.KEY_M; + case GLFW.GLFW_KEY_N : return Keyboard.KEY_N; + case GLFW.GLFW_KEY_O : return Keyboard.KEY_O; + case GLFW.GLFW_KEY_P : return Keyboard.KEY_P; + case GLFW.GLFW_KEY_Q : return Keyboard.KEY_Q; + case GLFW.GLFW_KEY_R : return Keyboard.KEY_R; + case GLFW.GLFW_KEY_S : return Keyboard.KEY_S; + case GLFW.GLFW_KEY_T : return Keyboard.KEY_T; + case GLFW.GLFW_KEY_U : return Keyboard.KEY_U; + case GLFW.GLFW_KEY_V : return Keyboard.KEY_V; + case GLFW.GLFW_KEY_W : return Keyboard.KEY_W; + case GLFW.GLFW_KEY_X : return Keyboard.KEY_X; + case GLFW.GLFW_KEY_Y : return Keyboard.KEY_Y; + case GLFW.GLFW_KEY_Z : return Keyboard.KEY_Z; + + case GLFW.GLFW_KEY_UP : return Keyboard.KEY_UP; + case GLFW.GLFW_KEY_DOWN : return Keyboard.KEY_DOWN; + case GLFW.GLFW_KEY_LEFT : return Keyboard.KEY_LEFT; + case GLFW.GLFW_KEY_RIGHT : return Keyboard.KEY_RIGHT; + + case GLFW.GLFW_KEY_INSERT : return Keyboard.KEY_INSERT; + case GLFW.GLFW_KEY_DELETE : return Keyboard.KEY_DELETE; + case GLFW.GLFW_KEY_HOME : return Keyboard.KEY_HOME; + case GLFW.GLFW_KEY_END : return Keyboard.KEY_END; + case GLFW.GLFW_KEY_PAGE_UP : return Keyboard.KEY_PRIOR; + case GLFW.GLFW_KEY_PAGE_DOWN: return Keyboard.KEY_NEXT; + + case GLFW.GLFW_KEY_F1 : return Keyboard.KEY_F1; + case GLFW.GLFW_KEY_F2 : return Keyboard.KEY_F2; + case GLFW.GLFW_KEY_F3 : return Keyboard.KEY_F3; + case GLFW.GLFW_KEY_F4 : return Keyboard.KEY_F4; + case GLFW.GLFW_KEY_F5 : return Keyboard.KEY_F5; + case GLFW.GLFW_KEY_F6 : return Keyboard.KEY_F6; + case GLFW.GLFW_KEY_F7 : return Keyboard.KEY_F7; + case GLFW.GLFW_KEY_F8 : return Keyboard.KEY_F8; + case GLFW.GLFW_KEY_F9 : return Keyboard.KEY_F9; + case GLFW.GLFW_KEY_F10 : return Keyboard.KEY_F10; + case GLFW.GLFW_KEY_F11 : return Keyboard.KEY_F11; + case GLFW.GLFW_KEY_F12 : return Keyboard.KEY_F12; + case GLFW.GLFW_KEY_F13 : return Keyboard.KEY_F13; + case GLFW.GLFW_KEY_F14 : return Keyboard.KEY_F14; + case GLFW.GLFW_KEY_F15 : return Keyboard.KEY_F15; + case GLFW.GLFW_KEY_F16 : return Keyboard.KEY_F16; + case GLFW.GLFW_KEY_F17 : return Keyboard.KEY_F17; + case GLFW.GLFW_KEY_F18 : return Keyboard.KEY_F18; + case GLFW.GLFW_KEY_F19 : return Keyboard.KEY_F19; + + case GLFW.GLFW_KEY_KP_1 : return Keyboard.KEY_NUMPAD1; + case GLFW.GLFW_KEY_KP_2 : return Keyboard.KEY_NUMPAD2; + case GLFW.GLFW_KEY_KP_3 : return Keyboard.KEY_NUMPAD3; + case GLFW.GLFW_KEY_KP_4 : return Keyboard.KEY_NUMPAD4; + case GLFW.GLFW_KEY_KP_5 : return Keyboard.KEY_NUMPAD5; + case GLFW.GLFW_KEY_KP_6 : return Keyboard.KEY_NUMPAD6; + case GLFW.GLFW_KEY_KP_7 : return Keyboard.KEY_NUMPAD7; + case GLFW.GLFW_KEY_KP_8 : return Keyboard.KEY_NUMPAD8; + case GLFW.GLFW_KEY_KP_9 : return Keyboard.KEY_NUMPAD9; + case GLFW.GLFW_KEY_KP_0 : return Keyboard.KEY_NUMPAD0; + + case GLFW.GLFW_KEY_KP_ADD : return Keyboard.KEY_ADD; + case GLFW.GLFW_KEY_KP_SUBTRACT : return Keyboard.KEY_SUBTRACT; + case GLFW.GLFW_KEY_KP_MULTIPLY : return Keyboard.KEY_MULTIPLY; + case GLFW.GLFW_KEY_KP_DIVIDE: return Keyboard.KEY_DIVIDE; + case GLFW.GLFW_KEY_KP_DECIMAL : return Keyboard.KEY_DECIMAL; + case GLFW.GLFW_KEY_KP_EQUAL : return Keyboard.KEY_NUMPADEQUALS; + case GLFW.GLFW_KEY_KP_ENTER : return Keyboard.KEY_NUMPADENTER; + case GLFW.GLFW_KEY_NUM_LOCK : return Keyboard.KEY_NUMLOCK; + + case GLFW.GLFW_KEY_SEMICOLON: return Keyboard.KEY_SEMICOLON; + case GLFW.GLFW_KEY_BACKSLASH: return Keyboard.KEY_BACKSLASH; + case GLFW.GLFW_KEY_COMMA : return Keyboard.KEY_COMMA; + case GLFW.GLFW_KEY_PERIOD : return Keyboard.KEY_PERIOD; + case GLFW.GLFW_KEY_SLASH : return Keyboard.KEY_SLASH; + case GLFW.GLFW_KEY_GRAVE_ACCENT : return Keyboard.KEY_GRAVE; + + case GLFW.GLFW_KEY_CAPS_LOCK: return Keyboard.KEY_CAPITAL; + case GLFW.GLFW_KEY_SCROLL_LOCK : return Keyboard.KEY_SCROLL; + + case GLFW.GLFW_KEY_WORLD_1 : return Keyboard.KEY_CIRCUMFLEX; // TODO not sure if correct + case GLFW.GLFW_KEY_PAUSE : return Keyboard.KEY_PAUSE; + + case GLFW.GLFW_KEY_MINUS : return Keyboard.KEY_MINUS; + case GLFW.GLFW_KEY_EQUAL : return Keyboard.KEY_EQUALS; + case GLFW.GLFW_KEY_LEFT_BRACKET : return Keyboard.KEY_LBRACKET; + case GLFW.GLFW_KEY_RIGHT_BRACKET: return Keyboard.KEY_RBRACKET; + case GLFW.GLFW_KEY_APOSTROPHE : return Keyboard.KEY_APOSTROPHE; +// public static final int KEY_AT = 0x91; /* (NEC PC98) */ +// public static final int KEY_COLON = 0x92; /* (NEC PC98) */ +// public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */ + +// public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */ +// public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */ +// public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */ +// public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */ +// public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */ +// public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */ +// public static final int KEY_STOP = 0x95; /* (NEC PC98) */ +// public static final int KEY_AX = 0x96; /* (Japan AX) */ +// public static final int KEY_UNLABELED = 0x97; /* (J3100) */ +// public static final int KEY_SECTION = 0xA7; /* Section symbol (Mac) */ +// public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */ +// public static final int KEY_SYSRQ = 0xB7; +// public static final int KEY_FUNCTION = 0xC4; /* Function (Mac) */ +// public static final int KEY_CLEAR = 0xDA; /* Clear key (Mac) */ + +// public static final int KEY_APPS = 0xDD; /* AppMenu key */ +// public static final int KEY_POWER = 0xDE; +// public static final int KEY_SLEEP = 0xDF; + + default: System.out.println("UNKNOWN GLFW KEY CODE: " + glfwKeyCode); + return Keyboard.KEY_NONE; + } + } + + public static int toGlfwKey(int lwjglKeyCode) { + + switch(lwjglKeyCode) { + + case Keyboard.KEY_ESCAPE : return GLFW.GLFW_KEY_ESCAPE; + case Keyboard.KEY_BACK : return GLFW.GLFW_KEY_BACKSPACE; + case Keyboard.KEY_TAB : return GLFW.GLFW_KEY_TAB; + case Keyboard.KEY_RETURN : return GLFW.GLFW_KEY_ENTER; + case Keyboard.KEY_SPACE : return GLFW.GLFW_KEY_SPACE; + + case Keyboard.KEY_LCONTROL : return GLFW.GLFW_KEY_LEFT_CONTROL; + case Keyboard.KEY_LSHIFT : return GLFW.GLFW_KEY_LEFT_SHIFT; + case Keyboard.KEY_LMENU : return GLFW.GLFW_KEY_LEFT_ALT; + case Keyboard.KEY_LMETA : return GLFW.GLFW_KEY_LEFT_SUPER; + + case Keyboard.KEY_RCONTROL : return GLFW.GLFW_KEY_RIGHT_CONTROL; + case Keyboard.KEY_RSHIFT : return GLFW.GLFW_KEY_RIGHT_SHIFT; + case Keyboard.KEY_RMENU : return GLFW.GLFW_KEY_RIGHT_ALT; + case Keyboard.KEY_RMETA : return GLFW.GLFW_KEY_RIGHT_SUPER; + + case Keyboard.KEY_1 : return GLFW.GLFW_KEY_1; + case Keyboard.KEY_2 : return GLFW.GLFW_KEY_2; + case Keyboard.KEY_3 : return GLFW.GLFW_KEY_3; + case Keyboard.KEY_4 : return GLFW.GLFW_KEY_4; + case Keyboard.KEY_5 : return GLFW.GLFW_KEY_5; + case Keyboard.KEY_6 : return GLFW.GLFW_KEY_6; + case Keyboard.KEY_7 : return GLFW.GLFW_KEY_7; + case Keyboard.KEY_8 : return GLFW.GLFW_KEY_8; + case Keyboard.KEY_9 : return GLFW.GLFW_KEY_9; + case Keyboard.KEY_0 : return GLFW.GLFW_KEY_0; + + case Keyboard.KEY_A : return GLFW.GLFW_KEY_A; + case Keyboard.KEY_B : return GLFW.GLFW_KEY_B; + case Keyboard.KEY_C : return GLFW.GLFW_KEY_C; + case Keyboard.KEY_D : return GLFW.GLFW_KEY_D; + case Keyboard.KEY_E : return GLFW.GLFW_KEY_E; + case Keyboard.KEY_F : return GLFW.GLFW_KEY_F; + case Keyboard.KEY_G : return GLFW.GLFW_KEY_G; + case Keyboard.KEY_H : return GLFW.GLFW_KEY_H; + case Keyboard.KEY_I : return GLFW.GLFW_KEY_I; + case Keyboard.KEY_J : return GLFW.GLFW_KEY_J; + case Keyboard.KEY_K : return GLFW.GLFW_KEY_K; + case Keyboard.KEY_L : return GLFW.GLFW_KEY_L; + case Keyboard.KEY_M : return GLFW.GLFW_KEY_M; + case Keyboard.KEY_N : return GLFW.GLFW_KEY_N; + case Keyboard.KEY_O : return GLFW.GLFW_KEY_O; + case Keyboard.KEY_P : return GLFW.GLFW_KEY_P; + case Keyboard.KEY_Q : return GLFW.GLFW_KEY_Q; + case Keyboard.KEY_R : return GLFW.GLFW_KEY_R; + case Keyboard.KEY_S : return GLFW.GLFW_KEY_S; + case Keyboard.KEY_T : return GLFW.GLFW_KEY_T; + case Keyboard.KEY_U : return GLFW.GLFW_KEY_U; + case Keyboard.KEY_V : return GLFW.GLFW_KEY_V; + case Keyboard.KEY_W : return GLFW.GLFW_KEY_W; + case Keyboard.KEY_X : return GLFW.GLFW_KEY_X; + case Keyboard.KEY_Y : return GLFW.GLFW_KEY_Y; + case Keyboard.KEY_Z : return GLFW.GLFW_KEY_Z; + + case Keyboard.KEY_UP : return GLFW.GLFW_KEY_UP; + case Keyboard.KEY_DOWN : return GLFW.GLFW_KEY_DOWN; + case Keyboard.KEY_LEFT : return GLFW.GLFW_KEY_LEFT; + case Keyboard.KEY_RIGHT : return GLFW.GLFW_KEY_RIGHT; + + case Keyboard.KEY_INSERT : return GLFW.GLFW_KEY_INSERT; + case Keyboard.KEY_DELETE : return GLFW.GLFW_KEY_DELETE; + case Keyboard.KEY_HOME : return GLFW.GLFW_KEY_HOME; + case Keyboard.KEY_END : return GLFW.GLFW_KEY_END; + case Keyboard.KEY_PRIOR : return GLFW.GLFW_KEY_PAGE_UP; + case Keyboard.KEY_NEXT : return GLFW.GLFW_KEY_PAGE_DOWN; + + case Keyboard.KEY_F1 : return GLFW.GLFW_KEY_F1; + case Keyboard.KEY_F2 : return GLFW.GLFW_KEY_F2; + case Keyboard.KEY_F3 : return GLFW.GLFW_KEY_F3; + case Keyboard.KEY_F4 : return GLFW.GLFW_KEY_F4; + case Keyboard.KEY_F5 : return GLFW.GLFW_KEY_F5; + case Keyboard.KEY_F6 : return GLFW.GLFW_KEY_F6; + case Keyboard.KEY_F7 : return GLFW.GLFW_KEY_F7; + case Keyboard.KEY_F8 : return GLFW.GLFW_KEY_F8; + case Keyboard.KEY_F9 : return GLFW.GLFW_KEY_F9; + case Keyboard.KEY_F10 : return GLFW.GLFW_KEY_F10; + case Keyboard.KEY_F11 : return GLFW.GLFW_KEY_F11; + case Keyboard.KEY_F12 : return GLFW.GLFW_KEY_F12; + case Keyboard.KEY_F13 : return GLFW.GLFW_KEY_F13; + case Keyboard.KEY_F14 : return GLFW.GLFW_KEY_F14; + case Keyboard.KEY_F15 : return GLFW.GLFW_KEY_F15; + case Keyboard.KEY_F16 : return GLFW.GLFW_KEY_F16; + case Keyboard.KEY_F17 : return GLFW.GLFW_KEY_F17; + case Keyboard.KEY_F18 : return GLFW.GLFW_KEY_F18; + case Keyboard.KEY_F19 : return GLFW.GLFW_KEY_F19; + + case Keyboard.KEY_NUMPAD1 : return GLFW.GLFW_KEY_KP_1; + case Keyboard.KEY_NUMPAD2 : return GLFW.GLFW_KEY_KP_2; + case Keyboard.KEY_NUMPAD3 : return GLFW.GLFW_KEY_KP_3; + case Keyboard.KEY_NUMPAD4 : return GLFW.GLFW_KEY_KP_4; + case Keyboard.KEY_NUMPAD5 : return GLFW.GLFW_KEY_KP_5; + case Keyboard.KEY_NUMPAD6 : return GLFW.GLFW_KEY_KP_6; + case Keyboard.KEY_NUMPAD7 : return GLFW.GLFW_KEY_KP_7; + case Keyboard.KEY_NUMPAD8 : return GLFW.GLFW_KEY_KP_8; + case Keyboard.KEY_NUMPAD9 : return GLFW.GLFW_KEY_KP_9; + case Keyboard.KEY_NUMPAD0 : return GLFW.GLFW_KEY_KP_0; + + case Keyboard.KEY_ADD : return GLFW.GLFW_KEY_KP_ADD; + case Keyboard.KEY_SUBTRACT : return GLFW.GLFW_KEY_KP_SUBTRACT; + case Keyboard.KEY_MULTIPLY : return GLFW.GLFW_KEY_KP_MULTIPLY; + case Keyboard.KEY_DIVIDE : return GLFW.GLFW_KEY_KP_DIVIDE; + case Keyboard.KEY_DECIMAL : return GLFW.GLFW_KEY_KP_DECIMAL; + case Keyboard.KEY_NUMPADEQUALS : return GLFW.GLFW_KEY_KP_EQUAL; + case Keyboard.KEY_NUMPADENTER : return GLFW.GLFW_KEY_KP_ENTER; + case Keyboard.KEY_NUMLOCK : return GLFW.GLFW_KEY_NUM_LOCK; + + case Keyboard.KEY_SEMICOLON : return GLFW.GLFW_KEY_SEMICOLON; + case Keyboard.KEY_BACKSLASH : return GLFW.GLFW_KEY_BACKSLASH; + case Keyboard.KEY_COMMA : return GLFW.GLFW_KEY_COMMA; + case Keyboard.KEY_PERIOD : return GLFW.GLFW_KEY_PERIOD; + case Keyboard.KEY_SLASH : return GLFW.GLFW_KEY_SLASH; + case Keyboard.KEY_GRAVE : return GLFW.GLFW_KEY_GRAVE_ACCENT; + + case Keyboard.KEY_CAPITAL : return GLFW.GLFW_KEY_CAPS_LOCK; + case Keyboard.KEY_SCROLL : return GLFW.GLFW_KEY_SCROLL_LOCK; + + case Keyboard.KEY_PAUSE : return GLFW.GLFW_KEY_PAUSE; + case Keyboard.KEY_CIRCUMFLEX: return GLFW.GLFW_KEY_WORLD_1; // TODO not sure if correct + + case Keyboard.KEY_MINUS : return GLFW.GLFW_KEY_MINUS; + case Keyboard.KEY_EQUALS : return GLFW.GLFW_KEY_EQUAL; + case Keyboard.KEY_LBRACKET : return GLFW.GLFW_KEY_LEFT_BRACKET; + case Keyboard.KEY_RBRACKET : return GLFW.GLFW_KEY_RIGHT_BRACKET; + case Keyboard.KEY_APOSTROPHE: return GLFW.GLFW_KEY_APOSTROPHE; +// public static final int KEY_AT = 0x91; /* (NEC PC98) */ +// public static final int KEY_COLON = 0x92; /* (NEC PC98) */ +// public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */ + +// public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */ +// public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */ +// public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */ +// public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */ + +// public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */ +// public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */ +// public static final int KEY_STOP = 0x95; /* (NEC PC98) */ +// public static final int KEY_AX = 0x96; /* (Japan AX) */ +// public static final int KEY_UNLABELED = 0x97; /* (J3100) */ +// public static final int KEY_SECTION = 0xA7; /* Section symbol (Mac) */ +// public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */ +// public static final int KEY_SYSRQ = 0xB7; +// public static final int KEY_FUNCTION = 0xC4; /* Function (Mac) */ + +// public static final int KEY_CLEAR = 0xDA; /* Clear key (Mac) */ + +// public static final int KEY_APPS = 0xDD; /* AppMenu key */ +// public static final int KEY_POWER = 0xDE; +// public static final int KEY_SLEEP = 0xDF; + + default: System.out.println("UNKNOWN LWJGL KEY CODE: " + lwjglKeyCode); + return GLFW.GLFW_KEY_UNKNOWN; + } + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Keyboard.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Keyboard.java new file mode 100644 index 000000000..5b2b57c09 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Keyboard.java @@ -0,0 +1,309 @@ +package org.lwjgl.input; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +import org.lwjgl.glfw.GLFW; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; +import org.lwjgl.opengl.Display; + +public class Keyboard { + + /** + * The special character meaning that no + * character was translated for the event. + */ + public static final int CHAR_NONE = '\0'; + + /** + * The special keycode meaning that only the + * translated character is valid. + */ + public static final int KEY_NONE = 0x00; + + public static final int KEY_ESCAPE = 0x01; + public static final int KEY_1 = 0x02; + public static final int KEY_2 = 0x03; + public static final int KEY_3 = 0x04; + public static final int KEY_4 = 0x05; + public static final int KEY_5 = 0x06; + public static final int KEY_6 = 0x07; + public static final int KEY_7 = 0x08; + public static final int KEY_8 = 0x09; + public static final int KEY_9 = 0x0A; + public static final int KEY_0 = 0x0B; + public static final int KEY_MINUS = 0x0C; /* - on main keyboard */ + public static final int KEY_EQUALS = 0x0D; + public static final int KEY_BACK = 0x0E; /* backspace */ + public static final int KEY_TAB = 0x0F; + public static final int KEY_Q = 0x10; + public static final int KEY_W = 0x11; + public static final int KEY_E = 0x12; + public static final int KEY_R = 0x13; + public static final int KEY_T = 0x14; + public static final int KEY_Y = 0x15; + public static final int KEY_U = 0x16; + public static final int KEY_I = 0x17; + public static final int KEY_O = 0x18; + public static final int KEY_P = 0x19; + public static final int KEY_LBRACKET = 0x1A; + public static final int KEY_RBRACKET = 0x1B; + public static final int KEY_RETURN = 0x1C; /* Enter on main keyboard */ + public static final int KEY_LCONTROL = 0x1D; + public static final int KEY_A = 0x1E; + public static final int KEY_S = 0x1F; + public static final int KEY_D = 0x20; + public static final int KEY_F = 0x21; + public static final int KEY_G = 0x22; + public static final int KEY_H = 0x23; + public static final int KEY_J = 0x24; + public static final int KEY_K = 0x25; + public static final int KEY_L = 0x26; + public static final int KEY_SEMICOLON = 0x27; + public static final int KEY_APOSTROPHE = 0x28; + public static final int KEY_GRAVE = 0x29; /* accent grave */ + public static final int KEY_LSHIFT = 0x2A; + public static final int KEY_BACKSLASH = 0x2B; + public static final int KEY_Z = 0x2C; + public static final int KEY_X = 0x2D; + public static final int KEY_C = 0x2E; + public static final int KEY_V = 0x2F; + public static final int KEY_B = 0x30; + public static final int KEY_N = 0x31; + public static final int KEY_M = 0x32; + public static final int KEY_COMMA = 0x33; + public static final int KEY_PERIOD = 0x34; /* . on main keyboard */ + public static final int KEY_SLASH = 0x35; /* / on main keyboard */ + public static final int KEY_RSHIFT = 0x36; + public static final int KEY_MULTIPLY = 0x37; /* * on numeric keypad */ + public static final int KEY_LMENU = 0x38; /* left Alt */ + public static final int KEY_SPACE = 0x39; + public static final int KEY_CAPITAL = 0x3A; + public static final int KEY_F1 = 0x3B; + public static final int KEY_F2 = 0x3C; + public static final int KEY_F3 = 0x3D; + public static final int KEY_F4 = 0x3E; + public static final int KEY_F5 = 0x3F; + public static final int KEY_F6 = 0x40; + public static final int KEY_F7 = 0x41; + public static final int KEY_F8 = 0x42; + public static final int KEY_F9 = 0x43; + public static final int KEY_F10 = 0x44; + public static final int KEY_NUMLOCK = 0x45; + public static final int KEY_SCROLL = 0x46; /* Scroll Lock */ + public static final int KEY_NUMPAD7 = 0x47; + public static final int KEY_NUMPAD8 = 0x48; + public static final int KEY_NUMPAD9 = 0x49; + public static final int KEY_SUBTRACT = 0x4A; /* - on numeric keypad */ + public static final int KEY_NUMPAD4 = 0x4B; + public static final int KEY_NUMPAD5 = 0x4C; + public static final int KEY_NUMPAD6 = 0x4D; + public static final int KEY_ADD = 0x4E; /* + on numeric keypad */ + public static final int KEY_NUMPAD1 = 0x4F; + public static final int KEY_NUMPAD2 = 0x50; + public static final int KEY_NUMPAD3 = 0x51; + public static final int KEY_NUMPAD0 = 0x52; + public static final int KEY_DECIMAL = 0x53; /* . on numeric keypad */ + public static final int KEY_F11 = 0x57; + public static final int KEY_F12 = 0x58; + public static final int KEY_F13 = 0x64; /* (NEC PC98) */ + public static final int KEY_F14 = 0x65; /* (NEC PC98) */ + public static final int KEY_F15 = 0x66; /* (NEC PC98) */ + public static final int KEY_F16 = 0x67; /* Extended Function keys - (Mac) */ + public static final int KEY_F17 = 0x68; + public static final int KEY_F18 = 0x69; + public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */ + public static final int KEY_F19 = 0x71; /* Extended Function keys - (Mac) */ + public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */ + public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */ + public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */ + public static final int KEY_NUMPADEQUALS = 0x8D; /* = on numeric keypad (NEC PC98) */ + public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */ + public static final int KEY_AT = 0x91; /* (NEC PC98) */ + public static final int KEY_COLON = 0x92; /* (NEC PC98) */ + public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */ + public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */ + public static final int KEY_STOP = 0x95; /* (NEC PC98) */ + public static final int KEY_AX = 0x96; /* (Japan AX) */ + public static final int KEY_UNLABELED = 0x97; /* (J3100) */ + public static final int KEY_NUMPADENTER = 0x9C; /* Enter on numeric keypad */ + public static final int KEY_RCONTROL = 0x9D; + public static final int KEY_SECTION = 0xA7; /* Section symbol (Mac) */ + public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */ + public static final int KEY_DIVIDE = 0xB5; /* / on numeric keypad */ + public static final int KEY_SYSRQ = 0xB7; + public static final int KEY_RMENU = 0xB8; /* right Alt */ + public static final int KEY_FUNCTION = 0xC4; /* Function (Mac) */ + public static final int KEY_PAUSE = 0xC5; /* Pause */ + public static final int KEY_HOME = 0xC7; /* Home on arrow keypad */ + public static final int KEY_UP = 0xC8; /* UpArrow on arrow keypad */ + public static final int KEY_PRIOR = 0xC9; /* PgUp on arrow keypad */ + public static final int KEY_LEFT = 0xCB; /* LeftArrow on arrow keypad */ + public static final int KEY_RIGHT = 0xCD; /* RightArrow on arrow keypad */ + public static final int KEY_END = 0xCF; /* End on arrow keypad */ + public static final int KEY_DOWN = 0xD0; /* DownArrow on arrow keypad */ + public static final int KEY_NEXT = 0xD1; /* PgDn on arrow keypad */ + public static final int KEY_INSERT = 0xD2; /* Insert on arrow keypad */ + public static final int KEY_DELETE = 0xD3; /* Delete on arrow keypad */ + public static final int KEY_CLEAR = 0xDA; /* Clear key (Mac) */ + public static final int KEY_LMETA = 0xDB; /* Left Windows/Option key */ + public static final int KEY_LWIN = KEY_LMETA; /* Left Windows key */ + public static final int KEY_RMETA = 0xDC; /* Right Windows/Option key */ + public static final int KEY_RWIN = KEY_RMETA; /* Right Windows key */ + public static final int KEY_APPS = 0xDD; /* AppMenu key */ + public static final int KEY_POWER = 0xDE; + public static final int KEY_SLEEP = 0xDF; + + private static EventQueue queue = new EventQueue(32); + // private static int maxEvents = 32; + + // private static int eventCount = 0; + // private static int currentEventPos = -1; + // private static int nextEventPos = 0; + + private static int[] keyEvents = new int[queue.getMaxEvents()]; + private static boolean[] keyEventStates = new boolean[queue.getMaxEvents()]; + private static long[] nanoTimeEvents = new long[queue.getMaxEvents()]; + private static char[] keyEventChars = new char[256]; + + private static boolean repeatEvents = false; + private static int latestEventKey = 0; + + public static final int KEYBOARD_SIZE = 256; + + private static final String[] keyName = new String[KEYBOARD_SIZE]; + private static final Map keyMap = new HashMap(253); + + static { + // Use reflection to find out key names + Field[] fields = Keyboard.class.getFields(); + try { + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()) + && Modifier.isFinal(field.getModifiers()) && field.getType().equals(int.class) + && field.getName().startsWith("KEY_") && !field.getName().endsWith( + "WIN")) { /* Don't use deprecated names */ + + int key = field.getInt(null); + String name = field.getName().substring(4); + keyName[key] = name; + keyMap.put(name, key); + } + + } + } catch (Exception e) { + } + + } + + public static void addKeyEvent(int key, int status) { + // eventCount++; + // if (eventCount > maxEvents) eventCount = maxEvents; + + switch (status) { + case GLFW.GLFW_REPEAT: + if (!repeatEvents) + break; + case GLFW.GLFW_RELEASE: + case GLFW.GLFW_PRESS: + keyEvents[queue.getNextPos()] = KeyCodes.toLwjglKey(key); + keyEventStates[queue.getNextPos()] = status == GLFW.GLFW_PRESS || status == GLFW.GLFW_REPEAT; + + nanoTimeEvents[queue.getNextPos()] = Sys.getNanoTime(); + + queue.add(); + } + /* + * nextEventPos++; if (nextEventPos == maxEvents) nextEventPos = 0; + * + * if (currentEventPos == nextEventPos) currentEventPos++; if + * (currentEventPos == maxEvents) currentEventPos = 0; + */ + } + + public static void addCharEvent(int key, char c) { + int index = KeyCodes.toLwjglKey(key); + keyEventChars[index] = c; + } + + public static boolean areRepeatEventsEnabled() { + return false; + } + + public static void create() throws LWJGLException { + + } + + public static boolean isKeyDown(int key) { + int k = GLFW.glfwGetKey(Display.getWindow(), KeyCodes.toGlfwKey(key)); + + return k == GLFW.GLFW_PRESS || k == GLFW.GLFW_REPEAT; + } + + public static void poll() { + // TODO + } + + public static void enableRepeatEvents(boolean enable) { + // TODO + // System.out.println("TODO: Implement + // Keyboad.enableRepeatEvents(boolean)"); + repeatEvents = enable; + } + + public static boolean isRepeatEvent() { + // TODO + return repeatEvents; + } + + public static boolean next() { + return queue.next(); + /* + * if (eventCount == 0) return false; + * + * eventCount--; currentEventPos++; if (currentEventPos == maxEvents) + * currentEventPos = 0; + * + * return true; + */ + } + + public static int getEventKey() { + return keyEvents[queue.getCurrentPos()]; + } + + public static char getEventCharacter() { + return keyEventChars[getEventKey()]; + } + + public static boolean getEventKeyState() { + return keyEventStates[queue.getCurrentPos()]; + } + + public static long getEventNanoseconds() { + return nanoTimeEvents[queue.getCurrentPos()]; + } + + public static String getKeyName(int key) { + return keyName[key]; + } + + public static int getKeyIndex(java.lang.String keyName) { + Integer ret = keyMap.get(keyName); + if (ret == null) + return KEY_NONE; + else + return ret; + } + + public static boolean isCreated() { + return Display.isCreated(); + } + + public static void destroy() { + + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Mouse.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Mouse.java new file mode 100644 index 000000000..452fdaf92 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/input/Mouse.java @@ -0,0 +1,241 @@ +package org.lwjgl.input; + +import org.lwjgl.glfw.GLFW; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; +import org.lwjgl.opengl.Display; + +public class Mouse { + + private static boolean grabbed = false; + + private static int lastX = 0; + private static int lastY = 0; + + private static int latestX = 0; + private static int latestY = 0; + + private static int x = 0; + private static int y = 0; + + private static int lastDWheel = 0; + + private static EventQueue queue = new EventQueue(32); + + private static int[] buttonEvents = new int[queue.getMaxEvents()]; + private static int[] wheelEvents = new int[queue.getMaxEvents()]; + private static boolean[] buttonEventStates = new boolean[queue.getMaxEvents()]; + private static int[] xEvents = new int[queue.getMaxEvents()]; + private static int[] yEvents = new int[queue.getMaxEvents()]; + private static int[] lastxEvents = new int[queue.getMaxEvents()]; + private static int[] lastyEvents = new int[queue.getMaxEvents()]; + private static long[] nanoTimeEvents = new long[queue.getMaxEvents()]; + + private static boolean clipPostionToDisplay = true; + + private static boolean isMouseInsideWindow = true; + + private static Cursor currentCursor = null; + + public static void addMoveEvent(double mouseX, double mouseY) { + latestX = (int) mouseX; + latestY = Display.getHeight() - (int) mouseY; + + lastxEvents[queue.getNextPos()] = xEvents[queue.getNextPos()]; + lastyEvents[queue.getNextPos()] = yEvents[queue.getNextPos()]; + + xEvents[queue.getNextPos()] = latestX; + yEvents[queue.getNextPos()] = latestY; + + buttonEvents[queue.getNextPos()] = -1; + buttonEventStates[queue.getNextPos()] = false; + + wheelEvents[queue.getNextPos()] = 0; + + nanoTimeEvents[queue.getNextPos()] = Sys.getNanoTime(); + + queue.add(); + } + + public static void addButtonEvent(int button, boolean pressed) { + lastxEvents[queue.getNextPos()] = xEvents[queue.getNextPos()]; + lastyEvents[queue.getNextPos()] = yEvents[queue.getNextPos()]; + + xEvents[queue.getNextPos()] = latestX; + yEvents[queue.getNextPos()] = latestY; + + buttonEvents[queue.getNextPos()] = button; + buttonEventStates[queue.getNextPos()] = pressed; + + wheelEvents[queue.getNextPos()] = 0; + + nanoTimeEvents[queue.getNextPos()] = Sys.getNanoTime(); + + queue.add(); + } + + public static void addWheelEvent(int wheel) { + lastxEvents[queue.getNextPos()] = xEvents[queue.getNextPos()]; + lastyEvents[queue.getNextPos()] = yEvents[queue.getNextPos()]; + + xEvents[queue.getNextPos()] = latestX; + yEvents[queue.getNextPos()] = latestY; + + buttonEvents[queue.getNextPos()] = -1; + buttonEventStates[queue.getNextPos()] = false; + + wheelEvents[queue.getNextPos()] = wheel; + lastDWheel = wheel; + + nanoTimeEvents[queue.getNextPos()] = Sys.getNanoTime(); + + queue.add(); + } + + public static void setMouseInsideWindow(boolean mouseInsideWindow) { + isMouseInsideWindow = mouseInsideWindow; + } + + public static void poll() { + lastX = x; + lastY = y; + + if (!grabbed && clipPostionToDisplay) { + if (latestX < 0) + latestX = 0; + if (latestY < 0) + latestY = 0; + if (latestX > Display.getWidth() - 1) + latestX = Display.getWidth() - 1; + if (latestY > Display.getHeight() - 1) + latestY = Display.getHeight() - 1; + } + + x = latestX; + y = latestY; + } + + public static void create() throws LWJGLException { + + } + + public static boolean isCreated() { + return Display.isCreated(); + } + + public static void setGrabbed(boolean grab) { + GLFW.glfwSetInputMode(Display.getWindow(), GLFW.GLFW_CURSOR, + grab ? GLFW.GLFW_CURSOR_DISABLED : GLFW.GLFW_CURSOR_NORMAL); + grabbed = grab; + } + + public static boolean isGrabbed() { + return grabbed; + } + + public static boolean isButtonDown(int button) { + return GLFW.glfwGetMouseButton(Display.getWindow(), button) == GLFW.GLFW_PRESS; + } + + public static boolean next() { + return queue.next(); + } + + public static int getEventX() { + return xEvents[queue.getCurrentPos()]; + } + + public static int getEventY() { + return yEvents[queue.getCurrentPos()]; + } + + public static int getEventDX() { + return xEvents[queue.getCurrentPos()] - lastxEvents[queue.getCurrentPos()]; + } + + public static int getEventDY() { + return yEvents[queue.getCurrentPos()] - lastyEvents[queue.getCurrentPos()]; + } + + public static long getEventNanoseconds() { + return nanoTimeEvents[queue.getCurrentPos()]; + } + + public static int getEventButton() { + return buttonEvents[queue.getCurrentPos()]; + } + + public static boolean getEventButtonState() { + return buttonEventStates[queue.getCurrentPos()]; + } + + public static int getEventDWheel() { + return wheelEvents[queue.getCurrentPos()]; + } + + public static int getX() { + return x; + } + + public static int getY() { + return y; + } + + public static int getDX() { + return x - lastX; + } + + public static int getDY() { + return y - lastY; + } + + public static int getDWheel() { + int dwheel = lastDWheel; + lastDWheel = 0; + return dwheel; + } + + public static int getButtonCount() { + return 8; // max mouse buttons supported by GLFW + } + + public static boolean isInsideWindow() { + return isMouseInsideWindow; + } + + public static void setClipMouseCoordinatesToWindow(boolean clip) { + clipPostionToDisplay = clip; + } + + public static void setCursorPosition(int new_x, int new_y) { + GLFW.glfwSetCursorPos(Display.getWindow(), new_x, new_y); + } + + public static Cursor setNativeCursor(Cursor cursor) throws LWJGLException { + if (cursor == null) { + GLFW.glfwSetCursor(Display.getWindow(), MemoryUtil.NULL); + return null; + } + + GLFW.glfwSetCursor(Display.getWindow(), cursor.getHandle()); + currentCursor = cursor; + return cursor; + } + + public static Cursor getCurrentCursor() { + return currentCursor; + } + + public static Cursor getNativeCursor() { + return currentCursor; + } + + public static boolean hasWheel() { + return true; + } + + public static void destroy() { + + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL.java new file mode 100644 index 000000000..9b75b4b3c --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL.java @@ -0,0 +1,330 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + */ +package org.lwjgl.openal; + +import org.lwjgl.*; +import org.lwjgl.system.*; + +import javax.annotation.*; +import java.nio.*; +import java.util.*; + +import static org.lwjgl.openal.AL10.*; +import static org.lwjgl.openal.EXTThreadLocalContext.*; +import static org.lwjgl.system.APIUtil.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.MemoryUtil.*; + +/** + * This class must be used before any OpenAL function is called. It has the following responsibilities: + *
    + *
  • Creates instances of {@link ALCapabilities} classes. An {@code ALCapabilities} instance contains flags for functionality that is available in an OpenAL + * context. Internally, it also contains function pointers that are only valid in that specific OpenAL context.
  • + *
  • Maintains thread-local and global state for {@code ALCapabilities} instances, corresponding to OpenAL contexts that are current in those threads and the + * entire process, respectively.
  • + *
+ * + *

ALCapabilities creation

+ *

Instances of {@code ALCapabilities} can be created with the {@link #createCapabilities} method. An OpenAL context must be current in the current thread + * or process before it is called. Calling this method is expensive, so {@code ALCapabilities} instances should be cached in user code.

+ * + *

Thread-local state

+ *

Before a function for a given OpenAL context can be called, the corresponding {@code ALCapabilities} instance must be made current in the current + * thread or process. The user is also responsible for clearing the current {@code ALCapabilities} instance when the context is destroyed or made current in + * another thread.

+ * + *

Note that OpenAL contexts are made current process-wide by default. Current thread-local contexts are only available if the + * {@link EXTThreadLocalContext ALC_EXT_thread_local_context} extension is supported by the OpenAL implementation. OpenAL Soft, the implementation + * that LWJGL ships with, supports this extension and performs better when it is used.

+ * + * @see ALC + */ +public final class AL { +// -- Begin LWJGL2 part -- + static { + // FIXME should be? + // Sys.initialize(); // init using dummy sys method + } + static long alContext; + static ALCdevice alcDevice; + static ALCCapabilities alContextCaps; + static ALCapabilities alCaps; + + private static boolean created_lwjgl2 = false; + + public static void create() throws LWJGLException { + if (alContext == MemoryUtil.NULL) { + //ALDevice alDevice = ALDevice.create(); + long alDevice = ALC10.alcOpenDevice((ByteBuffer)null); + if(alDevice == MemoryUtil.NULL){ + throw new LWJGLException("Cannot open the device"); + } + + IntBuffer attribs = BufferUtils.createIntBuffer(16); + + attribs.put(ALC10.ALC_FREQUENCY); + attribs.put(44100); + + attribs.put(ALC10.ALC_REFRESH); + attribs.put(60); + + attribs.put(ALC10.ALC_SYNC); + attribs.put(ALC10.ALC_FALSE); + + attribs.put(0); + attribs.flip(); + + long contextHandle = ALC10.alcCreateContext(alDevice, attribs); + ALC10.alcMakeContextCurrent(contextHandle); + //alContext = new ALContext(alDevice, contextHandle); + alContext = ALC10.alcCreateContext(contextHandle, (IntBuffer)null); + alContextCaps = ALC.createCapabilities(alContext); + + alCaps = AL.createCapabilities(alContextCaps); + + alcDevice = new ALCdevice(alDevice); + created_lwjgl2 = true; + } + } + + public static boolean isCreated() { + return created_lwjgl2; + } + + public static ALCdevice getDevice() { + return alcDevice; + } +// -- End LWJGL2 part + + @Nullable + private static FunctionProvider functionProvider; + + @Nullable + private static ALCapabilities processCaps; + + private static final ThreadLocal capabilitiesTLS = new ThreadLocal<>(); + + private static ICD icd = new ICDStatic(); + + private AL() {} + + static void init() { + functionProvider = new FunctionProvider() { + // We'll use alGetProcAddress for both core and extension entry points. + // To do that, we need to first grab the alGetProcAddress function from + // the OpenAL native library. + private final long alGetProcAddress = ALC.getFunctionProvider().getFunctionAddress("alGetProcAddress"); + + @Override + public long getFunctionAddress(ByteBuffer functionName) { + long address = invokePP(memAddress(functionName), alGetProcAddress); + if (address == NULL && Checks.DEBUG_FUNCTIONS) { + apiLog("Failed to locate address for AL function " + memASCII(functionName)); + } + return address; + } + }; + } + + public static void destroy() { + if (functionProvider == null) { + return; + } + + // LWJGL2 code + if (created_lwjgl2) { + ALC10.alcMakeContextCurrent(MemoryUtil.NULL); + ALC10.alcDestroyContext(alContext); + ALC10.alcCloseDevice(alcDevice.device); + alContext = -1; + alcDevice = null; + created_lwjgl2 = false; + } + + setCurrentProcess(null); + + functionProvider = null; + } + + /** + * Sets the specified {@link ALCapabilities} for the current process-wide OpenAL context. + * + *

If the current thread had a context current (see {@link #setCurrentThread}), those {@code ALCapabilities} are cleared. Any OpenAL functions called in + * the current thread, or any threads that have no context current, will use the specified {@code ALCapabilities}.

+ * + * @param caps the {@link ALCapabilities} to make current, or null + */ + public static void setCurrentProcess(@Nullable ALCapabilities caps) { + processCaps = caps; + capabilitiesTLS.set(null); // See EXT_thread_local_context, second Q. + icd.set(caps); + } + + /** + * Sets the specified {@link ALCapabilities} for the current OpenAL context in the current thread. + * + *

Any OpenAL functions called in the current thread will use the specified {@code ALCapabilities}.

+ * + * @param caps the {@link ALCapabilities} to make current, or null + */ + public static void setCurrentThread(@Nullable ALCapabilities caps) { + capabilitiesTLS.set(caps); + icd.set(caps); + } + + /** + * Returns the {@link ALCapabilities} for the OpenAL context that is current in the current thread or process. + * + * @throws IllegalStateException if no OpenAL context is current in the current thread or process + */ + public static ALCapabilities getCapabilities() { + ALCapabilities caps = capabilitiesTLS.get(); + if (caps == null) { + caps = processCaps; + } + + return checkCapabilities(caps); + } + + private static ALCapabilities checkCapabilities(@Nullable ALCapabilities caps) { + if (caps == null) { + throw new IllegalStateException( + "No ALCapabilities instance set for the current thread or process. Possible solutions:\n" + + "\ta) Call AL.createCapabilities() after making a context current.\n" + + "\tb) Call AL.setCurrentProcess() or AL.setCurrentThread() if an ALCapabilities instance already exists." + ); + } + return caps; + } + + /** + * Creates a new {@link ALCapabilities} instance for the OpenAL context that is current in the current thread or process. + * + * @param alcCaps the {@link ALCCapabilities} of the device associated with the current context + * + * @return the ALCapabilities instance + */ + public static ALCapabilities createCapabilities(ALCCapabilities alcCaps) { + FunctionProvider functionProvider = ALC.check(AL.functionProvider); + + ALCapabilities caps = null; + + try { + long GetString = functionProvider.getFunctionAddress("alGetString"); + long GetError = functionProvider.getFunctionAddress("alGetError"); + long IsExtensionPresent = functionProvider.getFunctionAddress("alIsExtensionPresent"); + if (GetString == NULL || GetError == NULL || IsExtensionPresent == NULL) { + throw new IllegalStateException("Core OpenAL functions could not be found. Make sure that the OpenAL library has been loaded correctly."); + } + + String versionString = memASCIISafe(invokeP(AL_VERSION, GetString)); + if (versionString == null || invokeI(GetError) != AL_NO_ERROR) { + throw new IllegalStateException("There is no OpenAL context current in the current thread or process."); + } + + APIVersion apiVersion = apiParseVersion(versionString); + + int majorVersion = apiVersion.major; + int minorVersion = apiVersion.minor; + + int[][] AL_VERSIONS = { + {0, 1} // OpenAL 1 + }; + + Set supportedExtensions = new HashSet<>(32); + + for (int major = 1; major <= AL_VERSIONS.length; major++) { + int[] minors = AL_VERSIONS[major - 1]; + for (int minor : minors) { + if (major < majorVersion || (major == majorVersion && minor <= minorVersion)) { + supportedExtensions.add("OpenAL" + major + minor); + } + } + } + + // Parse EXTENSIONS string + String extensionsString = memASCIISafe(invokeP(AL_EXTENSIONS, GetString)); + if (extensionsString != null) { + MemoryStack stack = stackGet(); + + StringTokenizer tokenizer = new StringTokenizer(extensionsString); + while (tokenizer.hasMoreTokens()) { + String extName = tokenizer.nextToken(); + try (MemoryStack frame = stack.push()) { + if (invokePZ(memAddress(frame.ASCII(extName, true)), IsExtensionPresent)) { + supportedExtensions.add(extName); + } + } + } + } + + if (alcCaps.ALC_EXT_EFX) { + supportedExtensions.add("ALC_EXT_EFX"); + } + + return caps = new ALCapabilities(functionProvider, supportedExtensions); + } finally { + if (alcCaps.ALC_EXT_thread_local_context && alcGetThreadContext() != NULL) { + setCurrentThread(caps); + } else { + setCurrentProcess(caps); + } + } + } + + static ALCapabilities getICD() { + return ALC.check(icd.get()); + } + + /** Function pointer provider. */ + private interface ICD { + default void set(@Nullable ALCapabilities caps) {} + @Nullable ALCapabilities get(); + } + + /** + * Write-once {@link ICD}. + * + *

This is the default implementation that skips the thread/process lookup. When a new ALCapabilities is set, we compare it to the write-once + * capabilities. If different function pointers are found, we fall back to the expensive lookup. This will never happen with the OpenAL-Soft + * implementation.

+ */ + private static class ICDStatic implements ICD { + + @Nullable + private static ALCapabilities tempCaps; + + @Override + public void set(@Nullable ALCapabilities caps) { + if (tempCaps == null) { + tempCaps = caps; + } else if (caps != null && caps != tempCaps && ThreadLocalUtil.areCapabilitiesDifferent(tempCaps.addresses, caps.addresses)) { + apiLog("[WARNING] Incompatible context detected. Falling back to thread/process lookup for AL contexts."); + icd = AL::getCapabilities; // fall back to thread/process lookup + } + } + + @Override + @Nullable + public ALCapabilities get() { + return WriteOnce.caps; + } + + private static final class WriteOnce { + // This will be initialized the first time get() above is called + @Nullable + static final ALCapabilities caps = ICDStatic.tempCaps; + + static { + if (caps == null) { + throw new IllegalStateException("No ALCapabilities instance has been set"); + } + } + } + + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL10.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL10.java new file mode 100644 index 000000000..9c5d15a33 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/AL10.java @@ -0,0 +1,1931 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.openal; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.MemoryUtil.*; + +/** Native bindings to AL 1.0 functionality. */ +public class AL10 { +// -- Begin LWJGL2 Bridge -- + public static void alGetDouble(int p1, DoubleBuffer p2) { + alGetDoublev(p1, p2); + } +/* + public static int alGetEnumValue(String p1) { + alGetEnumValue((CharSequence) p1); + } +*/ + public static void alGetFloat(int p1, FloatBuffer p2) { + alGetFloatv(p1, p2); + } + + public static void alGetInteger(int p1, IntBuffer p2) { + alGetIntegerv(p1, p2); + } + + public static void alGetListener(int p1, FloatBuffer p2) { + alGetListenerfv(p1, p2); + } + + public static void alGetSource(int p1, int p2, FloatBuffer p3) { + alGetSourcefv(p1, p2, p3); + } +/* + public static boolean alIsExtensionPresent(String p1) { + return alIsExtensionPresent((CharSequence) p1); + } +*/ + public static void alListener(int pname, FloatBuffer value) { + alListenerfv(pname, value); + } + + public static void alSource(int p1, int p2, FloatBuffer p3) { + alSourcefv(p1, p2, p3); + } + + public static void alSourcePause(IntBuffer p1) { + alSourcePausev(p1); + } + + public static void alSourcePlay(IntBuffer p1) { + alSourcePlayv(p1); + } + + public static void alSourceRewind(IntBuffer p1) { + alSourceRewindv(p1); + } + + public static void alSourceStop(IntBuffer p1) { + alSourceStopv(p1); + } +// -- End LWJGL2 Bridge -- + + /** General tokens. */ + public static final int + AL_INVALID = 0xFFFFFFFF, + AL_NONE = 0x0, + AL_FALSE = 0x0, + AL_TRUE = 0x1; + + /** Error conditions. */ + public static final int + AL_NO_ERROR = 0x0, + AL_INVALID_NAME = 0xA001, + AL_INVALID_ENUM = 0xA002, + AL_INVALID_VALUE = 0xA003, + AL_INVALID_OPERATION = 0xA004, + AL_OUT_OF_MEMORY = 0xA005; + + /** Numerical queries. */ + public static final int + AL_DOPPLER_FACTOR = 0xC000, + AL_DISTANCE_MODEL = 0xD000; + + /** String queries. */ + public static final int + AL_VENDOR = 0xB001, + AL_VERSION = 0xB002, + AL_RENDERER = 0xB003, + AL_EXTENSIONS = 0xB004; + + /** Distance attenuation models. */ + public static final int + AL_INVERSE_DISTANCE = 0xD001, + AL_INVERSE_DISTANCE_CLAMPED = 0xD002; + + /** Source types. */ + public static final int + AL_SOURCE_ABSOLUTE = 0x201, + AL_SOURCE_RELATIVE = 0x202; + + /** Listener and Source attributes. */ + public static final int + AL_POSITION = 0x1004, + AL_VELOCITY = 0x1006, + AL_GAIN = 0x100A; + + /** Source attributes. */ + public static final int + AL_CONE_INNER_ANGLE = 0x1001, + AL_CONE_OUTER_ANGLE = 0x1002, + AL_PITCH = 0x1003, + AL_DIRECTION = 0x1005, + AL_LOOPING = 0x1007, + AL_BUFFER = 0x1009, + AL_SOURCE_STATE = 0x1010, + AL_CONE_OUTER_GAIN = 0x1022, + AL_SOURCE_TYPE = 0x1027; + + /** Source state. */ + public static final int + AL_INITIAL = 0x1011, + AL_PLAYING = 0x1012, + AL_PAUSED = 0x1013, + AL_STOPPED = 0x1014; + + /** Listener attributes. */ + public static final int AL_ORIENTATION = 0x100F; + + /** Queue state. */ + public static final int + AL_BUFFERS_QUEUED = 0x1015, + AL_BUFFERS_PROCESSED = 0x1016; + + /** Gain bounds. */ + public static final int + AL_MIN_GAIN = 0x100D, + AL_MAX_GAIN = 0x100E; + + /** Distance model attributes, */ + public static final int + AL_REFERENCE_DISTANCE = 0x1020, + AL_ROLLOFF_FACTOR = 0x1021, + AL_MAX_DISTANCE = 0x1023; + + /** Buffer attributes, */ + public static final int + AL_FREQUENCY = 0x2001, + AL_BITS = 0x2002, + AL_CHANNELS = 0x2003, + AL_SIZE = 0x2004; + + /** Buffer formats. */ + public static final int + AL_FORMAT_MONO8 = 0x1100, + AL_FORMAT_MONO16 = 0x1101, + AL_FORMAT_STEREO8 = 0x1102, + AL_FORMAT_STEREO16 = 0x1103; + + /** Buffer state. */ + public static final int + AL_UNUSED = 0x2010, + AL_PENDING = 0x2011, + AL_PROCESSED = 0x2012; + + protected AL10() { + throw new UnsupportedOperationException(); + } + + static boolean isAvailable(ALCapabilities caps) { + return checkFunctions( + caps.alGetError, caps.alEnable, caps.alDisable, caps.alIsEnabled, caps.alGetBoolean, caps.alGetInteger, caps.alGetFloat, caps.alGetDouble, + caps.alGetBooleanv, caps.alGetIntegerv, caps.alGetFloatv, caps.alGetDoublev, caps.alGetString, caps.alDistanceModel, caps.alDopplerFactor, + caps.alDopplerVelocity, caps.alListenerf, caps.alListeneri, caps.alListener3f, caps.alListenerfv, caps.alGetListenerf, caps.alGetListeneri, + caps.alGetListener3f, caps.alGetListenerfv, caps.alGenSources, caps.alDeleteSources, caps.alIsSource, caps.alSourcef, caps.alSource3f, + caps.alSourcefv, caps.alSourcei, caps.alGetSourcef, caps.alGetSource3f, caps.alGetSourcefv, caps.alGetSourcei, caps.alGetSourceiv, + caps.alSourceQueueBuffers, caps.alSourceUnqueueBuffers, caps.alSourcePlay, caps.alSourcePause, caps.alSourceStop, caps.alSourceRewind, + caps.alSourcePlayv, caps.alSourcePausev, caps.alSourceStopv, caps.alSourceRewindv, caps.alGenBuffers, caps.alDeleteBuffers, caps.alIsBuffer, + caps.alGetBufferf, caps.alGetBufferi, caps.alBufferData, caps.alGetEnumValue, caps.alGetProcAddress, caps.alIsExtensionPresent + ); + } + + // --- [ alGetError ] --- + + /** + * Obtains error information. + * + *

Each detectable error is assigned a numeric code. When an error is detected by AL, a flag is set and the error code is recorded. Further errors, if they + * occur, do not affect this recorded code. When alGetError is called, the code is returned and the flag is cleared, so that a further error will again + * record its code. If a call to alGetError returns AL_NO_ERROR then there has been no detectable error since the last call to alGetError (or since the AL + * was initialized).

+ * + *

Error codes can be mapped to strings. The alGetString function returns a pointer to a constant (literal) string that is identical to the identifier used + * for the enumeration value, as defined in the specification.

+ */ + @NativeType("ALenum") + public static int alGetError() { + long __functionAddress = AL.getICD().alGetError; + return invokeI(__functionAddress); + } + + // --- [ alEnable ] --- + + /** + * Enables AL capabilities. + * + * @param target the capability to enable + */ + @NativeType("ALvoid") + public static void alEnable(@NativeType("ALenum") int target) { + long __functionAddress = AL.getICD().alEnable; + invokeV(target, __functionAddress); + } + + // --- [ alDisable ] --- + + /** + * Disables AL capabilities. + * + * @param target the capability to disable + */ + @NativeType("ALvoid") + public static void alDisable(@NativeType("ALenum") int target) { + long __functionAddress = AL.getICD().alDisable; + invokeV(target, __functionAddress); + } + + // --- [ alIsEnabled ] --- + + /** + * Queries whether a given capability is currently enabled or not. + * + * @param target the capability to query + */ + @NativeType("ALboolean") + public static boolean alIsEnabled(@NativeType("ALenum") int target) { + long __functionAddress = AL.getICD().alIsEnabled; + return invokeZ(target, __functionAddress); + } + + // --- [ alGetBoolean ] --- + + /** + * Returns the boolean value of the specified parameter. + * + * @param paramName the parameter to query + */ + @NativeType("ALboolean") + public static boolean alGetBoolean(@NativeType("ALenum") int paramName) { + long __functionAddress = AL.getICD().alGetBoolean; + return invokeZ(paramName, __functionAddress); + } + + // --- [ alGetInteger ] --- + + /** + * Returns the integer value of the specified parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_DOPPLER_FACTOR DOPPLER_FACTOR}{@link #AL_DISTANCE_MODEL DISTANCE_MODEL}{@link AL11#AL_SPEED_OF_SOUND SPEED_OF_SOUND}
+ */ + @NativeType("ALint") + public static int alGetInteger(@NativeType("ALenum") int paramName) { + long __functionAddress = AL.getICD().alGetInteger; + return invokeI(paramName, __functionAddress); + } + + // --- [ alGetFloat ] --- + + /** + * Returns the float value of the specified parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_DOPPLER_FACTOR DOPPLER_FACTOR}{@link #AL_DISTANCE_MODEL DISTANCE_MODEL}{@link AL11#AL_SPEED_OF_SOUND SPEED_OF_SOUND}
+ */ + @NativeType("ALfloat") + public static float alGetFloat(@NativeType("ALenum") int paramName) { + long __functionAddress = AL.getICD().alGetFloat; + return invokeF(paramName, __functionAddress); + } + + // --- [ alGetDouble ] --- + + /** + * Returns the double value of the specified parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_DOPPLER_FACTOR DOPPLER_FACTOR}{@link #AL_DISTANCE_MODEL DISTANCE_MODEL}{@link AL11#AL_SPEED_OF_SOUND SPEED_OF_SOUND}
+ */ + @NativeType("ALdouble") + public static double alGetDouble(@NativeType("ALenum") int paramName) { + long __functionAddress = AL.getICD().alGetDouble; + return invokeD(paramName, __functionAddress); + } + + // --- [ alGetBooleanv ] --- + + /** Unsafe version of: {@link #alGetBooleanv GetBooleanv} */ + public static void nalGetBooleanv(int paramName, long dest) { + long __functionAddress = AL.getICD().alGetBooleanv; + invokePV(paramName, dest, __functionAddress); + } + + /** + * Pointer version of {@link #alGetBoolean GetBoolean}. + * + * @param paramName the parameter to query + * @param dest a buffer that will receive the parameter values + */ + @NativeType("ALvoid") + public static void alGetBooleanv(@NativeType("ALenum") int paramName, @NativeType("ALboolean *") ByteBuffer dest) { + if (CHECKS) { + check(dest, 1); + } + nalGetBooleanv(paramName, memAddress(dest)); + } + + // --- [ alGetIntegerv ] --- + + /** Unsafe version of: {@link #alGetIntegerv GetIntegerv} */ + public static void nalGetIntegerv(int paramName, long dest) { + long __functionAddress = AL.getICD().alGetIntegerv; + invokePV(paramName, dest, __functionAddress); + } + + /** + * Pointer version of {@link #alGetInteger GetInteger}. + * + * @param paramName the parameter to query + * @param dest a buffer that will receive the parameter values + */ + @NativeType("ALvoid") + public static void alGetIntegerv(@NativeType("ALenum") int paramName, @NativeType("ALint *") IntBuffer dest) { + if (CHECKS) { + check(dest, 1); + } + nalGetIntegerv(paramName, memAddress(dest)); + } + + // --- [ alGetFloatv ] --- + + /** Unsafe version of: {@link #alGetFloatv GetFloatv} */ + public static void nalGetFloatv(int paramName, long dest) { + long __functionAddress = AL.getICD().alGetFloatv; + invokePV(paramName, dest, __functionAddress); + } + + /** + * Pointer version of {@link #alGetFloat GetFloat}. + * + * @param paramName the parameter to query + * @param dest a buffer that will receive the parameter values + */ + @NativeType("ALvoid") + public static void alGetFloatv(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") FloatBuffer dest) { + if (CHECKS) { + check(dest, 1); + } + nalGetFloatv(paramName, memAddress(dest)); + } + + // --- [ alGetDoublev ] --- + + /** Unsafe version of: {@link #alGetDoublev GetDoublev} */ + public static void nalGetDoublev(int paramName, long dest) { + long __functionAddress = AL.getICD().alGetDoublev; + invokePV(paramName, dest, __functionAddress); + } + + /** + * Pointer version of {@link #alGetDouble GetDouble}. + * + * @param paramName the parameter to query + * @param dest a buffer that will receive the parameter values + */ + @NativeType("ALvoid") + public static void alGetDoublev(@NativeType("ALenum") int paramName, @NativeType("ALdouble *") DoubleBuffer dest) { + if (CHECKS) { + check(dest, 1); + } + nalGetDoublev(paramName, memAddress(dest)); + } + + // --- [ alGetString ] --- + + /** Unsafe version of: {@link #alGetString GetString} */ + public static long nalGetString(int paramName) { + long __functionAddress = AL.getICD().alGetString; + return invokeP(paramName, __functionAddress); + } + + /** + * Returns the string value of the specified parameter + * + * @param paramName the parameter to query. One of:
{@link #AL_VENDOR VENDOR}{@link #AL_VERSION VERSION}{@link #AL_RENDERER RENDERER}{@link #AL_EXTENSIONS EXTENSIONS}
+ */ + @Nullable + @NativeType("ALchar const *") + public static String alGetString(@NativeType("ALenum") int paramName) { + long __result = nalGetString(paramName); + return memUTF8Safe(__result); + } + + // --- [ alDistanceModel ] --- + + /** + * Sets the distance attenuation model. + * + *

Samples usually use the entire dynamic range of the chosen format/encoding, independent of their real world intensity. For example, a jet engine and a + * clockwork both will have samples with full amplitude. The application will then have to adjust source gain accordingly to account for relative differences.

+ * + *

Source gain is then attenuated by distance. The effective attenuation of a source depends on many factors, among which distance attenuation and source + * and listener gain are only some of the contributing factors. Even if the source and listener gain exceed 1.0 (amplification beyond the guaranteed + * dynamic range), distance and other attenuation might ultimately limit the overall gain to a value below 1.0.

+ * + *

OpenAL currently supports three modes of operation with respect to distance attenuation, including one that is similar to the IASIG I3DL2 model. The + * application can choose one of these models (or chooses to disable distance-dependent attenuation) on a per-context basis.

+ * + * @param modelName the distance attenuation model to set. One of:
{@link #AL_INVERSE_DISTANCE INVERSE_DISTANCE}{@link #AL_INVERSE_DISTANCE_CLAMPED INVERSE_DISTANCE_CLAMPED}{@link AL11#AL_LINEAR_DISTANCE LINEAR_DISTANCE}{@link AL11#AL_LINEAR_DISTANCE_CLAMPED LINEAR_DISTANCE_CLAMPED}
{@link AL11#AL_EXPONENT_DISTANCE EXPONENT_DISTANCE}{@link AL11#AL_EXPONENT_DISTANCE_CLAMPED EXPONENT_DISTANCE_CLAMPED}{@link #AL_NONE NONE}
+ */ + @NativeType("ALvoid") + public static void alDistanceModel(@NativeType("ALenum") int modelName) { + long __functionAddress = AL.getICD().alDistanceModel; + invokeV(modelName, __functionAddress); + } + + // --- [ alDopplerFactor ] --- + + /** + * Sets the doppler effect factor. + * + *

The Doppler Effect depends on the velocities of source and listener relative to the medium, and the propagation speed of sound in that medium. The + * application might want to emphasize or de-emphasize the Doppler Effect as physically accurate calculation might not give the desired results. The amount + * of frequency shift (pitch change) is proportional to the speed of listener and source along their line of sight. The Doppler Effect as implemented by + * OpenAL is described by the formula below. Effects of the medium (air, water) moving with respect to listener and source are ignored.

+ * + *

+     * SS: AL_SPEED_OF_SOUND = speed of sound (default value 343.3)
+     * DF: AL_DOPPLER_FACTOR = Doppler factor (default 1.0)
+     * vls: Listener velocity scalar (scalar, projected on source-to-listener vector)
+     * vss: Source velocity scalar (scalar, projected on source-to-listener vector)
+     * f: Frequency of sample
+     * f': effective Doppler shifted frequency
+     * 
+     * 3D Mathematical representation of vls and vss:
+     * 
+     * Mag(vector) = sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z)
+     * DotProduct(v1, v2) = (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z)
+     * 
+     * SL = source to listener vector
+     * SV = Source velocity vector
+     * LV = Listener velocity vector
+     * 
+     * vls = DotProduct(SL, LV) / Mag(SL)
+     * vss = DotProduct(SL, SV) / Mag(SL)
+     * 
+     * Dopper Calculation:
+     * 
+     * vss = min(vss, SS / DF)
+     * vls = min(vls, SS / DF)
+     * 
+     * f' = f * (SS - DF * vls) / (SS - DF * vss)
+ * + *

The {@code dopplerFactor} is a simple scaling of source and listener velocities to exaggerate or deemphasize the Doppler (pitch) shift resulting from + * the calculation.

+ * + * @param dopplerFactor the doppler factor + */ + @NativeType("ALvoid") + public static void alDopplerFactor(@NativeType("ALfloat") float dopplerFactor) { + long __functionAddress = AL.getICD().alDopplerFactor; + invokeV(dopplerFactor, __functionAddress); + } + + // --- [ alDopplerVelocity ] --- + + /** + * Sets the doppler effect propagation velocity. + * + *

The OpenAL 1.1 Doppler implementation is different than that of OpenAL 1.0, because the older implementation was confusing and not implemented + * consistently. The new "speed of sound" property makes the 1.1 implementation more intuitive than the old implementation. If your implementation wants to + * support the AL_DOPPLER_VELOCITY parameter (the alDopplerVelocity call will remain as an entry point so that 1.0 applications can link with a 1.1 + * library), the above formula can be changed to the following:

+ * + *

+     * vss = min(vss, (SS * DV)/DF)
+     * vls = min(vls, (SS * DV)/DF)
+     * 
+     * f' = f * (SS * DV - DF*vls) / (SS * DV - DF * vss)
+ * + *

OpenAL 1.1 programmers would never use AL_DOPPLER_VELOCITY (which defaults to 1.0).

+ * + * @param dopplerVelocity the doppler velocity + */ + @NativeType("ALvoid") + public static void alDopplerVelocity(@NativeType("ALfloat") float dopplerVelocity) { + long __functionAddress = AL.getICD().alDopplerVelocity; + invokeV(dopplerVelocity, __functionAddress); + } + + // --- [ alListenerf ] --- + + /** + * Sets the float value of a listener parameter. + * + * @param paramName the parameter to modify. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alListenerf(@NativeType("ALenum") int paramName, @NativeType("ALfloat") float value) { + long __functionAddress = AL.getICD().alListenerf; + invokeV(paramName, value, __functionAddress); + } + + // --- [ alListeneri ] --- + + /** + * Integer version of {@link #alListenerf Listenerf}. + * + * @param paramName the parameter to modify. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ * @param values the parameter value + */ + @NativeType("ALvoid") + public static void alListeneri(@NativeType("ALenum") int paramName, @NativeType("ALint") int values) { + long __functionAddress = AL.getICD().alListeneri; + invokeV(paramName, values, __functionAddress); + } + + // --- [ alListener3f ] --- + + /** + * Sets the 3 dimensional float values of a listener parameter. + * + * @param paramName the parameter to modify. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ * @param value1 the first value + * @param value2 the second value + * @param value3 the third value + */ + @NativeType("ALvoid") + public static void alListener3f(@NativeType("ALenum") int paramName, @NativeType("ALfloat") float value1, @NativeType("ALfloat") float value2, @NativeType("ALfloat") float value3) { + long __functionAddress = AL.getICD().alListener3f; + invokeV(paramName, value1, value2, value3, __functionAddress); + } + + // --- [ alListenerfv ] --- + + /** Unsafe version of: {@link #alListenerfv Listenerfv} */ + public static void nalListenerfv(int paramName, long values) { + long __functionAddress = AL.getICD().alListenerfv; + invokePV(paramName, values, __functionAddress); + } + + /** + * Pointer version of {@link #alListenerf Listenerf}. + * + * @param paramName the parameter to modify + * @param values the parameter values + */ + @NativeType("ALvoid") + public static void alListenerfv(@NativeType("ALenum") int paramName, @NativeType("ALfloat const *") FloatBuffer values) { + if (CHECKS) { + check(values, 1); + } + nalListenerfv(paramName, memAddress(values)); + } + + // --- [ alGetListenerf ] --- + + /** Unsafe version of: {@link #alGetListenerf GetListenerf} */ + public static void nalGetListenerf(int paramName, long value) { + long __functionAddress = AL.getICD().alGetListenerf; + invokePV(paramName, value, __functionAddress); + } + + /** + * Returns the float value of a listener parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alGetListenerf(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") FloatBuffer value) { + if (CHECKS) { + check(value, 1); + } + nalGetListenerf(paramName, memAddress(value)); + } + + /** + * Returns the float value of a listener parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ */ + @NativeType("ALvoid") + public static float alGetListenerf(@NativeType("ALenum") int paramName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer value = stack.callocFloat(1); + nalGetListenerf(paramName, memAddress(value)); + return value.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alGetListeneri ] --- + + /** Unsafe version of: {@link #alGetListeneri GetListeneri} */ + public static void nalGetListeneri(int paramName, long value) { + long __functionAddress = AL.getICD().alGetListeneri; + invokePV(paramName, value, __functionAddress); + } + + /** + * Returns the integer value of a listener parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alGetListeneri(@NativeType("ALenum") int paramName, @NativeType("ALint *") IntBuffer value) { + if (CHECKS) { + check(value, 1); + } + nalGetListeneri(paramName, memAddress(value)); + } + + /** + * Returns the integer value of a listener parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ */ + @NativeType("ALvoid") + public static int alGetListeneri(@NativeType("ALenum") int paramName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer value = stack.callocInt(1); + nalGetListeneri(paramName, memAddress(value)); + return value.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alGetListener3f ] --- + + /** Unsafe version of: {@link #alGetListener3f GetListener3f} */ + public static void nalGetListener3f(int paramName, long value1, long value2, long value3) { + long __functionAddress = AL.getICD().alGetListener3f; + invokePPPV(paramName, value1, value2, value3, __functionAddress); + } + + /** + * Returns the 3 dimensional values of a listener parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ * @param value1 the first parameter value + * @param value2 the second parameter value + * @param value3 the third parameter value + */ + @NativeType("ALvoid") + public static void alGetListener3f(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") FloatBuffer value1, @NativeType("ALfloat *") FloatBuffer value2, @NativeType("ALfloat *") FloatBuffer value3) { + if (CHECKS) { + check(value1, 1); + check(value2, 1); + check(value3, 1); + } + nalGetListener3f(paramName, memAddress(value1), memAddress(value2), memAddress(value3)); + } + + // --- [ alGetListenerfv ] --- + + /** Unsafe version of: {@link #alGetListenerfv GetListenerfv} */ + public static void nalGetListenerfv(int paramName, long values) { + long __functionAddress = AL.getICD().alGetListenerfv; + invokePV(paramName, values, __functionAddress); + } + + /** + * Returns float values of a listener parameter. + * + * @param paramName the parameter to query. One of:
{@link #AL_ORIENTATION ORIENTATION}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}
+ * @param values the parameter values + */ + @NativeType("ALvoid") + public static void alGetListenerfv(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") FloatBuffer values) { + if (CHECKS) { + check(values, 1); + } + nalGetListenerfv(paramName, memAddress(values)); + } + + // --- [ alGenSources ] --- + + /** + * Unsafe version of: {@link #alGenSources GenSources} + * + * @param n the number of source names to generated + */ + public static void nalGenSources(int n, long srcNames) { + long __functionAddress = AL.getICD().alGenSources; + invokePV(n, srcNames, __functionAddress); + } + + /** + * Requests a number of source names. + * + * @param srcNames the buffer that will receive the source names + */ + @NativeType("ALvoid") + public static void alGenSources(@NativeType("ALuint *") IntBuffer srcNames) { + nalGenSources(srcNames.remaining(), memAddress(srcNames)); + } + + /** Requests a number of source names. */ + @NativeType("ALvoid") + public static int alGenSources() { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer srcNames = stack.callocInt(1); + nalGenSources(1, memAddress(srcNames)); + return srcNames.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alDeleteSources ] --- + + /** + * Unsafe version of: {@link #alDeleteSources DeleteSources} + * + * @param n the number of sources to delete + */ + public static void nalDeleteSources(int n, long sources) { + long __functionAddress = AL.getICD().alDeleteSources; + invokePV(n, sources, __functionAddress); + } + + /** + * Requests the deletion of a number of sources. + * + * @param sources the sources to delete + */ + @NativeType("ALvoid") + public static void alDeleteSources(@NativeType("ALuint *") IntBuffer sources) { + nalDeleteSources(sources.remaining(), memAddress(sources)); + } + + /** Requests the deletion of a number of sources. */ + @NativeType("ALvoid") + public static void alDeleteSources(@NativeType("ALuint *") int source) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer sources = stack.ints(source); + nalDeleteSources(1, memAddress(sources)); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alIsSource ] --- + + /** + * Verifies whether the specified object name is a source name. + * + * @param sourceName a value that may be a source name + */ + @NativeType("ALboolean") + public static boolean alIsSource(@NativeType("ALuint") int sourceName) { + long __functionAddress = AL.getICD().alIsSource; + return invokeZ(sourceName, __functionAddress); + } + + // --- [ alSourcef ] --- + + /** + * Sets the float value of a source parameter. + * + * @param source the source to modify + * @param param the parameter to modify. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alSourcef(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat") float value) { + long __functionAddress = AL.getICD().alSourcef; + invokeV(source, param, value, __functionAddress); + } + + // --- [ alSource3f ] --- + + /** + * Sets the 3 dimensional values of a source parameter. + * + * @param source the source to modify + * @param param the parameter to modify. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ * @param v1 the first parameter value + * @param v2 the second parameter value + * @param v3 the third parameter value + */ + @NativeType("ALvoid") + public static void alSource3f(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat") float v1, @NativeType("ALfloat") float v2, @NativeType("ALfloat") float v3) { + long __functionAddress = AL.getICD().alSource3f; + invokeV(source, param, v1, v2, v3, __functionAddress); + } + + // --- [ alSourcefv ] --- + + /** Unsafe version of: {@link #alSourcefv Sourcefv} */ + public static void nalSourcefv(int source, int param, long values) { + long __functionAddress = AL.getICD().alSourcefv; + invokePV(source, param, values, __functionAddress); + } + + /** + * Pointer version of {@link #alSourcef Sourcef}. + * + * @param source the source to modify + * @param param the parameter to modify + * @param values the parameter values + */ + @NativeType("ALvoid") + public static void alSourcefv(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat const *") FloatBuffer values) { + if (CHECKS) { + check(values, 1); + } + nalSourcefv(source, param, memAddress(values)); + } + + // --- [ alSourcei ] --- + + /** + * Integer version of {@link #alSourcef Sourcef}. + * + * @param source the source to modify + * @param param the parameter to modify + * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alSourcei(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALint") int value) { + long __functionAddress = AL.getICD().alSourcei; + invokeV(source, param, value, __functionAddress); + } + + // --- [ alGetSourcef ] --- + + /** Unsafe version of: {@link #alGetSourcef GetSourcef} */ + public static void nalGetSourcef(int source, int param, long value) { + long __functionAddress = AL.getICD().alGetSourcef; + invokePV(source, param, value, __functionAddress); + } + + /** + * Returns the float value of the specified source parameter. + * + * @param source the source to query + * @param param the parameter to query. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alGetSourcef(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat *") FloatBuffer value) { + if (CHECKS) { + check(value, 1); + } + nalGetSourcef(source, param, memAddress(value)); + } + + /** + * Returns the float value of the specified source parameter. + * + * @param source the source to query + * @param param the parameter to query. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ */ + @NativeType("ALvoid") + public static float alGetSourcef(@NativeType("ALuint") int source, @NativeType("ALenum") int param) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer value = stack.callocFloat(1); + nalGetSourcef(source, param, memAddress(value)); + return value.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alGetSource3f ] --- + + /** Unsafe version of: {@link #alGetSource3f GetSource3f} */ + public static void nalGetSource3f(int source, int param, long v1, long v2, long v3) { + long __functionAddress = AL.getICD().alGetSource3f; + invokePPPV(source, param, v1, v2, v3, __functionAddress); + } + + /** + * Returns the 3 dimensional values of the specified source parameter. + * + * @param source the source to query + * @param param the parameter to query. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ * @param v1 the first parameter value + * @param v2 the second parameter value + * @param v3 the third parameter value + */ + @NativeType("ALvoid") + public static void alGetSource3f(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat *") FloatBuffer v1, @NativeType("ALfloat *") FloatBuffer v2, @NativeType("ALfloat *") FloatBuffer v3) { + if (CHECKS) { + check(v1, 1); + check(v2, 1); + check(v3, 1); + } + nalGetSource3f(source, param, memAddress(v1), memAddress(v2), memAddress(v3)); + } + + // --- [ alGetSourcefv ] --- + + /** Unsafe version of: {@link #alGetSourcefv GetSourcefv} */ + public static void nalGetSourcefv(int source, int param, long values) { + long __functionAddress = AL.getICD().alGetSourcefv; + invokePV(source, param, values, __functionAddress); + } + + /** + * Returns the float values of the specified source parameter. + * + * @param source the source to query + * @param param the parameter to query. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ * @param values the parameter values + */ + @NativeType("ALvoid") + public static void alGetSourcefv(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat *") FloatBuffer values) { + if (CHECKS) { + check(values, 1); + } + nalGetSourcefv(source, param, memAddress(values)); + } + + // --- [ alGetSourcei ] --- + + /** Unsafe version of: {@link #alGetSourcei GetSourcei} */ + public static void nalGetSourcei(int source, int param, long value) { + long __functionAddress = AL.getICD().alGetSourcei; + invokePV(source, param, value, __functionAddress); + } + + /** + * Returns the integer value of the specified source parameter. + * + * @param source the source to query + * @param param the parameter to query. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alGetSourcei(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALint *") IntBuffer value) { + if (CHECKS) { + check(value, 1); + } + nalGetSourcei(source, param, memAddress(value)); + } + + /** + * Returns the integer value of the specified source parameter. + * + * @param source the source to query + * @param param the parameter to query. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ */ + @NativeType("ALvoid") + public static int alGetSourcei(@NativeType("ALuint") int source, @NativeType("ALenum") int param) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer value = stack.callocInt(1); + nalGetSourcei(source, param, memAddress(value)); + return value.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alGetSourceiv ] --- + + /** Unsafe version of: {@link #alGetSourceiv GetSourceiv} */ + public static void nalGetSourceiv(int source, int param, long values) { + long __functionAddress = AL.getICD().alGetSourceiv; + invokePV(source, param, values, __functionAddress); + } + + /** + * Returns the integer values of the specified source parameter. + * + * @param source the source to query + * @param param the parameter to query. One of:
{@link #AL_CONE_INNER_ANGLE CONE_INNER_ANGLE}{@link #AL_CONE_OUTER_ANGLE CONE_OUTER_ANGLE}{@link #AL_PITCH PITCH}{@link #AL_DIRECTION DIRECTION}{@link #AL_LOOPING LOOPING}{@link #AL_BUFFER BUFFER}{@link #AL_SOURCE_STATE SOURCE_STATE}
{@link #AL_CONE_OUTER_GAIN CONE_OUTER_GAIN}{@link #AL_SOURCE_TYPE SOURCE_TYPE}{@link #AL_POSITION POSITION}{@link #AL_VELOCITY VELOCITY}{@link #AL_GAIN GAIN}{@link #AL_REFERENCE_DISTANCE REFERENCE_DISTANCE}{@link #AL_ROLLOFF_FACTOR ROLLOFF_FACTOR}
{@link #AL_MAX_DISTANCE MAX_DISTANCE}
+ * @param values the parameter values + */ + @NativeType("ALvoid") + public static void alGetSourceiv(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALint *") IntBuffer values) { + if (CHECKS) { + check(values, 1); + } + nalGetSourceiv(source, param, memAddress(values)); + } + + // --- [ alSourceQueueBuffers ] --- + + /** + * Unsafe version of: {@link #alSourceQueueBuffers SourceQueueBuffers} + * + * @param numBuffers the number of buffers to queue + */ + public static void nalSourceQueueBuffers(int sourceName, int numBuffers, long bufferNames) { + long __functionAddress = AL.getICD().alSourceQueueBuffers; + invokePV(sourceName, numBuffers, bufferNames, __functionAddress); + } + + /** + * Queues up one or multiple buffer names to the specified source. + * + *

The buffers will be queued in the sequence in which they appear in the array. This command is legal on a source in any playback state (to allow for + * streaming, queuing has to be possible on a AL_PLAYING source). All buffers in a queue must have the same format and attributes, with the exception of + * the {@code NULL} buffer (i.e., 0) which can always be queued.

+ * + * @param sourceName the target source + * @param bufferNames the buffer names + */ + @NativeType("ALvoid") + public static void alSourceQueueBuffers(@NativeType("ALuint") int sourceName, @NativeType("ALuint *") IntBuffer bufferNames) { + nalSourceQueueBuffers(sourceName, bufferNames.remaining(), memAddress(bufferNames)); + } + + /** + * Queues up one or multiple buffer names to the specified source. + * + *

The buffers will be queued in the sequence in which they appear in the array. This command is legal on a source in any playback state (to allow for + * streaming, queuing has to be possible on a AL_PLAYING source). All buffers in a queue must have the same format and attributes, with the exception of + * the {@code NULL} buffer (i.e., 0) which can always be queued.

+ * + * @param sourceName the target source + */ + @NativeType("ALvoid") + public static void alSourceQueueBuffers(@NativeType("ALuint") int sourceName, @NativeType("ALuint *") int bufferName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer bufferNames = stack.ints(bufferName); + nalSourceQueueBuffers(sourceName, 1, memAddress(bufferNames)); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alSourceUnqueueBuffers ] --- + + /** + * Unsafe version of: {@link #alSourceUnqueueBuffers SourceUnqueueBuffers} + * + * @param numEntries the number of buffers to unqueue + */ + public static void nalSourceUnqueueBuffers(int sourceName, int numEntries, long bufferNames) { + long __functionAddress = AL.getICD().alSourceUnqueueBuffers; + invokePV(sourceName, numEntries, bufferNames, __functionAddress); + } + + /** + * Removes a number of buffer entries that have finished processing, in the order of apperance, from the queue of the specified source. + * + *

Once a queue entry for a buffer has been appended to a queue and is pending processing, it should not be changed. Removal of a given queue entry is not + * possible unless either the source is stopped (in which case then entire queue is considered processed), or if the queue entry has already been processed + * (AL_PLAYING or AL_PAUSED source). A playing source will enter the AL_STOPPED state if it completes playback of the last buffer in its queue (the same + * behavior as when a single buffer has been attached to a source and has finished playback).

+ * + * @param sourceName the target source + * @param bufferNames the buffer names + */ + @NativeType("ALvoid") + public static void alSourceUnqueueBuffers(@NativeType("ALuint") int sourceName, @NativeType("ALuint *") IntBuffer bufferNames) { + nalSourceUnqueueBuffers(sourceName, bufferNames.remaining(), memAddress(bufferNames)); + } + + /** + * Removes a number of buffer entries that have finished processing, in the order of apperance, from the queue of the specified source. + * + *

Once a queue entry for a buffer has been appended to a queue and is pending processing, it should not be changed. Removal of a given queue entry is not + * possible unless either the source is stopped (in which case then entire queue is considered processed), or if the queue entry has already been processed + * (AL_PLAYING or AL_PAUSED source). A playing source will enter the AL_STOPPED state if it completes playback of the last buffer in its queue (the same + * behavior as when a single buffer has been attached to a source and has finished playback).

+ * + * @param sourceName the target source + */ + @NativeType("ALvoid") + public static int alSourceUnqueueBuffers(@NativeType("ALuint") int sourceName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer bufferNames = stack.callocInt(1); + nalSourceUnqueueBuffers(sourceName, 1, memAddress(bufferNames)); + return bufferNames.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alSourcePlay ] --- + + /** + * Sets the source state to AL_PLAYING. + * + *

alSourcePlay applied to an AL_INITIAL source will promote the source to AL_PLAYING, thus the data found in the buffer will be fed into the processing, + * starting at the beginning. alSourcePlay applied to a AL_PLAYING source will restart the source from the beginning. It will not affect the configuration, + * and will leave the source in AL_PLAYING state, but reset the sampling offset to the beginning. alSourcePlay applied to a AL_PAUSED source will resume + * processing using the source state as preserved at the alSourcePause operation. alSourcePlay applied to a AL_STOPPED source will propagate it to + * AL_INITIAL then to AL_PLAYING immediately.

+ * + * @param source the source to play + */ + @NativeType("ALvoid") + public static void alSourcePlay(@NativeType("ALuint") int source) { + long __functionAddress = AL.getICD().alSourcePlay; + invokeV(source, __functionAddress); + } + + // --- [ alSourcePause ] --- + + /** + * Sets the source state to AL_PAUSED. + * + *

alSourcePause applied to an AL_INITIAL source is a legal NOP. alSourcePause applied to a AL_PLAYING source will change its state to AL_PAUSED. The + * source is exempt from processing, its current state is preserved. alSourcePause applied to a AL_PAUSED source is a legal NOP. alSourcePause applied to a + * AL_STOPPED source is a legal NOP.

+ * + * @param source the source to pause + */ + @NativeType("ALvoid") + public static void alSourcePause(@NativeType("ALuint") int source) { + long __functionAddress = AL.getICD().alSourcePause; + invokeV(source, __functionAddress); + } + + // --- [ alSourceStop ] --- + + /** + * Sets the source state to AL_STOPPED. + * + *

alSourceStop applied to an AL_INITIAL source is a legal NOP. alSourceStop applied to a AL_PLAYING source will change its state to AL_STOPPED. The source + * is exempt from processing, its current state is preserved. alSourceStop applied to a AL_PAUSED source will change its state to AL_STOPPED, with the same + * consequences as on a AL_PLAYING source. alSourceStop applied to a AL_STOPPED source is a legal NOP.

+ * + * @param source the source to stop + */ + @NativeType("ALvoid") + public static void alSourceStop(@NativeType("ALuint") int source) { + long __functionAddress = AL.getICD().alSourceStop; + invokeV(source, __functionAddress); + } + + // --- [ alSourceRewind ] --- + + /** + * Sets the source state to AL_INITIAL. + * + *

alSourceRewind applied to an AL_INITIAL source is a legal NOP. alSourceRewind applied to a AL_PLAYING source will change its state to AL_STOPPED then + * AL_INITIAL. The source is exempt from processing: its current state is preserved, with the exception of the sampling offset, which is reset to the + * beginning. alSourceRewind applied to a AL_PAUSED source will change its state to AL_INITIAL, with the same consequences as on a AL_PLAYING source. + * alSourceRewind applied to an AL_STOPPED source promotes the source to AL_INITIAL, resetting the sampling offset to the beginning.

+ * + * @param source the source to rewind + */ + @NativeType("ALvoid") + public static void alSourceRewind(@NativeType("ALuint") int source) { + long __functionAddress = AL.getICD().alSourceRewind; + invokeV(source, __functionAddress); + } + + // --- [ alSourcePlayv ] --- + + /** + * Unsafe version of: {@link #alSourcePlayv SourcePlayv} + * + * @param n the number of sources to play + */ + public static void nalSourcePlayv(int n, long sources) { + long __functionAddress = AL.getICD().alSourcePlayv; + invokePV(n, sources, __functionAddress); + } + + /** + * Pointer version of {@link #alSourcePlay SourcePlay}. + * + * @param sources the sources to play + */ + @NativeType("ALvoid") + public static void alSourcePlayv(@NativeType("ALuint const *") IntBuffer sources) { + nalSourcePlayv(sources.remaining(), memAddress(sources)); + } + + // --- [ alSourcePausev ] --- + + /** + * Unsafe version of: {@link #alSourcePausev SourcePausev} + * + * @param n the number of sources to pause + */ + public static void nalSourcePausev(int n, long sources) { + long __functionAddress = AL.getICD().alSourcePausev; + invokePV(n, sources, __functionAddress); + } + + /** + * Pointer version of {@link #alSourcePause SourcePause}. + * + * @param sources the sources to pause + */ + @NativeType("ALvoid") + public static void alSourcePausev(@NativeType("ALuint const *") IntBuffer sources) { + nalSourcePausev(sources.remaining(), memAddress(sources)); + } + + // --- [ alSourceStopv ] --- + + /** + * Unsafe version of: {@link #alSourceStopv SourceStopv} + * + * @param n the number of sources to stop + */ + public static void nalSourceStopv(int n, long sources) { + long __functionAddress = AL.getICD().alSourceStopv; + invokePV(n, sources, __functionAddress); + } + + /** + * Pointer version of {@link #alSourceStop SourceStop}. + * + * @param sources the sources to stop + */ + @NativeType("ALvoid") + public static void alSourceStopv(@NativeType("ALuint const *") IntBuffer sources) { + nalSourceStopv(sources.remaining(), memAddress(sources)); + } + + // --- [ alSourceRewindv ] --- + + /** + * Unsafe version of: {@link #alSourceRewindv SourceRewindv} + * + * @param n the number of sources to rewind + */ + public static void nalSourceRewindv(int n, long sources) { + long __functionAddress = AL.getICD().alSourceRewindv; + invokePV(n, sources, __functionAddress); + } + + /** + * Pointer version of {@link #alSourceRewind SourceRewind}. + * + * @param sources the sources to rewind + */ + @NativeType("ALvoid") + public static void alSourceRewindv(@NativeType("ALuint const *") IntBuffer sources) { + nalSourceRewindv(sources.remaining(), memAddress(sources)); + } + + // --- [ alGenBuffers ] --- + + /** + * Unsafe version of: {@link #alGenBuffers GenBuffers} + * + * @param n the number of buffer names to generate + */ + public static void nalGenBuffers(int n, long bufferNames) { + long __functionAddress = AL.getICD().alGenBuffers; + invokePV(n, bufferNames, __functionAddress); + } + + /** + * Requests a number of buffer names. + * + * @param bufferNames the buffer that will receive the buffer names + */ + @NativeType("ALvoid") + public static void alGenBuffers(@NativeType("ALuint *") IntBuffer bufferNames) { + nalGenBuffers(bufferNames.remaining(), memAddress(bufferNames)); + } + + /** Requests a number of buffer names. */ + @NativeType("ALvoid") + public static int alGenBuffers() { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer bufferNames = stack.callocInt(1); + nalGenBuffers(1, memAddress(bufferNames)); + return bufferNames.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alDeleteBuffers ] --- + + /** + * Unsafe version of: {@link #alDeleteBuffers DeleteBuffers} + * + * @param n the number of buffers to delete + */ + public static void nalDeleteBuffers(int n, long bufferNames) { + long __functionAddress = AL.getICD().alDeleteBuffers; + invokePV(n, bufferNames, __functionAddress); + } + + /** + * Requests the deletion of a number of buffers. + * + * @param bufferNames the buffers to delete + */ + @NativeType("ALvoid") + public static void alDeleteBuffers(@NativeType("ALuint const *") IntBuffer bufferNames) { + nalDeleteBuffers(bufferNames.remaining(), memAddress(bufferNames)); + } + + /** Requests the deletion of a number of buffers. */ + @NativeType("ALvoid") + public static void alDeleteBuffers(@NativeType("ALuint const *") int bufferName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer bufferNames = stack.ints(bufferName); + nalDeleteBuffers(1, memAddress(bufferNames)); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alIsBuffer ] --- + + /** + * Verifies whether the specified object name is a buffer name. + * + * @param bufferName a value that may be a buffer name + */ + @NativeType("ALboolean") + public static boolean alIsBuffer(@NativeType("ALuint") int bufferName) { + long __functionAddress = AL.getICD().alIsBuffer; + return invokeZ(bufferName, __functionAddress); + } + + // --- [ alGetBufferf ] --- + + /** Unsafe version of: {@link #alGetBufferf GetBufferf} */ + public static void nalGetBufferf(int bufferName, int paramName, long value) { + long __functionAddress = AL.getICD().alGetBufferf; + invokePV(bufferName, paramName, value, __functionAddress); + } + + /** + * Returns the float value of the specified buffer parameter. + * + * @param bufferName the buffer to query + * @param paramName the parameter to query. One of:
{@link #AL_FREQUENCY FREQUENCY}{@link #AL_BITS BITS}{@link #AL_CHANNELS CHANNELS}{@link #AL_SIZE SIZE}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alGetBufferf(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int paramName, @NativeType("ALfloat *") FloatBuffer value) { + if (CHECKS) { + check(value, 1); + } + nalGetBufferf(bufferName, paramName, memAddress(value)); + } + + /** + * Returns the float value of the specified buffer parameter. + * + * @param bufferName the buffer to query + * @param paramName the parameter to query. One of:
{@link #AL_FREQUENCY FREQUENCY}{@link #AL_BITS BITS}{@link #AL_CHANNELS CHANNELS}{@link #AL_SIZE SIZE}
+ */ + @NativeType("ALvoid") + public static float alGetBufferf(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int paramName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer value = stack.callocFloat(1); + nalGetBufferf(bufferName, paramName, memAddress(value)); + return value.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alGetBufferi ] --- + + /** Unsafe version of: {@link #alGetBufferi GetBufferi} */ + public static void nalGetBufferi(int bufferName, int paramName, long value) { + long __functionAddress = AL.getICD().alGetBufferi; + invokePV(bufferName, paramName, value, __functionAddress); + } + + /** + * Returns the integer value of the specified buffer parameter. + * + * @param bufferName the buffer to query + * @param paramName the parameter to query. One of:
{@link #AL_FREQUENCY FREQUENCY}{@link #AL_BITS BITS}{@link #AL_CHANNELS CHANNELS}{@link #AL_SIZE SIZE}
+ * @param value the parameter value + */ + @NativeType("ALvoid") + public static void alGetBufferi(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int paramName, @NativeType("ALint *") IntBuffer value) { + if (CHECKS) { + check(value, 1); + } + nalGetBufferi(bufferName, paramName, memAddress(value)); + } + + /** + * Returns the integer value of the specified buffer parameter. + * + * @param bufferName the buffer to query + * @param paramName the parameter to query. One of:
{@link #AL_FREQUENCY FREQUENCY}{@link #AL_BITS BITS}{@link #AL_CHANNELS CHANNELS}{@link #AL_SIZE SIZE}
+ */ + @NativeType("ALvoid") + public static int alGetBufferi(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int paramName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer value = stack.callocInt(1); + nalGetBufferi(bufferName, paramName, memAddress(value)); + return value.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alBufferData ] --- + + /** + * Unsafe version of: {@link #alBufferData BufferData} + * + * @param size the data buffer size, in bytes + */ + public static void nalBufferData(int bufferName, int format, long data, int size, int frequency) { + long __functionAddress = AL.getICD().alBufferData; + invokePV(bufferName, format, data, size, frequency, __functionAddress); + } + + /** + * Sets the sample data of the specified buffer. + * + *

The data specified is copied to an internal software, or if possible, hardware buffer. The implementation is free to apply decompression, conversion, + * resampling, and filtering as needed.

+ * + *

8-bit data is expressed as an unsigned value over the range 0 to 255, 128 being an audio output level of zero.

+ * + *

16-bit data is expressed as a signed value over the range -32768 to 32767, 0 being an audio output level of zero. Byte order for 16-bit values is + * determined by the native format of the CPU.

+ * + *

Stereo data is expressed in an interleaved format, left channel sample followed by the right channel sample.

+ * + *

Buffers containing audio data with more than one channel will be played without 3D spatialization features – these formats are normally used for + * background music.

+ * + * @param bufferName the buffer to modify + * @param format the data format. One of:
{@link #AL_FORMAT_MONO8 FORMAT_MONO8}{@link #AL_FORMAT_MONO16 FORMAT_MONO16}{@link #AL_FORMAT_STEREO8 FORMAT_STEREO8}{@link #AL_FORMAT_STEREO16 FORMAT_STEREO16}
+ * @param data the sample data + * @param frequency the data frequency + */ + @NativeType("ALvoid") + public static void alBufferData(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int format, @NativeType("ALvoid const *") ByteBuffer data, @NativeType("ALsizei") int frequency) { + nalBufferData(bufferName, format, memAddress(data), data.remaining(), frequency); + } + + /** + * Sets the sample data of the specified buffer. + * + *

The data specified is copied to an internal software, or if possible, hardware buffer. The implementation is free to apply decompression, conversion, + * resampling, and filtering as needed.

+ * + *

8-bit data is expressed as an unsigned value over the range 0 to 255, 128 being an audio output level of zero.

+ * + *

16-bit data is expressed as a signed value over the range -32768 to 32767, 0 being an audio output level of zero. Byte order for 16-bit values is + * determined by the native format of the CPU.

+ * + *

Stereo data is expressed in an interleaved format, left channel sample followed by the right channel sample.

+ * + *

Buffers containing audio data with more than one channel will be played without 3D spatialization features – these formats are normally used for + * background music.

+ * + * @param bufferName the buffer to modify + * @param format the data format. One of:
{@link #AL_FORMAT_MONO8 FORMAT_MONO8}{@link #AL_FORMAT_MONO16 FORMAT_MONO16}{@link #AL_FORMAT_STEREO8 FORMAT_STEREO8}{@link #AL_FORMAT_STEREO16 FORMAT_STEREO16}
+ * @param data the sample data + * @param frequency the data frequency + */ + @NativeType("ALvoid") + public static void alBufferData(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int format, @NativeType("ALvoid const *") ShortBuffer data, @NativeType("ALsizei") int frequency) { + nalBufferData(bufferName, format, memAddress(data), data.remaining() << 1, frequency); + } + + /** + * Sets the sample data of the specified buffer. + * + *

The data specified is copied to an internal software, or if possible, hardware buffer. The implementation is free to apply decompression, conversion, + * resampling, and filtering as needed.

+ * + *

8-bit data is expressed as an unsigned value over the range 0 to 255, 128 being an audio output level of zero.

+ * + *

16-bit data is expressed as a signed value over the range -32768 to 32767, 0 being an audio output level of zero. Byte order for 16-bit values is + * determined by the native format of the CPU.

+ * + *

Stereo data is expressed in an interleaved format, left channel sample followed by the right channel sample.

+ * + *

Buffers containing audio data with more than one channel will be played without 3D spatialization features – these formats are normally used for + * background music.

+ * + * @param bufferName the buffer to modify + * @param format the data format. One of:
{@link #AL_FORMAT_MONO8 FORMAT_MONO8}{@link #AL_FORMAT_MONO16 FORMAT_MONO16}{@link #AL_FORMAT_STEREO8 FORMAT_STEREO8}{@link #AL_FORMAT_STEREO16 FORMAT_STEREO16}
+ * @param data the sample data + * @param frequency the data frequency + */ + @NativeType("ALvoid") + public static void alBufferData(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int format, @NativeType("ALvoid const *") IntBuffer data, @NativeType("ALsizei") int frequency) { + nalBufferData(bufferName, format, memAddress(data), data.remaining() << 2, frequency); + } + + /** + * Sets the sample data of the specified buffer. + * + *

The data specified is copied to an internal software, or if possible, hardware buffer. The implementation is free to apply decompression, conversion, + * resampling, and filtering as needed.

+ * + *

8-bit data is expressed as an unsigned value over the range 0 to 255, 128 being an audio output level of zero.

+ * + *

16-bit data is expressed as a signed value over the range -32768 to 32767, 0 being an audio output level of zero. Byte order for 16-bit values is + * determined by the native format of the CPU.

+ * + *

Stereo data is expressed in an interleaved format, left channel sample followed by the right channel sample.

+ * + *

Buffers containing audio data with more than one channel will be played without 3D spatialization features – these formats are normally used for + * background music.

+ * + * @param bufferName the buffer to modify + * @param format the data format. One of:
{@link #AL_FORMAT_MONO8 FORMAT_MONO8}{@link #AL_FORMAT_MONO16 FORMAT_MONO16}{@link #AL_FORMAT_STEREO8 FORMAT_STEREO8}{@link #AL_FORMAT_STEREO16 FORMAT_STEREO16}
+ * @param data the sample data + * @param frequency the data frequency + */ + @NativeType("ALvoid") + public static void alBufferData(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int format, @NativeType("ALvoid const *") FloatBuffer data, @NativeType("ALsizei") int frequency) { + nalBufferData(bufferName, format, memAddress(data), data.remaining() << 2, frequency); + } + + // --- [ alGetEnumValue ] --- + + /** Unsafe version of: {@link #alGetEnumValue GetEnumValue} */ + public static int nalGetEnumValue(long enumName) { + long __functionAddress = AL.getICD().alGetEnumValue; + return invokePI(enumName, __functionAddress); + } + + /** + * Returns the enumeration value of the specified enum. + * + * @param enumName the enum name + */ + @NativeType("ALuint") + public static int alGetEnumValue(@NativeType("ALchar const *") ByteBuffer enumName) { + if (CHECKS) { + checkNT1(enumName); + } + return nalGetEnumValue(memAddress(enumName)); + } + + /** + * Returns the enumeration value of the specified enum. + * + * @param enumName the enum name + */ + @NativeType("ALuint") + public static int alGetEnumValue(@NativeType("ALchar const *") CharSequence enumName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nASCII(enumName, true); + long enumNameEncoded = stack.getPointerAddress(); + return nalGetEnumValue(enumNameEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alGetProcAddress ] --- + + /** Unsafe version of: {@link #alGetProcAddress GetProcAddress} */ + public static long nalGetProcAddress(long funcName) { + long __functionAddress = AL.getICD().alGetProcAddress; + return invokePP(funcName, __functionAddress); + } + + /** + * Retrieves extension entry points. + * + *

Returns {@code NULL} if no entry point with the name funcName can be found. Implementations are free to return {@code NULL} if an entry point is present, but not + * applicable for the current context. However the specification does not guarantee this behavior.

+ * + *

Applications can use alGetProcAddress to obtain core API entry points, not just extensions. This is the recommended way to dynamically load and unload + * OpenAL DLL's as sound drivers.

+ * + * @param funcName the function name + */ + @NativeType("void *") + public static long alGetProcAddress(@NativeType("ALchar const *") ByteBuffer funcName) { + if (CHECKS) { + checkNT1(funcName); + } + return nalGetProcAddress(memAddress(funcName)); + } + + /** + * Retrieves extension entry points. + * + *

Returns {@code NULL} if no entry point with the name funcName can be found. Implementations are free to return {@code NULL} if an entry point is present, but not + * applicable for the current context. However the specification does not guarantee this behavior.

+ * + *

Applications can use alGetProcAddress to obtain core API entry points, not just extensions. This is the recommended way to dynamically load and unload + * OpenAL DLL's as sound drivers.

+ * + * @param funcName the function name + */ + @NativeType("void *") + public static long alGetProcAddress(@NativeType("ALchar const *") CharSequence funcName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nASCII(funcName, true); + long funcNameEncoded = stack.getPointerAddress(); + return nalGetProcAddress(funcNameEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alIsExtensionPresent ] --- + + /** Unsafe version of: {@link #alIsExtensionPresent IsExtensionPresent} */ + public static boolean nalIsExtensionPresent(long extName) { + long __functionAddress = AL.getICD().alIsExtensionPresent; + return invokePZ(extName, __functionAddress); + } + + /** + * Verifies that a given extension is available for the current context and the device it is associated with. + * + *

Invalid and unsupported string tokens return ALC_FALSE. {@code extName} is not case sensitive – the implementation will convert the name to all + * upper-case internally (and will express extension names in upper-case).

+ * + * @param extName the extension name + */ + @NativeType("ALCboolean") + public static boolean alIsExtensionPresent(@NativeType("ALchar const *") ByteBuffer extName) { + if (CHECKS) { + checkNT1(extName); + } + return nalIsExtensionPresent(memAddress(extName)); + } + + /** + * Verifies that a given extension is available for the current context and the device it is associated with. + * + *

Invalid and unsupported string tokens return ALC_FALSE. {@code extName} is not case sensitive – the implementation will convert the name to all + * upper-case internally (and will express extension names in upper-case).

+ * + * @param extName the extension name + */ + @NativeType("ALCboolean") + public static boolean alIsExtensionPresent(@NativeType("ALchar const *") CharSequence extName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nASCII(extName, true); + long extNameEncoded = stack.getPointerAddress(); + return nalIsExtensionPresent(extNameEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + /** Array version of: {@link #alGetIntegerv GetIntegerv} */ + @NativeType("ALvoid") + public static void alGetIntegerv(@NativeType("ALenum") int paramName, @NativeType("ALint *") int[] dest) { + long __functionAddress = AL.getICD().alGetIntegerv; + if (CHECKS) { + check(dest, 1); + } + invokePV(paramName, dest, __functionAddress); + } + + /** Array version of: {@link #alGetFloatv GetFloatv} */ + @NativeType("ALvoid") + public static void alGetFloatv(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") float[] dest) { + long __functionAddress = AL.getICD().alGetFloatv; + if (CHECKS) { + check(dest, 1); + } + invokePV(paramName, dest, __functionAddress); + } + + /** Array version of: {@link #alGetDoublev GetDoublev} */ + @NativeType("ALvoid") + public static void alGetDoublev(@NativeType("ALenum") int paramName, @NativeType("ALdouble *") double[] dest) { + long __functionAddress = AL.getICD().alGetDoublev; + if (CHECKS) { + check(dest, 1); + } + invokePV(paramName, dest, __functionAddress); + } + + /** Array version of: {@link #alListenerfv Listenerfv} */ + @NativeType("ALvoid") + public static void alListenerfv(@NativeType("ALenum") int paramName, @NativeType("ALfloat const *") float[] values) { + long __functionAddress = AL.getICD().alListenerfv; + if (CHECKS) { + check(values, 1); + } + invokePV(paramName, values, __functionAddress); + } + + /** Array version of: {@link #alGetListenerf GetListenerf} */ + @NativeType("ALvoid") + public static void alGetListenerf(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") float[] value) { + long __functionAddress = AL.getICD().alGetListenerf; + if (CHECKS) { + check(value, 1); + } + invokePV(paramName, value, __functionAddress); + } + + /** Array version of: {@link #alGetListeneri GetListeneri} */ + @NativeType("ALvoid") + public static void alGetListeneri(@NativeType("ALenum") int paramName, @NativeType("ALint *") int[] value) { + long __functionAddress = AL.getICD().alGetListeneri; + if (CHECKS) { + check(value, 1); + } + invokePV(paramName, value, __functionAddress); + } + + /** Array version of: {@link #alGetListener3f GetListener3f} */ + @NativeType("ALvoid") + public static void alGetListener3f(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") float[] value1, @NativeType("ALfloat *") float[] value2, @NativeType("ALfloat *") float[] value3) { + long __functionAddress = AL.getICD().alGetListener3f; + if (CHECKS) { + check(value1, 1); + check(value2, 1); + check(value3, 1); + } + invokePPPV(paramName, value1, value2, value3, __functionAddress); + } + + /** Array version of: {@link #alGetListenerfv GetListenerfv} */ + @NativeType("ALvoid") + public static void alGetListenerfv(@NativeType("ALenum") int paramName, @NativeType("ALfloat *") float[] values) { + long __functionAddress = AL.getICD().alGetListenerfv; + if (CHECKS) { + check(values, 1); + } + invokePV(paramName, values, __functionAddress); + } + + /** Array version of: {@link #alGenSources GenSources} */ + @NativeType("ALvoid") + public static void alGenSources(@NativeType("ALuint *") int[] srcNames) { + long __functionAddress = AL.getICD().alGenSources; + invokePV(srcNames.length, srcNames, __functionAddress); + } + + /** Array version of: {@link #alDeleteSources DeleteSources} */ + @NativeType("ALvoid") + public static void alDeleteSources(@NativeType("ALuint *") int[] sources) { + long __functionAddress = AL.getICD().alDeleteSources; + invokePV(sources.length, sources, __functionAddress); + } + + /** Array version of: {@link #alSourcefv Sourcefv} */ + @NativeType("ALvoid") + public static void alSourcefv(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat const *") float[] values) { + long __functionAddress = AL.getICD().alSourcefv; + if (CHECKS) { + check(values, 1); + } + invokePV(source, param, values, __functionAddress); + } + + /** Array version of: {@link #alGetSourcef GetSourcef} */ + @NativeType("ALvoid") + public static void alGetSourcef(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat *") float[] value) { + long __functionAddress = AL.getICD().alGetSourcef; + if (CHECKS) { + check(value, 1); + } + invokePV(source, param, value, __functionAddress); + } + + /** Array version of: {@link #alGetSource3f GetSource3f} */ + @NativeType("ALvoid") + public static void alGetSource3f(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat *") float[] v1, @NativeType("ALfloat *") float[] v2, @NativeType("ALfloat *") float[] v3) { + long __functionAddress = AL.getICD().alGetSource3f; + if (CHECKS) { + check(v1, 1); + check(v2, 1); + check(v3, 1); + } + invokePPPV(source, param, v1, v2, v3, __functionAddress); + } + + /** Array version of: {@link #alGetSourcefv GetSourcefv} */ + @NativeType("ALvoid") + public static void alGetSourcefv(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALfloat *") float[] values) { + long __functionAddress = AL.getICD().alGetSourcefv; + if (CHECKS) { + check(values, 1); + } + invokePV(source, param, values, __functionAddress); + } + + /** Array version of: {@link #alGetSourcei GetSourcei} */ + @NativeType("ALvoid") + public static void alGetSourcei(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALint *") int[] value) { + long __functionAddress = AL.getICD().alGetSourcei; + if (CHECKS) { + check(value, 1); + } + invokePV(source, param, value, __functionAddress); + } + + /** Array version of: {@link #alGetSourceiv GetSourceiv} */ + @NativeType("ALvoid") + public static void alGetSourceiv(@NativeType("ALuint") int source, @NativeType("ALenum") int param, @NativeType("ALint *") int[] values) { + long __functionAddress = AL.getICD().alGetSourceiv; + if (CHECKS) { + check(values, 1); + } + invokePV(source, param, values, __functionAddress); + } + + /** Array version of: {@link #alSourceQueueBuffers SourceQueueBuffers} */ + @NativeType("ALvoid") + public static void alSourceQueueBuffers(@NativeType("ALuint") int sourceName, @NativeType("ALuint *") int[] bufferNames) { + long __functionAddress = AL.getICD().alSourceQueueBuffers; + invokePV(sourceName, bufferNames.length, bufferNames, __functionAddress); + } + + /** Array version of: {@link #alSourceUnqueueBuffers SourceUnqueueBuffers} */ + @NativeType("ALvoid") + public static void alSourceUnqueueBuffers(@NativeType("ALuint") int sourceName, @NativeType("ALuint *") int[] bufferNames) { + long __functionAddress = AL.getICD().alSourceUnqueueBuffers; + invokePV(sourceName, bufferNames.length, bufferNames, __functionAddress); + } + + /** Array version of: {@link #alSourcePlayv SourcePlayv} */ + @NativeType("ALvoid") + public static void alSourcePlayv(@NativeType("ALuint const *") int[] sources) { + long __functionAddress = AL.getICD().alSourcePlayv; + invokePV(sources.length, sources, __functionAddress); + } + + /** Array version of: {@link #alSourcePausev SourcePausev} */ + @NativeType("ALvoid") + public static void alSourcePausev(@NativeType("ALuint const *") int[] sources) { + long __functionAddress = AL.getICD().alSourcePausev; + invokePV(sources.length, sources, __functionAddress); + } + + /** Array version of: {@link #alSourceStopv SourceStopv} */ + @NativeType("ALvoid") + public static void alSourceStopv(@NativeType("ALuint const *") int[] sources) { + long __functionAddress = AL.getICD().alSourceStopv; + invokePV(sources.length, sources, __functionAddress); + } + + /** Array version of: {@link #alSourceRewindv SourceRewindv} */ + @NativeType("ALvoid") + public static void alSourceRewindv(@NativeType("ALuint const *") int[] sources) { + long __functionAddress = AL.getICD().alSourceRewindv; + invokePV(sources.length, sources, __functionAddress); + } + + /** Array version of: {@link #alGenBuffers GenBuffers} */ + @NativeType("ALvoid") + public static void alGenBuffers(@NativeType("ALuint *") int[] bufferNames) { + long __functionAddress = AL.getICD().alGenBuffers; + invokePV(bufferNames.length, bufferNames, __functionAddress); + } + + /** Array version of: {@link #alDeleteBuffers DeleteBuffers} */ + @NativeType("ALvoid") + public static void alDeleteBuffers(@NativeType("ALuint const *") int[] bufferNames) { + long __functionAddress = AL.getICD().alDeleteBuffers; + invokePV(bufferNames.length, bufferNames, __functionAddress); + } + + /** Array version of: {@link #alGetBufferf GetBufferf} */ + @NativeType("ALvoid") + public static void alGetBufferf(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int paramName, @NativeType("ALfloat *") float[] value) { + long __functionAddress = AL.getICD().alGetBufferf; + if (CHECKS) { + check(value, 1); + } + invokePV(bufferName, paramName, value, __functionAddress); + } + + /** Array version of: {@link #alGetBufferi GetBufferi} */ + @NativeType("ALvoid") + public static void alGetBufferi(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int paramName, @NativeType("ALint *") int[] value) { + long __functionAddress = AL.getICD().alGetBufferi; + if (CHECKS) { + check(value, 1); + } + invokePV(bufferName, paramName, value, __functionAddress); + } + + /** Array version of: {@link #alBufferData BufferData} */ + @NativeType("ALvoid") + public static void alBufferData(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int format, @NativeType("ALvoid const *") short[] data, @NativeType("ALsizei") int frequency) { + long __functionAddress = AL.getICD().alBufferData; + invokePV(bufferName, format, data, data.length << 1, frequency, __functionAddress); + } + + /** Array version of: {@link #alBufferData BufferData} */ + @NativeType("ALvoid") + public static void alBufferData(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int format, @NativeType("ALvoid const *") int[] data, @NativeType("ALsizei") int frequency) { + long __functionAddress = AL.getICD().alBufferData; + invokePV(bufferName, format, data, data.length << 2, frequency, __functionAddress); + } + + /** Array version of: {@link #alBufferData BufferData} */ + @NativeType("ALvoid") + public static void alBufferData(@NativeType("ALuint") int bufferName, @NativeType("ALenum") int format, @NativeType("ALvoid const *") float[] data, @NativeType("ALsizei") int frequency) { + long __functionAddress = AL.getICD().alBufferData; + invokePV(bufferName, format, data, data.length << 2, frequency, __functionAddress); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALC10.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALC10.java new file mode 100644 index 000000000..5d52edd3f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALC10.java @@ -0,0 +1,530 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.openal; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.MemoryUtil.*; + +/** Native bindings to ALC 1.0 functionality. */ +public class ALC10 { + + /** General tokens. */ + public static final int + ALC_INVALID = 0xFFFFFFFF, + ALC_FALSE = 0x0, + ALC_TRUE = 0x1; + + /** Context creation attributes. */ + public static final int + ALC_FREQUENCY = 0x1007, + ALC_REFRESH = 0x1008, + ALC_SYNC = 0x1009; + + /** Error conditions. */ + public static final int + ALC_NO_ERROR = 0x0, + ALC_INVALID_DEVICE = 0xA001, + ALC_INVALID_CONTEXT = 0xA002, + ALC_INVALID_ENUM = 0xA003, + ALC_INVALID_VALUE = 0xA004, + ALC_OUT_OF_MEMORY = 0xA005; + + /** String queries. */ + public static final int + ALC_DEFAULT_DEVICE_SPECIFIER = 0x1004, + ALC_DEVICE_SPECIFIER = 0x1005, + ALC_EXTENSIONS = 0x1006; + + /** Integer queries. */ + public static final int + ALC_MAJOR_VERSION = 0x1000, + ALC_MINOR_VERSION = 0x1001, + ALC_ATTRIBUTES_SIZE = 0x1002, + ALC_ALL_ATTRIBUTES = 0x1003; + + protected ALC10() { + throw new UnsupportedOperationException(); + } + + static boolean isAvailable(ALCCapabilities caps) { + return checkFunctions( + caps.alcOpenDevice, caps.alcCloseDevice, caps.alcCreateContext, caps.alcMakeContextCurrent, caps.alcProcessContext, caps.alcSuspendContext, + caps.alcDestroyContext, caps.alcGetCurrentContext, caps.alcGetContextsDevice, caps.alcIsExtensionPresent, caps.alcGetProcAddress, + caps.alcGetEnumValue, caps.alcGetError, caps.alcGetString, caps.alcGetIntegerv + ); + } + +// -- Begin LWJGL2 -- + static ALCcontext alcContext; + + public static ALCcontext alcCreateContext(ALCdevice device, java.nio.IntBuffer attrList) { + long alContextHandle = alcCreateContext(device.device, attrList); + alcContext = new ALCcontext(alContextHandle); + return alcContext; + } + + // FIXME if Minecraft 1.12.2 and below crashes here! +/* + public static ALCcontext alcGetCurrentContext() { + return alcContext; + } +*/ + public static ALCdevice alcGetContextsDevice(ALCcontext context) { + return AL.alcDevice; + } + + public static void alcGetInteger(ALCdevice device, int pname, java.nio.IntBuffer integerdata) { + int res = alcGetInteger(device.device, pname); + integerdata.put(0, res); + } +// -- End LWJGL2 -- + + // --- [ alcOpenDevice ] --- + + /** Unsafe version of: {@link #alcOpenDevice OpenDevice} */ + public static long nalcOpenDevice(long deviceSpecifier) { + long __functionAddress = ALC.getICD().alcOpenDevice; + return invokePP(deviceSpecifier, __functionAddress); + } + + /** + * Allows the application to connect to a device. + * + *

If the function returns {@code NULL}, then no sound driver/device has been found. The argument is a null terminated string that requests a certain device or + * device configuration. If {@code NULL} is specified, the implementation will provide an implementation specific default.

+ * + * @param deviceSpecifier the requested device or device configuration + */ + @NativeType("ALCdevice *") + public static long alcOpenDevice(@Nullable @NativeType("ALCchar const *") ByteBuffer deviceSpecifier) { + if (CHECKS) { + checkNT1Safe(deviceSpecifier); + } + return nalcOpenDevice(memAddressSafe(deviceSpecifier)); + } + + /** + * Allows the application to connect to a device. + * + *

If the function returns {@code NULL}, then no sound driver/device has been found. The argument is a null terminated string that requests a certain device or + * device configuration. If {@code NULL} is specified, the implementation will provide an implementation specific default.

+ * + * @param deviceSpecifier the requested device or device configuration + */ + @NativeType("ALCdevice *") + public static long alcOpenDevice(@Nullable @NativeType("ALCchar const *") CharSequence deviceSpecifier) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nUTF8Safe(deviceSpecifier, true); + long deviceSpecifierEncoded = deviceSpecifier == null ? NULL : stack.getPointerAddress(); + return nalcOpenDevice(deviceSpecifierEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alcCloseDevice ] --- + + /** + * Allows the application to disconnect from a device. + * + *

The return code will be ALC_TRUE or ALC_FALSE, indicating success or failure. Failure will occur if all the device's contexts and buffers have not been + * destroyed. Once closed, the {@code deviceHandle} is invalid.

+ * + * @param deviceHandle the device to close + */ + @NativeType("ALCboolean") + public static boolean alcCloseDevice(@NativeType("ALCdevice const *") long deviceHandle) { + long __functionAddress = ALC.getICD().alcCloseDevice; + if (CHECKS) { + check(deviceHandle); + } + return invokePZ(deviceHandle, __functionAddress); + } + + // --- [ alcCreateContext ] --- + + /** Unsafe version of: {@link #alcCreateContext CreateContext} */ + public static long nalcCreateContext(long deviceHandle, long attrList) { + long __functionAddress = ALC.getICD().alcCreateContext; + if (CHECKS) { + check(deviceHandle); + } + return invokePPP(deviceHandle, attrList, __functionAddress); + } + + /** + * Creates an AL context. + * + * @param deviceHandle a valid device + * @param attrList null or a zero terminated list of integer pairs composed of valid ALC attribute tokens and requested values. One of:
{@link #ALC_FREQUENCY FREQUENCY}{@link #ALC_REFRESH REFRESH}{@link #ALC_SYNC SYNC}{@link ALC11#ALC_MONO_SOURCES MONO_SOURCES}{@link ALC11#ALC_STEREO_SOURCES STEREO_SOURCES}
+ */ + @NativeType("ALCcontext *") + public static long alcCreateContext(@NativeType("ALCdevice const *") long deviceHandle, @Nullable @NativeType("ALCint const *") IntBuffer attrList) { + if (CHECKS) { + checkNTSafe(attrList); + } + return nalcCreateContext(deviceHandle, memAddressSafe(attrList)); + } + + // --- [ alcMakeContextCurrent ] --- + + /** + * Makes a context current with respect to OpenAL operation. + * + *

The context parameter can be {@code NULL} or a valid context pointer. Using {@code NULL} results in no context being current, which is useful when shutting OpenAL down. + * The operation will apply to the device that the context was created for.

+ * + *

For each OS process (usually this means for each application), only one context can be current at any given time. All AL commands apply to the current + * context. Commands that affect objects shared among contexts (e.g. buffers) have side effects on other contexts.

+ * + * @param context the context to make current + */ + @NativeType("ALCboolean") + public static boolean alcMakeContextCurrent(@NativeType("ALCcontext *") long context) { + long __functionAddress = ALC.getICD().alcMakeContextCurrent; + return invokePZ(context, __functionAddress); + } + + // --- [ alcProcessContext ] --- + + /** + * The current context is the only context accessible to state changes by AL commands (aside from state changes affecting shared objects). However, + * multiple contexts can be processed at the same time. To indicate that a context should be processed (i.e. that internal execution state such as the + * offset increments are to be performed), the application uses {@code alcProcessContext}. + * + *

Repeated calls to alcProcessContext are legal, and do not affect a context that is already marked as processing. The default state of a context created + * by alcCreateContext is that it is processing.

+ * + * @param context the context to mark for processing + */ + @NativeType("ALCvoid") + public static void alcProcessContext(@NativeType("ALCcontext *") long context) { + long __functionAddress = ALC.getICD().alcProcessContext; + if (CHECKS) { + check(context); + } + invokePV(context, __functionAddress); + } + + // --- [ alcSuspendContext ] --- + + /** + * The application can suspend any context from processing (including the current one). To indicate that a context should be suspended from processing + * (i.e. that internal execution state such as offset increments are not to be changed), the application uses {@code alcSuspendContext}. + * + *

Repeated calls to alcSuspendContext are legal, and do not affect a context that is already marked as suspended.

+ * + * @param context the context to mark as suspended + */ + @NativeType("ALCvoid") + public static void alcSuspendContext(@NativeType("ALCcontext *") long context) { + long __functionAddress = ALC.getICD().alcSuspendContext; + if (CHECKS) { + check(context); + } + invokePV(context, __functionAddress); + } + + // --- [ alcDestroyContext ] --- + + /** + * Destroys a context. + * + *

The correct way to destroy a context is to first release it using alcMakeCurrent with a {@code NULL} context. Applications should not attempt to destroy a + * current context – doing so will not work and will result in an ALC_INVALID_OPERATION error. All sources within a context will automatically be deleted + * during context destruction.

+ * + * @param context the context to destroy + */ + @NativeType("ALCvoid") + public static void alcDestroyContext(@NativeType("ALCcontext *") long context) { + long __functionAddress = ALC.getICD().alcDestroyContext; + if (CHECKS) { + check(context); + } + invokePV(context, __functionAddress); + } + + // --- [ alcGetCurrentContext ] --- + + /** Queries for, and obtains a handle to, the current context for the application. If there is no current context, {@code NULL} is returned. */ + @NativeType("ALCcontext *") + public static long alcGetCurrentContext() { + long __functionAddress = ALC.getICD().alcGetCurrentContext; + return invokeP(__functionAddress); + } + + // --- [ alcGetContextsDevice ] --- + + /** + * Queries for, and obtains a handle to, the device of a given context. + * + * @param context the context to query + */ + @NativeType("ALCdevice *") + public static long alcGetContextsDevice(@NativeType("ALCcontext *") long context) { + long __functionAddress = ALC.getICD().alcGetContextsDevice; + if (CHECKS) { + check(context); + } + return invokePP(context, __functionAddress); + } + + // --- [ alcIsExtensionPresent ] --- + + /** Unsafe version of: {@link #alcIsExtensionPresent IsExtensionPresent} */ + public static boolean nalcIsExtensionPresent(long deviceHandle, long extName) { + long __functionAddress = ALC.getICD().alcIsExtensionPresent; + return invokePPZ(deviceHandle, extName, __functionAddress); + } + + /** + * Verifies that a given extension is available for the current context and the device it is associated with. + * + *

Invalid and unsupported string tokens return ALC_FALSE. A {@code NULL} deviceHandle is acceptable. {@code extName} is not case sensitive – the implementation + * will convert the name to all upper-case internally (and will express extension names in upper-case).

+ * + * @param deviceHandle the device to query + * @param extName the extension name + */ + @NativeType("ALCboolean") + public static boolean alcIsExtensionPresent(@NativeType("ALCdevice const *") long deviceHandle, @NativeType("ALCchar const *") ByteBuffer extName) { + if (CHECKS) { + checkNT1(extName); + } + return nalcIsExtensionPresent(deviceHandle, memAddress(extName)); + } + + /** + * Verifies that a given extension is available for the current context and the device it is associated with. + * + *

Invalid and unsupported string tokens return ALC_FALSE. A {@code NULL} deviceHandle is acceptable. {@code extName} is not case sensitive – the implementation + * will convert the name to all upper-case internally (and will express extension names in upper-case).

+ * + * @param deviceHandle the device to query + * @param extName the extension name + */ + @NativeType("ALCboolean") + public static boolean alcIsExtensionPresent(@NativeType("ALCdevice const *") long deviceHandle, @NativeType("ALCchar const *") CharSequence extName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nASCII(extName, true); + long extNameEncoded = stack.getPointerAddress(); + return nalcIsExtensionPresent(deviceHandle, extNameEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alcGetProcAddress ] --- + + /** Unsafe version of: {@link #alcGetProcAddress GetProcAddress} */ + public static long nalcGetProcAddress(long deviceHandle, long funcName) { + long __functionAddress = ALC.getICD().alcGetProcAddress; + return invokePPP(deviceHandle, funcName, __functionAddress); + } + + /** + * Retrieves extension entry points. + * + *

The application is expected to verify the applicability of an extension or core function entry point before requesting it by name, by use of + * {@link #alcIsExtensionPresent IsExtensionPresent}.

+ * + *

Entry points can be device specific, but are not context specific. Using a {@code NULL} device handle does not guarantee that the entry point is returned, + * even if available for one of the available devices.

+ * + * @param deviceHandle the device to query + * @param funcName the function name + */ + @NativeType("void *") + public static long alcGetProcAddress(@NativeType("ALCdevice const *") long deviceHandle, @NativeType("ALchar const *") ByteBuffer funcName) { + if (CHECKS) { + checkNT1(funcName); + } + return nalcGetProcAddress(deviceHandle, memAddress(funcName)); + } + + /** + * Retrieves extension entry points. + * + *

The application is expected to verify the applicability of an extension or core function entry point before requesting it by name, by use of + * {@link #alcIsExtensionPresent IsExtensionPresent}.

+ * + *

Entry points can be device specific, but are not context specific. Using a {@code NULL} device handle does not guarantee that the entry point is returned, + * even if available for one of the available devices.

+ * + * @param deviceHandle the device to query + * @param funcName the function name + */ + @NativeType("void *") + public static long alcGetProcAddress(@NativeType("ALCdevice const *") long deviceHandle, @NativeType("ALchar const *") CharSequence funcName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nASCII(funcName, true); + long funcNameEncoded = stack.getPointerAddress(); + return nalcGetProcAddress(deviceHandle, funcNameEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alcGetEnumValue ] --- + + /** Unsafe version of: {@link #alcGetEnumValue GetEnumValue} */ + public static int nalcGetEnumValue(long deviceHandle, long enumName) { + long __functionAddress = ALC.getICD().alcGetEnumValue; + return invokePPI(deviceHandle, enumName, __functionAddress); + } + + /** + * Returns extension enum values. + * + *

Enumeration/token values are device independent, but tokens defined for extensions might not be present for a given device. Using a {@code NULL} handle is + * legal, but only the tokens defined by the AL core are guaranteed. Availability of extension tokens depends on the ALC extension.

+ * + * @param deviceHandle the device to query + * @param enumName the enum name + */ + @NativeType("ALCenum") + public static int alcGetEnumValue(@NativeType("ALCdevice const *") long deviceHandle, @NativeType("ALCchar const *") ByteBuffer enumName) { + if (CHECKS) { + checkNT1(enumName); + } + return nalcGetEnumValue(deviceHandle, memAddress(enumName)); + } + + /** + * Returns extension enum values. + * + *

Enumeration/token values are device independent, but tokens defined for extensions might not be present for a given device. Using a {@code NULL} handle is + * legal, but only the tokens defined by the AL core are guaranteed. Availability of extension tokens depends on the ALC extension.

+ * + * @param deviceHandle the device to query + * @param enumName the enum name + */ + @NativeType("ALCenum") + public static int alcGetEnumValue(@NativeType("ALCdevice const *") long deviceHandle, @NativeType("ALCchar const *") CharSequence enumName) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nASCII(enumName, true); + long enumNameEncoded = stack.getPointerAddress(); + return nalcGetEnumValue(deviceHandle, enumNameEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ alcGetError ] --- + + /** + * Queries ALC errors. + * + *

ALC uses the same conventions and mechanisms as AL for error handling. In particular, ALC does not use conventions derived from X11 (GLX) or Windows + * (WGL).

+ * + *

Error conditions are specific to the device, and (like AL) a call to alcGetError resets the error state.

+ * + * @param deviceHandle the device to query + */ + @NativeType("ALCenum") + public static int alcGetError(@NativeType("ALCdevice *") long deviceHandle) { + long __functionAddress = ALC.getICD().alcGetError; + return invokePI(deviceHandle, __functionAddress); + } + + // --- [ alcGetString ] --- + + /** Unsafe version of: {@link #alcGetString GetString} */ + public static long nalcGetString(long deviceHandle, int token) { + long __functionAddress = ALC.getICD().alcGetString; + return invokePP(deviceHandle, token, __functionAddress); + } + + /** + * Obtains string value(s) from ALC. + * + *

LWJGL note: Use {@link ALUtil#getStringList} for those tokens that return multiple values.

+ * + * @param deviceHandle the device to query + * @param token the information to query. One of:
{@link #ALC_DEFAULT_DEVICE_SPECIFIER DEFAULT_DEVICE_SPECIFIER}{@link #ALC_DEVICE_SPECIFIER DEVICE_SPECIFIER}{@link #ALC_EXTENSIONS EXTENSIONS}
{@link ALC11#ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER CAPTURE_DEFAULT_DEVICE_SPECIFIER}{@link ALC11#ALC_CAPTURE_DEVICE_SPECIFIER CAPTURE_DEVICE_SPECIFIER}
+ */ + @Nullable + @NativeType("ALCchar const *") + public static String alcGetString(@NativeType("ALCdevice *") long deviceHandle, @NativeType("ALCenum") int token) { + long __result = nalcGetString(deviceHandle, token); + return memUTF8Safe(__result); + } + + // --- [ alcGetIntegerv ] --- + + /** + * Unsafe version of: {@link #alcGetIntegerv GetIntegerv} + * + * @param size the size of the {@code dest} buffer + */ + public static void nalcGetIntegerv(long deviceHandle, int token, int size, long dest) { + long __functionAddress = ALC.getICD().alcGetIntegerv; + invokePPV(deviceHandle, token, size, dest, __functionAddress); + } + + /** + * Obtains integer value(s) from ALC. + * + * @param deviceHandle the device to query + * @param token the information to query. One of:
{@link #ALC_MAJOR_VERSION MAJOR_VERSION}{@link #ALC_MINOR_VERSION MINOR_VERSION}{@link #ALC_ATTRIBUTES_SIZE ATTRIBUTES_SIZE}{@link #ALC_ALL_ATTRIBUTES ALL_ATTRIBUTES}{@link ALC11#ALC_CAPTURE_SAMPLES CAPTURE_SAMPLES}
+ * @param dest the destination buffer + */ + @NativeType("ALCvoid") + public static void alcGetIntegerv(@NativeType("ALCdevice *") long deviceHandle, @NativeType("ALCenum") int token, @NativeType("ALCint *") IntBuffer dest) { + nalcGetIntegerv(deviceHandle, token, dest.remaining(), memAddress(dest)); + } + + /** + * Obtains integer value(s) from ALC. + * + * @param deviceHandle the device to query + * @param token the information to query. One of:
{@link #ALC_MAJOR_VERSION MAJOR_VERSION}{@link #ALC_MINOR_VERSION MINOR_VERSION}{@link #ALC_ATTRIBUTES_SIZE ATTRIBUTES_SIZE}{@link #ALC_ALL_ATTRIBUTES ALL_ATTRIBUTES}{@link ALC11#ALC_CAPTURE_SAMPLES CAPTURE_SAMPLES}
+ */ + @NativeType("ALCvoid") + public static int alcGetInteger(@NativeType("ALCdevice *") long deviceHandle, @NativeType("ALCenum") int token) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer dest = stack.callocInt(1); + nalcGetIntegerv(deviceHandle, token, 1, memAddress(dest)); + return dest.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + /** Array version of: {@link #alcCreateContext CreateContext} */ + @NativeType("ALCcontext *") + public static long alcCreateContext(@NativeType("ALCdevice const *") long deviceHandle, @Nullable @NativeType("ALCint const *") int[] attrList) { + long __functionAddress = ALC.getICD().alcCreateContext; + if (CHECKS) { + check(deviceHandle); + checkNTSafe(attrList); + } + return invokePPP(deviceHandle, attrList, __functionAddress); + } + + /** Array version of: {@link #alcGetIntegerv GetIntegerv} */ + @NativeType("ALCvoid") + public static void alcGetIntegerv(@NativeType("ALCdevice *") long deviceHandle, @NativeType("ALCenum") int token, @NativeType("ALCint *") int[] dest) { + long __functionAddress = ALC.getICD().alcGetIntegerv; + invokePPV(deviceHandle, token, dest.length, dest, __functionAddress); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCcontext.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCcontext.java new file mode 100644 index 000000000..2d99d4c1d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCcontext.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.openal; + +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; + +/** + * The ALCcontext class represents a context opened in OpenAL space. + * + * All operations of the AL core API affect a current AL context. Within the scope of AL, + * the ALC is implied - it is not visible as a handle or function parameter. Only one AL + * Context per process can be current at a time. Applications maintaining multiple AL + * Contexts, whether threaded or not, have to set the current context accordingly. + * Applications can have multiple threads that share one more or contexts. In other words, + * AL and ALC are threadsafe. + * + * @author Brian Matzon + * @version $Revision$ + * $Id$ + */ +public final class ALCcontext { + + /** Address of actual context */ + final long context; + + /** Whether this context is valid */ + private boolean valid; + + /** + * Creates a new instance of ALCcontext + * + * @param context address of actual context + */ + ALCcontext(long context) { + this.context = context; + this.valid = true; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object context) { + if(context instanceof ALCcontext) { + return ((ALCcontext)context).context == this.context; + } + return super.equals(context); + } + + /** + * Creates an attribute list in a ByteBuffer + * @param contextFrequency Frequency to add + * @param contextRefresh Refresh rate to add + * @param contextSynchronized Whether to synchronize the context + * @return + */ + static IntBuffer createAttributeList(int contextFrequency, int contextRefresh, int contextSynchronized) { + IntBuffer attribList = BufferUtils.createIntBuffer(7); + + attribList.put(ALC10.ALC_FREQUENCY); + attribList.put(contextFrequency); + attribList.put(ALC10.ALC_REFRESH); + attribList.put(contextRefresh); + attribList.put(ALC10.ALC_SYNC); + attribList.put(contextSynchronized); + attribList.put(0); //terminating int + + return attribList; + } + + /** + * Marks this context as invalid + * + */ + void setInvalid() { + valid = false; + } + + /** + * @return true if this context is still valid + */ + public boolean isValid() { + return valid; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCdevice.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCdevice.java new file mode 100644 index 000000000..9cc06a97a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/ALCdevice.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.openal; + +import java.util.HashMap; + +/** + * The ALCdevice class represents a device opened in OpenAL space. + * + * ALC introduces the notion of a Device. A Device can be, depending on the + * implementation, a hardware device, or a daemon/OS service/actual server. This + * mechanism also permits different drivers (and hardware) to coexist within the same + * system, as well as allowing several applications to share system resources for audio, + * including a single hardware output device. The details are left to the implementation, + * which has to map the available backends to unique device specifiers. + * + * @author Brian Matzon + * @version $Revision$ + * $Id$ + */ +public final class ALCdevice { + + /** Address of actual device */ + final long device; + + /** Whether this device is valid */ + private boolean valid; + + /** List of contexts belonging to the device */ + private final HashMap contexts = new HashMap(); + + /** + * Creates a new instance of ALCdevice + * + * @param device address of actual device + */ + ALCdevice(long device) { + this.device = device; + this.valid = true; + } + + /* + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object device) { + if(device instanceof ALCdevice) { + return ((ALCdevice)device).device == this.device; + } + return super.equals(device); + } + + /** + * Adds a context to the device + * + * @param context context to add to the list of contexts for this device + */ + void addContext(ALCcontext context) { + synchronized (contexts) { + contexts.put(context.context, context); + } + } + + /** + * Remove context associated with device + * + * @param context Context to disassociate with device + */ + void removeContext(ALCcontext context) { + synchronized (contexts) { + contexts.remove(context.context); + } + } + + /** + * Marks this device and all of its contexts invalid + */ + void setInvalid() { + valid = false; + synchronized (contexts) { + for ( ALCcontext context : contexts.values() ) + context.setInvalid(); + } + contexts.clear(); + } + + /** + * @return true if this device is still valid + */ + public boolean isValid() { + return valid; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFX10.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFX10.java new file mode 100644 index 000000000..b755b7c4d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFX10.java @@ -0,0 +1,143 @@ +package org.lwjgl.openal; + +import java.nio.IntBuffer; + +import org.lwjgl.openal.EXTEfx; + +public class EFX10 { + + public static final int AL_EFFECT_TYPE = EXTEfx.AL_EFFECT_TYPE; + public static final int AL_EFFECTSLOT_EFFECT = EXTEfx.AL_EFFECTSLOT_EFFECT; + public static final int AL_EFFECT_ECHO = EXTEfx.AL_EFFECT_ECHO; + public static final float AL_ECHO_MIN_DAMPING = EXTEfx.AL_ECHO_MIN_DAMPING; + public static final int AL_ECHO_DAMPING = EXTEfx.AL_ECHO_DAMPING; + public static final float AL_ECHO_MAX_DAMPING = EXTEfx.AL_ECHO_MAX_DAMPING; + public static final float AL_ECHO_MIN_DELAY = EXTEfx.AL_ECHO_MIN_DELAY; + public static final int AL_ECHO_DELAY = EXTEfx.AL_ECHO_DELAY; + public static final float AL_ECHO_MAX_DELAY = EXTEfx.AL_ECHO_MAX_DELAY; + public static final float AL_ECHO_MIN_FEEDBACK = EXTEfx.AL_ECHO_MIN_FEEDBACK; + public static final int AL_ECHO_FEEDBACK = EXTEfx.AL_ECHO_FEEDBACK; + public static final float AL_ECHO_MAX_FEEDBACK = EXTEfx.AL_ECHO_MAX_FEEDBACK; + public static final float AL_ECHO_MIN_LRDELAY = EXTEfx.AL_ECHO_MIN_LRDELAY; + public static final int AL_ECHO_LRDELAY = EXTEfx.AL_ECHO_LRDELAY; + public static final float AL_ECHO_MAX_LRDELAY = EXTEfx.AL_ECHO_MAX_LRDELAY; + public static final float AL_ECHO_MIN_SPREAD = EXTEfx.AL_ECHO_MIN_SPREAD; + public static final int AL_ECHO_SPREAD = EXTEfx.AL_ECHO_SPREAD; + public static final float AL_ECHO_MAX_SPREAD = EXTEfx.AL_ECHO_MAX_SPREAD; + public static final int AL_EFFECT_REVERB = EXTEfx.AL_EFFECT_REVERB; + public static final int AL_RING_MODULATOR_SINUSOID = EXTEfx.AL_RING_MODULATOR_SINUSOID; + public static final int AL_RING_MODULATOR_SAWTOOTH = EXTEfx.AL_RING_MODULATOR_SAWTOOTH; + public static final int AL_RING_MODULATOR_SQUARE = EXTEfx.AL_RING_MODULATOR_SQUARE; + public static final int AL_EFFECT_RING_MODULATOR = EXTEfx.AL_EFFECT_RING_MODULATOR; + public static final float AL_RING_MODULATOR_MAX_FREQUENCY = EXTEfx.AL_RING_MODULATOR_MAX_FREQUENCY; + public static final int AL_RING_MODULATOR_FREQUENCY = EXTEfx.AL_RING_MODULATOR_FREQUENCY; + public static final float AL_RING_MODULATOR_MIN_FREQUENCY = EXTEfx.AL_RING_MODULATOR_MIN_FREQUENCY; + public static final float AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF = EXTEfx.AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF; + public static final int AL_RING_MODULATOR_HIGHPASS_CUTOFF = EXTEfx.AL_RING_MODULATOR_HIGHPASS_CUTOFF; + public static final float AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF = EXTEfx.AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF; + public static final int AL_RING_MODULATOR_WAVEFORM = EXTEfx.AL_RING_MODULATOR_WAVEFORM; + public static final int AL_FILTER_TYPE = EXTEfx.AL_FILTER_TYPE; + public static final int AL_FILTER_LOWPASS = EXTEfx.AL_FILTER_LOWPASS; + public static final int AL_LOWPASS_GAIN = EXTEfx.AL_LOWPASS_GAIN; + public static final int AL_LOWPASS_GAINHF = EXTEfx.AL_LOWPASS_GAINHF; + public static final int AL_EFFECTSLOT_NULL = EXTEfx.AL_EFFECTSLOT_NULL; + public static final int AL_FILTER_NULL = EXTEfx.AL_FILTER_NULL; + public static final int AL_AUXILIARY_SEND_FILTER = EXTEfx.AL_AUXILIARY_SEND_FILTER; + public static final int AL_DIRECT_FILTER = EXTEfx.AL_DIRECT_FILTER; + public static final int ALC_MAX_AUXILIARY_SENDS = EXTEfx.ALC_MAX_AUXILIARY_SENDS; + public static final int ALC_EFX_MAJOR_VERSION = EXTEfx.ALC_EFX_MAJOR_VERSION; + public static final int AL_REVERB_DECAY_TIME = EXTEfx.AL_REVERB_DECAY_TIME; + public static final int AL_FILTER_HIGHPASS = EXTEfx.AL_FILTER_HIGHPASS; + public static final int AL_FILTER_BANDPASS = EXTEfx.AL_FILTER_BANDPASS; + public static final int AL_EFFECT_NULL = EXTEfx.AL_EFFECT_NULL; + public static final int AL_EFFECT_EAXREVERB = EXTEfx.AL_EFFECT_EAXREVERB; + public static final int AL_EFFECT_CHORUS = EXTEfx.AL_EFFECT_CHORUS; + public static final int AL_EFFECT_DISTORTION = EXTEfx.AL_EFFECT_DISTORTION; + public static final int AL_EFFECT_FLANGER = EXTEfx.AL_EFFECT_FLANGER; + public static final int AL_EFFECT_FREQUENCY_SHIFTER = EXTEfx.AL_EFFECT_FREQUENCY_SHIFTER; + public static final int AL_EFFECT_VOCAL_MORPHER = EXTEfx.AL_EFFECT_VOCAL_MORPHER; + public static final int AL_EFFECT_PITCH_SHIFTER = EXTEfx.AL_EFFECT_PITCH_SHIFTER; + public static final int AL_EFFECT_AUTOWAH = EXTEfx.AL_EFFECT_AUTOWAH; + public static final int AL_EFFECT_COMPRESSOR = EXTEfx.AL_EFFECT_COMPRESSOR; + public static final int AL_EFFECT_EQUALIZER = EXTEfx.AL_EFFECT_EQUALIZER; + + public static int alGenAuxiliaryEffectSlots() { + return EXTEfx.alGenAuxiliaryEffectSlots(); + } + + public static int alGenFilters() { + return EXTEfx.alGenFilters(); + } + + public static void alDeleteFilters(int filter) { + EXTEfx.alDeleteFilters(filter); + } + + public static void alFilteri(int filter, int param, int value) { + EXTEfx.alFilteri(filter, param, value); + } + + public static void alFilterf(int filter, int param, float value) { + EXTEfx.alFilterf(filter, param, value); + } + + public static float alGetFilterf(int filter, int param) { + return EXTEfx.alGetFilterf(filter, param); + } + + public static int alGenEffects() { + return EXTEfx.alGenEffects(); + } + + public static void alDeleteEffects(int effect) { + EXTEfx.alDeleteAuxiliaryEffectSlots(effect); + } + + public static void alDeleteAuxiliaryEffectSlots(int effectSlot) { + EXTEfx.alDeleteAuxiliaryEffectSlots(effectSlot); + } + + public static void alEffecti(int effect, int param, int value) { + EXTEfx.alEffecti(effect, param, value); + } + + public static float alGetEffectf(int effect, int param) { + return EXTEfx.alGetEffectf(effect, param); + } + + public static int alGetEffecti(int effect, int param) { + return EXTEfx.alGetEffecti(effect, param); + } + + public static void alEffectf(int effect, int param, float value) { + EXTEfx.alEffectf(effect, param, value); + } + + public static void alAuxiliaryEffectSloti(int effectSlot, int param, int value) { + EXTEfx.alAuxiliaryEffectSloti(effectSlot, param, value); + } + + public static void alGenAuxiliaryEffectSlots(IntBuffer effectSlots) { + EXTEfx.alGenAuxiliaryEffectSlots(effectSlots); + } + + public static void alGenEffects(IntBuffer effects) { + EXTEfx.alGenEffects(effects); + } + + public static void alDeleteEffects(IntBuffer effects) { + EXTEfx.alDeleteEffects(effects); + } + + public static void alDeleteAuxiliaryEffectSlots(IntBuffer effectSlots) { + EXTEfx.alDeleteAuxiliaryEffectSlots(effectSlots); + } + + public static void alGenFilters(IntBuffer filters) { + EXTEfx.alGenFilters(filters); + } + + public static void alDeleteFilters(IntBuffer filters) { + EXTEfx.alDeleteFilters(filters); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFXUtil.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFXUtil.java new file mode 100644 index 000000000..57b4348cc --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/EFXUtil.java @@ -0,0 +1,210 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: http://lwjgl.org/license.php + */ +package org.lwjgl.openal; + +import static org.lwjgl.openal.AL10.*; +import static org.lwjgl.openal.EXTEfx.*; + +import org.lwjgl.openal.ALC; +import org.lwjgl.openal.ALCCapabilities; + +/** + * Utility class for the OpenAL extension AL_EXT_EFX. Provides functions to check for the extension + * and support of various effects and filters. + *

+ * Currently supports AL_EXT_EFX version 1.0 effects and filters. + * + * @author Ciardhubh + */ +public final class EFXUtil { + + /** Constant for testSupportGeneric to check an effect. */ + private static final int EFFECT = 1111; + /** Constant for testSupportGeneric to check a filter. */ + private static final int FILTER = 2222; + + /** Utility class, hidden contructor. */ + private EFXUtil() { + } + + /** + * Checks if OpenAL implementation is loaded and supports AL_EXT_EFX. + * + * @return True if AL_EXT_EFX is supported, false if not. + * + * @throws org.lwjgl.openal.OpenALException + * If OpenAL has not been created yet. + */ + public static boolean isEfxSupported() { + //return ALC.getCapabilities().ALC_EXT_EFX; + return ALC.createCapabilities(AL.alcDevice.device).ALC_EXT_EFX; + } + + /** + * Tests OpenAL to see whether the given effect type is supported. This is done by creating an + * effect of the given type. If creation succeeds the effect is supported. + * + * @param effectType Type of effect whose support is to be tested, e.g. AL_EFFECT_REVERB. + * + * @return True if it is supported, false if not. + * + * @throws org.lwjgl.openal.OpenALException + * If the request fails due to an AL_OUT_OF_MEMORY error or OpenAL has + * not been created yet. + * @throws IllegalArgumentException effectType is not a valid effect type. + */ + public static boolean isEffectSupported(int effectType) { + // Make sure type is a real effect. + switch ( effectType ) { + case AL_EFFECT_NULL: + case AL_EFFECT_EAXREVERB: + case AL_EFFECT_REVERB: + case AL_EFFECT_CHORUS: + case AL_EFFECT_DISTORTION: + case AL_EFFECT_ECHO: + case AL_EFFECT_FLANGER: + case AL_EFFECT_FREQUENCY_SHIFTER: + case AL_EFFECT_VOCAL_MORPHER: + case AL_EFFECT_PITCH_SHIFTER: + case AL_EFFECT_RING_MODULATOR: + case AL_EFFECT_AUTOWAH: + case AL_EFFECT_COMPRESSOR: + case AL_EFFECT_EQUALIZER: + break; + default: + throw new IllegalArgumentException("Unknown or invalid effect type: " + effectType); + } + + return testSupportGeneric(EFFECT, effectType); + } + + /** + * Tests OpenAL to see whether the given filter type is supported. This is done by creating a + * filter of the given type. If creation succeeds the filter is supported. + * + * @param filterType Type of filter whose support is to be tested, e.g. AL_FILTER_LOWPASS. + * + * @return True if it is supported, false if not. + * + * @throws org.lwjgl.openal.OpenALException + * If the request fails due to an AL_OUT_OF_MEMORY error or OpenAL has + * not been created yet. + * @throws IllegalArgumentException filterType is not a valid filter type. + */ + public static boolean isFilterSupported(int filterType) { + // Make sure type is a real filter. + switch ( filterType ) { + case AL_FILTER_NULL: + case AL_FILTER_LOWPASS: + case AL_FILTER_HIGHPASS: + case AL_FILTER_BANDPASS: + break; + default: + throw new IllegalArgumentException("Unknown or invalid filter type: " + filterType); + } + + return testSupportGeneric(FILTER, filterType); + } + + /** + * Generic test function to see if an EFX object supports a given kind of type. Works for + * effects and filters. + * + * @param objectType Type of object to test. Must be either EFXUtil.EFFECT or EFXUtil.FILTER. + * @param typeValue OpenAL type the object should be tested for support, e.g. AL_FILTER_LOWPASS + * or AL_EFFECT_REVERB. + * + * @return True if object supports typeValue, false else. + */ + private static boolean testSupportGeneric(int objectType, int typeValue) { + // Check for supported objectType. + switch ( objectType ) { + case EFFECT: + case FILTER: + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + + boolean supported = false; + if ( isEfxSupported() ) { + + // Try to create object in order to check AL's response. + alGetError(); + int genError; + int testObject = 0; + try { + switch ( objectType ) { // Create object based on type + case EFFECT: + testObject = alGenEffects(); + break; + case FILTER: + testObject = alGenFilters(); + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + genError = alGetError(); + } catch (OpenALException debugBuildException) { + // Hack because OpenALException hides the original error code (short of parsing the + // error message String which would break if it gets changed). + if ( debugBuildException.getMessage().contains("AL_OUT_OF_MEMORY") ) { + genError = AL_OUT_OF_MEMORY; + } else { + genError = AL_INVALID_OPERATION; + } + } + + if ( genError == AL_NO_ERROR ) { + // Successfully created, now try to set type. + alGetError(); + int setError; + try { + switch ( objectType ) { // Set based on object type + case EFFECT: + alEffecti(testObject, AL_EFFECT_TYPE, typeValue); + break; + case FILTER: + alFilteri(testObject, AL_FILTER_TYPE, typeValue); + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + setError = alGetError(); + } catch (OpenALException debugBuildException) { + // Hack because OpenALException hides the original error code (short of parsing + // the error message String which would break when it gets changed). + setError = AL_INVALID_VALUE; + } + + if ( setError == AL_NO_ERROR ) { + supported = true; + } + + // Cleanup + try { + switch ( objectType ) { // Set based on object type + case EFFECT: + alDeleteEffects(testObject); + break; + case FILTER: + alDeleteFilters(testObject); + break; + default: + throw new IllegalArgumentException("Invalid objectType: " + objectType); + } + } catch (OpenALException debugBuildException) { + // Don't care about cleanup errors. + } + + } else if ( genError == AL_OUT_OF_MEMORY ) { + throw new OpenALException(AL10.alGetString(genError)); + } + } + + return supported; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/OpenALException.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/OpenALException.java new file mode 100644 index 000000000..6ed4d0b97 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/OpenALException.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.openal; + +/** + *
+ * Thrown by the debug build library of the LWJGL if any OpenAL operation + * causes an error. + * + * @author Brian Matzon + * @version $Revision$ + * $Id$ + */ +public class OpenALException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * Constructor for OpenALException. + */ + public OpenALException() { + super(); + } + + /** + * Constructor that takes an AL error number + */ + public OpenALException(int error_code) { + super("OpenAL error: " + org.lwjgl.openal.AL10.alGetString(error_code) + " (" + error_code + ")"); + } + + /** + * Constructor for OpenALException. + * @param message + */ + public OpenALException(String message) { + super(message); + } + + /** + * Constructor for OpenALException. + * @param message + * @param cause + */ + public OpenALException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor for OpenALException. + * @param cause + */ + public OpenALException(Throwable cause) { + super(cause); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/Util.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/Util.java new file mode 100644 index 000000000..0930c2a7a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/openal/Util.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.openal; + + +/** + * Simple utility class for checking AL/ALC errors + * + * @author cix_foo + * @author Brian Matzon + * @version $Revision$ + */ + +public final class Util { + /** No c'tor */ + private Util() { + } + + /** + * Checks for any ALC errors and throws an unchecked exception on errors + * @param device Device for which to check ALC errors + */ + public static void checkALCError(ALCdevice device) { + int err = ALC10.alcGetError(device.device); + if (err != ALC10.ALC_NO_ERROR) + throw new OpenALException(ALC10.alcGetString(AL.getDevice().device, err)); + } + + /** + * Checks for any AL errors and throws an unchecked exception on errors + */ + public static void checkALError() { + int err = AL10.alGetError(); + if (err != AL10.AL_NO_ERROR) + throw new OpenALException(err); + } + + /** + * Checks for a valid device + * @param device ALCdevice to check the validity of + */ + public static void checkALCValidDevice(ALCdevice device) { + if(!device.isValid()) { + throw new OpenALException("Invalid device: " + device); + } + } + + /** + * Checks for a valid context + * @param context ALCcontext to check the validity of + */ + public static void checkALCValidContext(ALCcontext context) { + if(!context.isValid()) { + throw new OpenALException("Invalid context: " + context); + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBBufferObject.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBBufferObject.java new file mode 100644 index 000000000..c83120376 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBBufferObject.java @@ -0,0 +1,5 @@ +package org.lwjgl.opengl; + +public class ARBBufferObject extends ARBVertexBufferObject +{ +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBShaderObjects.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBShaderObjects.java new file mode 100644 index 000000000..c5ee33188 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ARBShaderObjects.java @@ -0,0 +1,1363 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.opengl; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.MemoryUtil.*; + +/** + * Native bindings to the ARB_shader_objects extension. + * + *

This extension adds API calls that are necessary to manage shader objects and program objects as defined in the OpenGL 2.0 white papers by 3Dlabs.

+ * + *

The generation of an executable that runs on one of OpenGL's programmable units is modeled to that of developing a typical C/C++ application. There are + * one or more source files, each of which are stored by OpenGL in a shader object. Each shader object (source file) needs to be compiled and attached to a + * program object. Once all shader objects are compiled successfully, the program object needs to be linked to produce an executable. This executable is + * part of the program object, and can now be loaded onto the programmable units to make it part of the current OpenGL state. Both the compile and link + * stages generate a text string that can be queried to get more information. This information could be, but is not limited to, compile errors, link errors, + * optimization hints, etc. Values for uniform variables, declared in a shader, can be set by the application and used to control a shader's behavior.

+ * + *

This extension defines functions for creating shader objects and program objects, for compiling shader objects, for linking program objects, for + * attaching shader objects to program objects, and for using a program object as part of current state. Functions to load uniform values are also defined. + * Some house keeping functions, like deleting an object and querying object state, are also provided.

+ * + *

Although this extension defines the API for creating shader objects, it does not define any specific types of shader objects. It is assumed that this + * extension will be implemented along with at least one such additional extension for creating a specific type of OpenGL 2.0 shader (e.g., the + * {@link ARBFragmentShader ARB_fragment_shader} extension or the {@link ARBVertexShader ARB_vertex_shader} extension).

+ * + *

Promoted to core in {@link GL20 OpenGL 2.0}.

+ */ +public class ARBShaderObjects { + + /** Accepted by the {@code pname} argument of GetHandleARB. */ + public static final int GL_PROGRAM_OBJECT_ARB = 0x8B40; + + /** Accepted by the {@code pname} parameter of GetObjectParameter{fi}vARB. */ + public static final int + GL_OBJECT_TYPE_ARB = 0x8B4E, + GL_OBJECT_SUBTYPE_ARB = 0x8B4F, + GL_OBJECT_DELETE_STATUS_ARB = 0x8B80, + GL_OBJECT_COMPILE_STATUS_ARB = 0x8B81, + GL_OBJECT_LINK_STATUS_ARB = 0x8B82, + GL_OBJECT_VALIDATE_STATUS_ARB = 0x8B83, + GL_OBJECT_INFO_LOG_LENGTH_ARB = 0x8B84, + GL_OBJECT_ATTACHED_OBJECTS_ARB = 0x8B85, + GL_OBJECT_ACTIVE_UNIFORMS_ARB = 0x8B86, + GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = 0x8B87, + GL_OBJECT_SHADER_SOURCE_LENGTH_ARB = 0x8B88; + + /** Returned by the {@code params} parameter of GetObjectParameter{fi}vARB. */ + public static final int GL_SHADER_OBJECT_ARB = 0x8B48; + + /** Returned by the {@code type} parameter of GetActiveUniformARB. */ + public static final int + GL_FLOAT_VEC2_ARB = 0x8B50, + GL_FLOAT_VEC3_ARB = 0x8B51, + GL_FLOAT_VEC4_ARB = 0x8B52, + GL_INT_VEC2_ARB = 0x8B53, + GL_INT_VEC3_ARB = 0x8B54, + GL_INT_VEC4_ARB = 0x8B55, + GL_BOOL_ARB = 0x8B56, + GL_BOOL_VEC2_ARB = 0x8B57, + GL_BOOL_VEC3_ARB = 0x8B58, + GL_BOOL_VEC4_ARB = 0x8B59, + GL_FLOAT_MAT2_ARB = 0x8B5A, + GL_FLOAT_MAT3_ARB = 0x8B5B, + GL_FLOAT_MAT4_ARB = 0x8B5C, + GL_SAMPLER_1D_ARB = 0x8B5D, + GL_SAMPLER_2D_ARB = 0x8B5E, + GL_SAMPLER_3D_ARB = 0x8B5F, + GL_SAMPLER_CUBE_ARB = 0x8B60, + GL_SAMPLER_1D_SHADOW_ARB = 0x8B61, + GL_SAMPLER_2D_SHADOW_ARB = 0x8B62, + GL_SAMPLER_2D_RECT_ARB = 0x8B63, + GL_SAMPLER_2D_RECT_SHADOW_ARB = 0x8B64; + + static { GL.initialize(); } + + protected ARBShaderObjects() { + throw new UnsupportedOperationException(); + } + + static boolean isAvailable(GLCapabilities caps) { + return checkFunctions( + caps.glDeleteObjectARB, caps.glGetHandleARB, caps.glDetachObjectARB, caps.glCreateShaderObjectARB, caps.glShaderSourceARB, caps.glCompileShaderARB, + caps.glCreateProgramObjectARB, caps.glAttachObjectARB, caps.glLinkProgramARB, caps.glUseProgramObjectARB, caps.glValidateProgramARB, + caps.glUniform1fARB, caps.glUniform2fARB, caps.glUniform3fARB, caps.glUniform4fARB, caps.glUniform1iARB, caps.glUniform2iARB, caps.glUniform3iARB, + caps.glUniform4iARB, caps.glUniform1fvARB, caps.glUniform2fvARB, caps.glUniform3fvARB, caps.glUniform4fvARB, caps.glUniform1ivARB, + caps.glUniform2ivARB, caps.glUniform3ivARB, caps.glUniform4ivARB, caps.glUniformMatrix2fvARB, caps.glUniformMatrix3fvARB, + caps.glUniformMatrix4fvARB, caps.glGetObjectParameterfvARB, caps.glGetObjectParameterivARB, caps.glGetInfoLogARB, caps.glGetAttachedObjectsARB, + caps.glGetUniformLocationARB, caps.glGetActiveUniformARB, caps.glGetUniformfvARB, caps.glGetUniformivARB, caps.glGetShaderSourceARB + ); + } + +// -- Begin LWJGL2 part -- + public static void glShaderSourceARB(int shader, java.nio.ByteBuffer string) { + byte[] b = new byte[string.remaining()]; + string.get(b); + org.lwjgl.opengl.ARBShaderObjects.glShaderSourceARB(shader, new String(b)); + } + + public static void glUniform1ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + glUniform1fvARB(location, value); + } + + public static void glUniform2ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + glUniform2fvARB(location, value); + } + + public static void glUniform3ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + glUniform3fvARB(location, value); + } + + public static void glUniform4ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + glUniform4fvARB(location, value); + } + + public static void glUniform1ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") IntBuffer value) { + glUniform1ivARB(location, value); + } + + public static void glUniform2ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") IntBuffer value) { + glUniform2ivARB(location, value); + } + + public static void glUniform3ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") IntBuffer value) { + glUniform3ivARB(location, value); + } + + public static void glUniform4ARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") IntBuffer value) { + glUniform4ivARB(location, value); + } + + public static void glGetObjectParameterARB(@NativeType("GLhandleARB") int obj, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + glGetObjectParameterivARB(obj, pname, params); + } +// -- End LWJGL2 part -- + + // --- [ glDeleteObjectARB ] --- + + /** + * Either deletes the object, or flags it for deletion. An object that is attached to a container object is not deleted until it is no longer attached to + * any container object, for any context. If it is still attached to at least one container object, the object is flagged for deletion. If the object is + * part of the current rendering state, it is not deleted until it is no longer part of the current rendering state for any context. If the object is still + * part of the rendering state of at least one context, it is flagged for deletion. + * + *

If an object is flagged for deletion, its Boolean status bit {@link #GL_OBJECT_DELETE_STATUS_ARB OBJECT_DELETE_STATUS_ARB} is set to true.

+ * + *

DeleteObjectARB will silently ignore the value zero.

+ * + *

When a container object is deleted, it will detach each attached object as part of the deletion process. When an object is deleted, all information for + * the object referenced is lost. The data for the object is also deleted.

+ * + * @param obj the shader object to delete + */ + public static native void glDeleteObjectARB(@NativeType("GLhandleARB") int obj); + + // --- [ glGetHandleARB ] --- + + /** + * Returns the handle to an object that is in use as part of current state. + * + * @param pname the state item for which the current object is to be returned. Must be:
{@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB}
+ */ + @NativeType("GLhandleARB") + public static native int glGetHandleARB(@NativeType("GLenum") int pname); + + // --- [ glDetachObjectARB ] --- + + /** + * Detaches an object from the container object it is attached to. + * + * @param containerObj the container object + * @param attachedObj the object to detach + */ + public static native void glDetachObjectARB(@NativeType("GLhandleARB") int containerObj, @NativeType("GLhandleARB") int attachedObj); + + // --- [ glCreateShaderObjectARB ] --- + + /** + * Creates a shader object. + * + * @param shaderType the type of the shader object to be created. One of:
{@link ARBVertexShader#GL_VERTEX_SHADER_ARB VERTEX_SHADER_ARB}{@link ARBFragmentShader#GL_FRAGMENT_SHADER_ARB FRAGMENT_SHADER_ARB}
+ */ + @NativeType("GLhandleARB") + public static native int glCreateShaderObjectARB(@NativeType("GLenum") int shaderType); + + // --- [ glShaderSourceARB ] --- + + /** + * Unsafe version of: {@link #glShaderSourceARB ShaderSourceARB} + * + * @param count the number of strings in the array + */ + public static native void nglShaderSourceARB(int shaderObj, int count, long string, long length); + + /** + * Sets the source code for the specified shader object {@code shaderObj} to the text strings in the {@code string} array. If the object previously had + * source code loaded into it, it is completely replaced. + * + *

The strings that are loaded into a shader object are expected to form the source code for a valid shader as defined in the OpenGL Shading Language + * Specification.

+ * + * @param shaderObj the shader object + * @param string an array of pointers to one or more, optionally null terminated, character strings that make up the source code + * @param length an array with the number of charARBs in each string (the string length). Each element in this array can be set to negative one (or smaller), + * indicating that its accompanying string is null terminated. If {@code length} is set to {@code NULL}, all strings in the {@code string} argument are + * considered null terminated. + */ + public static void glShaderSourceARB(@NativeType("GLhandleARB") int shaderObj, @NativeType("GLcharARB const **") PointerBuffer string, @Nullable @NativeType("GLint const *") IntBuffer length) { + if (CHECKS) { + checkSafe(length, string.remaining()); + } + nglShaderSourceARB(shaderObj, string.remaining(), memAddress(string), memAddressSafe(length)); + } + + /** + * Sets the source code for the specified shader object {@code shaderObj} to the text strings in the {@code string} array. If the object previously had + * source code loaded into it, it is completely replaced. + * + *

The strings that are loaded into a shader object are expected to form the source code for a valid shader as defined in the OpenGL Shading Language + * Specification.

+ * + * @param shaderObj the shader object + * @param string an array of pointers to one or more, optionally null terminated, character strings that make up the source code + */ + public static void glShaderSourceARB(@NativeType("GLhandleARB") int shaderObj, @NativeType("GLcharARB const **") CharSequence... string) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + long stringAddress = org.lwjgl.system.APIUtil.apiArrayi(stack, MemoryUtil::memUTF8, string); + nglShaderSourceARB(shaderObj, string.length, stringAddress, stringAddress - (string.length << 2)); + org.lwjgl.system.APIUtil.apiArrayFree(stringAddress, string.length); + } finally { + stack.setPointer(stackPointer); + } + } + + /** + * Sets the source code for the specified shader object {@code shaderObj} to the text strings in the {@code string} array. If the object previously had + * source code loaded into it, it is completely replaced. + * + *

The strings that are loaded into a shader object are expected to form the source code for a valid shader as defined in the OpenGL Shading Language + * Specification.

+ * + * @param shaderObj the shader object + * @param string an array of pointers to one or more, optionally null terminated, character strings that make up the source code + */ + public static void glShaderSourceARB(@NativeType("GLhandleARB") int shaderObj, @NativeType("GLcharARB const **") CharSequence string) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + long stringAddress = org.lwjgl.system.APIUtil.apiArrayi(stack, MemoryUtil::memUTF8, string); + nglShaderSourceARB(shaderObj, 1, stringAddress, stringAddress - 4); + org.lwjgl.system.APIUtil.apiArrayFree(stringAddress, 1); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glCompileShaderARB ] --- + + /** + * Compiles a shader object. Each shader object has a Boolean status, {@link #GL_OBJECT_COMPILE_STATUS_ARB OBJECT_COMPILE_STATUS_ARB}, that is modified as a result of compilation. This status + * can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}. This status will be set to {@link GL11#GL_TRUE TRUE} if the shader {@code shaderObj} was compiled without errors and is + * ready for use, and {@link GL11#GL_FALSE FALSE} otherwise. Compilation can fail for a variety of reasons as listed in the OpenGL Shading Language Specification. If + * CompileShaderARB failed, any information about a previous compile is lost and is not restored. Thus a failed compile does not restore the old state of + * {@code shaderObj}. If {@code shaderObj} does not reference a shader object, the error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. + * + *

Note that changing the source code of a shader object, through ShaderSourceARB, does not change its compile status {@link #GL_OBJECT_COMPILE_STATUS_ARB OBJECT_COMPILE_STATUS_ARB}.

+ * + *

Each shader object has an information log that is modified as a result of compilation. This information log can be queried with {@link #glGetInfoLogARB GetInfoLogARB} to + * obtain more information about the compilation attempt.

+ * + * @param shaderObj the shader object to compile + */ + public static native void glCompileShaderARB(@NativeType("GLhandleARB") int shaderObj); + + // --- [ glCreateProgramObjectARB ] --- + + /** + * Creates a program object. + * + *

A program object is a container object. Shader objects are attached to a program object with the command AttachObjectARB. It is permissible to attach + * shader objects to program objects before source code has been loaded into the shader object, or before the shader object has been compiled. It is + * permissible to attach multiple shader objects of the same type to a single program object, and it is permissible to attach a shader object to more than + * one program object.

+ */ + @NativeType("GLhandleARB") + public static native int glCreateProgramObjectARB(); + + // --- [ glAttachObjectARB ] --- + + /** + * Attaches an object to a container object. + * + * @param containerObj the container object + * @param obj the object to attach + */ + public static native void glAttachObjectARB(@NativeType("GLhandleARB") int containerObj, @NativeType("GLhandleARB") int obj); + + // --- [ glLinkProgramARB ] --- + + /** + * Links a program object. + * + *

Each program object has a Boolean status, {@link #GL_OBJECT_LINK_STATUS_ARB OBJECT_LINK_STATUS_ARB}, that is modified as a result of linking. This status can be queried with + * {@link #glGetObjectParameterivARB GetObjectParameterivARB}. This status will be set to {@link GL11#GL_TRUE TRUE} if a valid executable is created, and {@link GL11#GL_FALSE FALSE} otherwise. Linking can fail for a + * variety of reasons as specified in the OpenGL Shading Language Specification. Linking will also fail if one or more of the shader objects, attached to + * {@code programObj}, are not compiled successfully, or if more active uniform or active sampler variables are used in {@code programObj} than allowed. + * If LinkProgramARB failed, any information about a previous link is lost and is not restored. Thus a failed link does not restore the old state of + * {@code programObj}. If {@code programObj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB}, the error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated.

+ * + *

Each program object has an information log that is modified as a result of a link operation. This information log can be queried with {@link #glGetInfoLogARB GetInfoLogARB} + * to obtain more information about the link operation.

+ * + * @param programObj the program object to link + */ + public static native void glLinkProgramARB(@NativeType("GLhandleARB") int programObj); + + // --- [ glUseProgramObjectARB ] --- + + /** + * Installs the executable code as part of current rendering state if the program object {@code programObj} contains valid executable code, i.e. has been + * linked successfully. If UseProgramObjectARB is called with the handle set to 0, it is as if the GL had no programmable stages and the fixed + * functionality paths will be used instead. If {@code programObj} cannot be made part of the current rendering state, an {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} error will + * be generated and the current rendering state left unmodified. This error will be set, for example, if {@code programObj} has not been linked + * successfully. If {@code programObj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB}, the error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. + * + *

While a program object is in use, applications are free to modify attached shader objects, compile attached shader objects, attach additional shader + * objects, and detach shader objects. This does not affect the link status {@link #GL_OBJECT_LINK_STATUS_ARB OBJECT_LINK_STATUS_ARB} of the program object. This does not affect the + * executable code that is part of the current state either. That executable code is only affected when the program object has been re-linked successfully. + * After such a successful re-link, the {@link #glLinkProgramARB LinkProgramARB} command will install the generated executable code as part of the current rendering state if the + * specified program object was already in use as a result of a previous call to UseProgramObjectARB. If this re-link failed, then the executable code part + * of the current state does not change.

+ * + * @param programObj the program object to use + */ + public static native void glUseProgramObjectARB(@NativeType("GLhandleARB") int programObj); + + // --- [ glValidateProgramARB ] --- + + /** + * Validates the program object {@code programObj} against the GL state at that moment. Each program object has a Boolean status, + * {@link #GL_OBJECT_VALIDATE_STATUS_ARB OBJECT_VALIDATE_STATUS_ARB}, that is modified as a result of validation. This status can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If validation + * succeeded this status will be set to {@link GL11#GL_TRUE TRUE}, otherwise it will be set to {@link GL11#GL_FALSE FALSE}. If validation succeeded the program object is guaranteed to + * execute, given the current GL state. If validation failed, the program object is guaranteed to not execute, given the current GL state. If + * {@code programObj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB}, the error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. + * + *

ValidateProgramARB will validate at least as much as is done when a rendering command is issued, and it could validate more. For example, it could give + * a hint on how to optimize some piece of shader code.

+ * + *

ValidateProgramARB will store its information in the info log. This information will either be an empty string or it will contain validation information.

+ * + *

ValidateProgramARB is typically only useful during application development. An application should not expect different OpenGL implementations to produce + * identical information.

+ * + * @param programObj the program object to validate + */ + public static native void glValidateProgramARB(@NativeType("GLhandleARB") int programObj); + + // --- [ glUniform1fARB ] --- + + /** + * float version of {@link #glUniform4fARB Uniform4fARB}. + * + * @param location the uniform variable location + * @param v0 the uniform x value + */ + public static native void glUniform1fARB(@NativeType("GLint") int location, @NativeType("GLfloat") float v0); + + // --- [ glUniform2fARB ] --- + + /** + * vec2 version of {@link #glUniform4fARB Uniform4fARB}. + * + * @param location the uniform variable location + * @param v0 the uniform x value + * @param v1 the uniform y value + */ + public static native void glUniform2fARB(@NativeType("GLint") int location, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1); + + // --- [ glUniform3fARB ] --- + + /** + * vec3 version of {@link #glUniform4fARB Uniform4fARB}. + * + * @param location the uniform variable location + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + */ + public static native void glUniform3fARB(@NativeType("GLint") int location, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2); + + // --- [ glUniform4fARB ] --- + + /** + * Loads a vec4 value into a uniform variable of the program object that is currently in use. + * + * @param location the uniform variable location + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + * @param v3 the uniform w value + */ + public static native void glUniform4fARB(@NativeType("GLint") int location, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2, @NativeType("GLfloat") float v3); + + // --- [ glUniform1iARB ] --- + + /** + * int version of {@link #glUniform1fARB Uniform1fARB}. + * + * @param location the uniform variable location + * @param v0 the uniform x value + */ + public static native void glUniform1iARB(@NativeType("GLint") int location, @NativeType("GLint") int v0); + + // --- [ glUniform2iARB ] --- + + /** + * ivec2 version of {@link #glUniform2fARB Uniform2fARB}. + * + * @param location the uniform variable location + * @param v0 the uniform x value + * @param v1 the uniform y value + */ + public static native void glUniform2iARB(@NativeType("GLint") int location, @NativeType("GLint") int v0, @NativeType("GLint") int v1); + + // --- [ glUniform3iARB ] --- + + /** + * ivec3 version of {@link #glUniform3fARB Uniform3fARB}. + * + * @param location the uniform variable location + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + */ + public static native void glUniform3iARB(@NativeType("GLint") int location, @NativeType("GLint") int v0, @NativeType("GLint") int v1, @NativeType("GLint") int v2); + + // --- [ glUniform4iARB ] --- + + /** + * ivec4 version of {@link #glUniform4fARB Uniform4fARB}. + * + * @param location the uniform variable location + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + * @param v3 the uniform w value + */ + public static native void glUniform4iARB(@NativeType("GLint") int location, @NativeType("GLint") int v0, @NativeType("GLint") int v1, @NativeType("GLint") int v2, @NativeType("GLint") int v3); + + // --- [ glUniform1fvARB ] --- + + /** + * Unsafe version of: {@link #glUniform1fvARB Uniform1fvARB} + * + * @param count the number of float values to load + */ + public static native void nglUniform1fvARB(int location, int count, long value); + + /** + * Loads floating-point values {@code count} times into a uniform location defined as an array of float values. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform1fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + nglUniform1fvARB(location, value.remaining(), memAddress(value)); + } + + // --- [ glUniform2fvARB ] --- + + /** + * Unsafe version of: {@link #glUniform2fvARB Uniform2fvARB} + * + * @param count the number of vec2 vectors to load + */ + public static native void nglUniform2fvARB(int location, int count, long value); + + /** + * Loads floating-point values {@code count} times into a uniform location defined as an array of vec2 vectors. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform2fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + nglUniform2fvARB(location, value.remaining() >> 1, memAddress(value)); + } + + // --- [ glUniform3fvARB ] --- + + /** + * Unsafe version of: {@link #glUniform3fvARB Uniform3fvARB} + * + * @param count the number of vec3 vectors to load + */ + public static native void nglUniform3fvARB(int location, int count, long value); + + /** + * Loads floating-point values {@code count} times into a uniform location defined as an array of vec3 vectors. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform3fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + nglUniform3fvARB(location, value.remaining() / 3, memAddress(value)); + } + + // --- [ glUniform4fvARB ] --- + + /** + * Unsafe version of: {@link #glUniform4fvARB Uniform4fvARB} + * + * @param count the number of vec4 vectors to load + */ + public static native void nglUniform4fvARB(int location, int count, long value); + + /** + * Loads floating-point values {@code count} times into a uniform location defined as an array of vec4 vectors. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform4fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + nglUniform4fvARB(location, value.remaining() >> 2, memAddress(value)); + } + + // --- [ glUniform1ivARB ] --- + + /** + * Unsafe version of: {@link #glUniform1ivARB Uniform1ivARB} + * + * @param count the number of integer values to load + */ + public static native void nglUniform1ivARB(int location, int count, long value); + + /** + * Loads integer values {@code count} times into a uniform location defined as an array of integer values. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform1ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + nglUniform1ivARB(location, value.remaining(), memAddress(value)); + } + + // --- [ glUniform2ivARB ] --- + + /** + * Unsafe version of: {@link #glUniform2ivARB Uniform2ivARB} + * + * @param count the number of ivec2 vectors to load + */ + public static native void nglUniform2ivARB(int location, int count, long value); + + /** + * Loads integer values {@code count} times into a uniform location defined as an array of ivec2 vectors. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform2ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + nglUniform2ivARB(location, value.remaining() >> 1, memAddress(value)); + } + + // --- [ glUniform3ivARB ] --- + + /** + * Unsafe version of: {@link #glUniform3ivARB Uniform3ivARB} + * + * @param count the number of ivec3 vectors to load + */ + public static native void nglUniform3ivARB(int location, int count, long value); + + /** + * Loads integer values {@code count} times into a uniform location defined as an array of ivec3 vectors. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform3ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + nglUniform3ivARB(location, value.remaining() / 3, memAddress(value)); + } + + // --- [ glUniform4ivARB ] --- + + /** + * Unsafe version of: {@link #glUniform4ivARB Uniform4ivARB} + * + * @param count the number of ivec4 vectors to load + */ + public static native void nglUniform4ivARB(int location, int count, long value); + + /** + * Loads integer values {@code count} times into a uniform location defined as an array of ivec4 vectors. + * + * @param location the uniform variable location + * @param value the values to load + */ + public static void glUniform4ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + nglUniform4ivARB(location, value.remaining() >> 2, memAddress(value)); + } + + // --- [ glUniformMatrix2fvARB ] --- + + /** + * Unsafe version of: {@link #glUniformMatrix2fvARB UniformMatrix2fvARB} + * + * @param count the number of 2x2 matrices to load + */ + public static native void nglUniformMatrix2fvARB(int location, int count, boolean transpose, long value); + + /** + * Loads a 2x2 matrix of floating-point values {@code count} times into a uniform location defined as a matrix or an array of matrices. + * + * @param location the uniform variable location + * @param transpose if {@link GL11#GL_FALSE FALSE}, the matrix is specified in column major order, otherwise in row major order + * @param value the matrix values to load + */ + public static void glUniformMatrix2fvARB(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") FloatBuffer value) { + nglUniformMatrix2fvARB(location, value.remaining() >> 2, transpose, memAddress(value)); + } + + // --- [ glUniformMatrix3fvARB ] --- + + /** + * Unsafe version of: {@link #glUniformMatrix3fvARB UniformMatrix3fvARB} + * + * @param count the number of 3x3 matrices to load + */ + public static native void nglUniformMatrix3fvARB(int location, int count, boolean transpose, long value); + + /** + * Loads a 3x3 matrix of floating-point values {@code count} times into a uniform location defined as a matrix or an array of matrices. + * + * @param location the uniform variable location + * @param transpose if {@link GL11#GL_FALSE FALSE}, the matrix is specified in column major order, otherwise in row major order + * @param value the matrix values to load + */ + public static void glUniformMatrix3fvARB(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") FloatBuffer value) { + nglUniformMatrix3fvARB(location, value.remaining() / 9, transpose, memAddress(value)); + } + + // --- [ glUniformMatrix4fvARB ] --- + + /** + * Unsafe version of: {@link #glUniformMatrix4fvARB UniformMatrix4fvARB} + * + * @param count the number of 4x4 matrices to load + */ + public static native void nglUniformMatrix4fvARB(int location, int count, boolean transpose, long value); + + /** + * Loads a 4x4 matrix of floating-point values {@code count} times into a uniform location defined as a matrix or an array of matrices. + * + * @param location the uniform variable location + * @param transpose if {@link GL11#GL_FALSE FALSE}, the matrix is specified in column major order, otherwise in row major order + * @param value the matrix values to load + */ + public static void glUniformMatrix4fvARB(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") FloatBuffer value) { + nglUniformMatrix4fvARB(location, value.remaining() >> 4, transpose, memAddress(value)); + } + + // --- [ glGetObjectParameterfvARB ] --- + + /** Unsafe version of: {@link #glGetObjectParameterfvARB GetObjectParameterfvARB} */ + public static native void nglGetObjectParameterfvARB(int obj, int pname, long params); + + /** + * Returns object specific parameter values. + * + * @param obj the object to query + * @param pname the parameter to query + * @param params a buffer in which to return the parameter value + */ + public static void glGetObjectParameterfvARB(@NativeType("GLhandleARB") int obj, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer params) { + if (CHECKS) { + check(params, 1); + } + nglGetObjectParameterfvARB(obj, pname, memAddress(params)); + } + + // --- [ glGetObjectParameterivARB ] --- + + /** Unsafe version of: {@link #glGetObjectParameterivARB GetObjectParameterivARB} */ + public static native void nglGetObjectParameterivARB(int obj, int pname, long params); + + /** + * Returns object specific parameter values. + * + * @param obj the object to query + * @param pname the parameter to query. One of:
{@link #GL_OBJECT_TYPE_ARB OBJECT_TYPE_ARB}{@link #GL_OBJECT_SUBTYPE_ARB OBJECT_SUBTYPE_ARB}{@link #GL_OBJECT_DELETE_STATUS_ARB OBJECT_DELETE_STATUS_ARB}
{@link #GL_OBJECT_COMPILE_STATUS_ARB OBJECT_COMPILE_STATUS_ARB}{@link #GL_OBJECT_LINK_STATUS_ARB OBJECT_LINK_STATUS_ARB}{@link #GL_OBJECT_VALIDATE_STATUS_ARB OBJECT_VALIDATE_STATUS_ARB}
{@link #GL_OBJECT_INFO_LOG_LENGTH_ARB OBJECT_INFO_LOG_LENGTH_ARB}{@link #GL_OBJECT_ATTACHED_OBJECTS_ARB OBJECT_ATTACHED_OBJECTS_ARB}{@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB}
{@link #GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB}{@link #GL_OBJECT_SHADER_SOURCE_LENGTH_ARB OBJECT_SHADER_SOURCE_LENGTH_ARB}
+ * @param params a buffer in which to return the parameter value + */ + public static void glGetObjectParameterivARB(@NativeType("GLhandleARB") int obj, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + if (CHECKS) { + check(params, 1); + } + nglGetObjectParameterivARB(obj, pname, memAddress(params)); + } + + /** + * Returns object specific parameter values. + * + * @param obj the object to query + * @param pname the parameter to query. One of:
{@link #GL_OBJECT_TYPE_ARB OBJECT_TYPE_ARB}{@link #GL_OBJECT_SUBTYPE_ARB OBJECT_SUBTYPE_ARB}{@link #GL_OBJECT_DELETE_STATUS_ARB OBJECT_DELETE_STATUS_ARB}
{@link #GL_OBJECT_COMPILE_STATUS_ARB OBJECT_COMPILE_STATUS_ARB}{@link #GL_OBJECT_LINK_STATUS_ARB OBJECT_LINK_STATUS_ARB}{@link #GL_OBJECT_VALIDATE_STATUS_ARB OBJECT_VALIDATE_STATUS_ARB}
{@link #GL_OBJECT_INFO_LOG_LENGTH_ARB OBJECT_INFO_LOG_LENGTH_ARB}{@link #GL_OBJECT_ATTACHED_OBJECTS_ARB OBJECT_ATTACHED_OBJECTS_ARB}{@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB}
{@link #GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB}{@link #GL_OBJECT_SHADER_SOURCE_LENGTH_ARB OBJECT_SHADER_SOURCE_LENGTH_ARB}
+ */ + @NativeType("void") + public static int glGetObjectParameteriARB(@NativeType("GLhandleARB") int obj, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer params = stack.callocInt(1); + nglGetObjectParameterivARB(obj, pname, memAddress(params)); + return params.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetInfoLogARB ] --- + + /** + * Unsafe version of: {@link #glGetInfoLogARB GetInfoLogARB} + * + * @param maxLength the maximum number of characters the GL is allowed to write into {@code infoLog} + */ + public static native void nglGetInfoLogARB(int obj, int maxLength, long length, long infoLog); + + /** + * A string that contains information about the last link or validation attempt and last compilation attempt are kept per program or shader object. This + * string is called the info log and can be obtained with this command. + * + *

This string will be null terminated. The number of characters in the info log is given by {@link #GL_OBJECT_INFO_LOG_LENGTH_ARB OBJECT_INFO_LOG_LENGTH_ARB}, which can be queried with + * {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code obj} is a shader object, the returned info log will either be an empty string or it will contain + * information about the last compilation attempt for that object. If {@code obj} is a program object, the returned info log will either be an empty string + * or it will contain information about the last link attempt or last validation attempt for that object. If {@code obj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB} + * or {@link #GL_SHADER_OBJECT_ARB SHADER_OBJECT_ARB}, the error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. If an error occurred, the return parameters {@code length} and {@code infoLog} + * will be unmodified.

+ * + *

The info log is typically only useful during application development and an application should not expect different OpenGL implementations to produce + * identical info logs.

+ * + * @param obj the shader object to query + * @param length the actual number of characters written by the GL into {@code infoLog} is returned in {@code length}, excluding the null termination. If + * {@code length} is {@code NULL} then the GL ignores this parameter. + * @param infoLog a buffer in which to return the info log + */ + public static void glGetInfoLogARB(@NativeType("GLhandleARB") int obj, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLcharARB *") ByteBuffer infoLog) { + if (CHECKS) { + checkSafe(length, 1); + } + nglGetInfoLogARB(obj, infoLog.remaining(), memAddressSafe(length), memAddress(infoLog)); + } + + /** + * A string that contains information about the last link or validation attempt and last compilation attempt are kept per program or shader object. This + * string is called the info log and can be obtained with this command. + * + *

This string will be null terminated. The number of characters in the info log is given by {@link #GL_OBJECT_INFO_LOG_LENGTH_ARB OBJECT_INFO_LOG_LENGTH_ARB}, which can be queried with + * {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code obj} is a shader object, the returned info log will either be an empty string or it will contain + * information about the last compilation attempt for that object. If {@code obj} is a program object, the returned info log will either be an empty string + * or it will contain information about the last link attempt or last validation attempt for that object. If {@code obj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB} + * or {@link #GL_SHADER_OBJECT_ARB SHADER_OBJECT_ARB}, the error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. If an error occurred, the return parameters {@code length} and {@code infoLog} + * will be unmodified.

+ * + *

The info log is typically only useful during application development and an application should not expect different OpenGL implementations to produce + * identical info logs.

+ * + * @param obj the shader object to query + * @param maxLength the maximum number of characters the GL is allowed to write into {@code infoLog} + */ + @NativeType("void") + public static String glGetInfoLogARB(@NativeType("GLhandleARB") int obj, @NativeType("GLsizei") int maxLength) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + ByteBuffer infoLog = memAlloc(maxLength); + try { + IntBuffer length = stack.ints(0); + nglGetInfoLogARB(obj, maxLength, memAddress(length), memAddress(infoLog)); + return memUTF8(infoLog, length.get(0)); + } finally { + memFree(infoLog); + stack.setPointer(stackPointer); + } + } + + /** + * A string that contains information about the last link or validation attempt and last compilation attempt are kept per program or shader object. This + * string is called the info log and can be obtained with this command. + * + *

This string will be null terminated. The number of characters in the info log is given by {@link #GL_OBJECT_INFO_LOG_LENGTH_ARB OBJECT_INFO_LOG_LENGTH_ARB}, which can be queried with + * {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code obj} is a shader object, the returned info log will either be an empty string or it will contain + * information about the last compilation attempt for that object. If {@code obj} is a program object, the returned info log will either be an empty string + * or it will contain information about the last link attempt or last validation attempt for that object. If {@code obj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB} + * or {@link #GL_SHADER_OBJECT_ARB SHADER_OBJECT_ARB}, the error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. If an error occurred, the return parameters {@code length} and {@code infoLog} + * will be unmodified.

+ * + *

The info log is typically only useful during application development and an application should not expect different OpenGL implementations to produce + * identical info logs.

+ * + * @param obj the shader object to query + */ + @NativeType("void") + public static String glGetInfoLogARB(@NativeType("GLhandleARB") int obj) { + return glGetInfoLogARB(obj, glGetObjectParameteriARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB)); + } + + // --- [ glGetAttachedObjectsARB ] --- + + /** + * Unsafe version of: {@link #glGetAttachedObjectsARB GetAttachedObjectsARB} + * + * @param maxCount the maximum number of handles the GL is allowed to write into {@code obj} + */ + public static native void nglGetAttachedObjectsARB(int containerObj, int maxCount, long count, long obj); + + /** + * Returns the handles of objects attached to {@code containerObj} in {@code obj}. . The number of objects attached to {@code containerObj} is given by + * {@link #GL_OBJECT_ATTACHED_OBJECTS_ARB OBJECT_ATTACHED_OBJECTS_ARB}, which can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code containerObj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB}, the + * error {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. If an error occurred, the return parameters {@code count} and {@code obj} will be unmodified. + * + * @param containerObj the container object to query + * @param count a buffer in which to return the actual number of object handles written by the GL into {@code obj}. If {@code NULL} then the GL ignores this parameter. + * @param obj a buffer in which to return the attached object handles + */ + public static void glGetAttachedObjectsARB(@NativeType("GLhandleARB") int containerObj, @Nullable @NativeType("GLsizei *") IntBuffer count, @NativeType("GLhandleARB *") IntBuffer obj) { + if (CHECKS) { + checkSafe(count, 1); + } + nglGetAttachedObjectsARB(containerObj, obj.remaining(), memAddressSafe(count), memAddress(obj)); + } + + // --- [ glGetUniformLocationARB ] --- + + /** Unsafe version of: {@link #glGetUniformLocationARB GetUniformLocationARB} */ + public static native int nglGetUniformLocationARB(int programObj, long name); + + /** + * Returns the location of uniform variable {@code name}. {@code name} has to be a null terminated string, without white space. The value of -1 will be + * returned if {@code name} does not correspond to an active uniform variable name in {@code programObj} or if {@code name} starts with the reserved prefix + * "gl_". If {@code programObj} has not been successfully linked, or if {@code programObj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB}, the error + * {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. The location of a uniform variable does not change until the next link command is issued. + * + *

A valid {@code name} cannot be a structure, an array of structures, or a subcomponent of a vector or a matrix. In order to identify a valid {@code name}, + * the "." (dot) and "[]" operators can be used in {@code name} to operate on a structure or to operate on an array.

+ * + *

The first element of a uniform array is identified using the name of the uniform array appended with "[0]". Except if the last part of the string + * {@code name} indicates a uniform array, then the location of the first element of that array can be retrieved by either using the name of the uniform + * array, or the name of the uniform array appended with "[0]".

+ * + * @param programObj the program object to query + * @param name the name of the uniform variable whose location is to be queried + */ + @NativeType("GLint") + public static int glGetUniformLocationARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLcharARB const *") ByteBuffer name) { + if (CHECKS) { + checkNT1(name); + } + return nglGetUniformLocationARB(programObj, memAddress(name)); + } + + /** + * Returns the location of uniform variable {@code name}. {@code name} has to be a null terminated string, without white space. The value of -1 will be + * returned if {@code name} does not correspond to an active uniform variable name in {@code programObj} or if {@code name} starts with the reserved prefix + * "gl_". If {@code programObj} has not been successfully linked, or if {@code programObj} is not of type {@link #GL_PROGRAM_OBJECT_ARB PROGRAM_OBJECT_ARB}, the error + * {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. The location of a uniform variable does not change until the next link command is issued. + * + *

A valid {@code name} cannot be a structure, an array of structures, or a subcomponent of a vector or a matrix. In order to identify a valid {@code name}, + * the "." (dot) and "[]" operators can be used in {@code name} to operate on a structure or to operate on an array.

+ * + *

The first element of a uniform array is identified using the name of the uniform array appended with "[0]". Except if the last part of the string + * {@code name} indicates a uniform array, then the location of the first element of that array can be retrieved by either using the name of the uniform + * array, or the name of the uniform array appended with "[0]".

+ * + * @param programObj the program object to query + * @param name the name of the uniform variable whose location is to be queried + */ + @NativeType("GLint") + public static int glGetUniformLocationARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLcharARB const *") CharSequence name) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + stack.nUTF8(name, true); + long nameEncoded = stack.getPointerAddress(); + return nglGetUniformLocationARB(programObj, nameEncoded); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetActiveUniformARB ] --- + + /** + * Unsafe version of: {@link #glGetActiveUniformARB GetActiveUniformARB} + * + * @param maxLength the maximum number of characters the GL is allowed to write into {@code name}. + */ + public static native void nglGetActiveUniformARB(int programObj, int index, int maxLength, long length, long size, long type, long name); + + /** + * Determines which of the declared uniform variables are active and their sizes and types. + * + *

This command provides information about the uniform selected by {@code index}. The {@code index} of 0 selects the first active uniform, and + * {@code index} of {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB} - 1 selects the last active uniform. The value of {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB} can be queried with + * {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code index} is greater than or equal to {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB}, the error {@link GL11#GL_INVALID_VALUE INVALID_VALUE} is generated.

+ * + *

If an error occurred, the return parameters {@code length}, {@code size}, {@code type} and {@code name} will be unmodified.

+ * + *

The returned uniform name can be the name of built-in uniform state as well. The length of the longest uniform name in {@code programObj} is given by + * {@link #GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB}, which can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}.

+ * + *

Each uniform variable, declared in a shader, is broken down into one or more strings using the "." (dot) and "[]" operators, if necessary, to the point + * that it is legal to pass each string back into {@link #glGetUniformLocationARB GetUniformLocationARB}. Each of these strings constitutes one active uniform, and each string is + * assigned an index.

+ * + *

If one or more elements of an array are active, GetActiveUniformARB will return the name of the array in {@code name}, subject to the restrictions + * listed above. The type of the array is returned in {@code type}. The {@code size} parameter contains the highest array element index used, plus one. The + * compiler or linker determines the highest index used. There will be only one active uniform reported by the GL per uniform array.

+ * + *

This command will return as much information about active uniforms as possible. If no information is available, {@code length} will be set to zero and + * {@code name} will be an empty string. This situation could arise if GetActiveUniformARB is issued after a failed link.

+ * + * @param programObj a handle to a program object for which the command {@link #glLinkProgramARB LinkProgramARB} has been issued in the past. It is not necessary for {@code programObj} to have + * been linked successfully. The link could have failed because the number of active uniforms exceeded the limit. + * @param index the uniform index + * @param length a buffer in which to return the actual number of characters written by the GL into {@code name}. This count excludes the null termination. If + * {@code length} is {@code NULL} then the GL ignores this parameter. + * @param size a buffer in which to return the uniform size. The size is in units of the type returned in {@code type}. + * @param type a buffer in which to return the uniform type + * @param name a buffer in which to return the uniform name + */ + public static void glGetActiveUniformARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLuint") int index, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type, @NativeType("GLcharARB *") ByteBuffer name) { + if (CHECKS) { + checkSafe(length, 1); + check(size, 1); + check(type, 1); + } + nglGetActiveUniformARB(programObj, index, name.remaining(), memAddressSafe(length), memAddress(size), memAddress(type), memAddress(name)); + } + + /** + * Determines which of the declared uniform variables are active and their sizes and types. + * + *

This command provides information about the uniform selected by {@code index}. The {@code index} of 0 selects the first active uniform, and + * {@code index} of {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB} - 1 selects the last active uniform. The value of {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB} can be queried with + * {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code index} is greater than or equal to {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB}, the error {@link GL11#GL_INVALID_VALUE INVALID_VALUE} is generated.

+ * + *

If an error occurred, the return parameters {@code length}, {@code size}, {@code type} and {@code name} will be unmodified.

+ * + *

The returned uniform name can be the name of built-in uniform state as well. The length of the longest uniform name in {@code programObj} is given by + * {@link #GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB}, which can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}.

+ * + *

Each uniform variable, declared in a shader, is broken down into one or more strings using the "." (dot) and "[]" operators, if necessary, to the point + * that it is legal to pass each string back into {@link #glGetUniformLocationARB GetUniformLocationARB}. Each of these strings constitutes one active uniform, and each string is + * assigned an index.

+ * + *

If one or more elements of an array are active, GetActiveUniformARB will return the name of the array in {@code name}, subject to the restrictions + * listed above. The type of the array is returned in {@code type}. The {@code size} parameter contains the highest array element index used, plus one. The + * compiler or linker determines the highest index used. There will be only one active uniform reported by the GL per uniform array.

+ * + *

This command will return as much information about active uniforms as possible. If no information is available, {@code length} will be set to zero and + * {@code name} will be an empty string. This situation could arise if GetActiveUniformARB is issued after a failed link.

+ * + * @param programObj a handle to a program object for which the command {@link #glLinkProgramARB LinkProgramARB} has been issued in the past. It is not necessary for {@code programObj} to have + * been linked successfully. The link could have failed because the number of active uniforms exceeded the limit. + * @param index the uniform index + * @param maxLength the maximum number of characters the GL is allowed to write into {@code name}. + * @param size a buffer in which to return the uniform size. The size is in units of the type returned in {@code type}. + * @param type a buffer in which to return the uniform type + */ + @NativeType("void") + public static String glGetActiveUniformARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLuint") int index, @NativeType("GLsizei") int maxLength, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type) { + if (CHECKS) { + check(size, 1); + check(type, 1); + } + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer length = stack.ints(0); + ByteBuffer name = stack.malloc(maxLength); + nglGetActiveUniformARB(programObj, index, maxLength, memAddress(length), memAddress(size), memAddress(type), memAddress(name)); + return memUTF8(name, length.get(0)); + } finally { + stack.setPointer(stackPointer); + } + } + + /** + * Determines which of the declared uniform variables are active and their sizes and types. + * + *

This command provides information about the uniform selected by {@code index}. The {@code index} of 0 selects the first active uniform, and + * {@code index} of {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB} - 1 selects the last active uniform. The value of {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB} can be queried with + * {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code index} is greater than or equal to {@link #GL_OBJECT_ACTIVE_UNIFORMS_ARB OBJECT_ACTIVE_UNIFORMS_ARB}, the error {@link GL11#GL_INVALID_VALUE INVALID_VALUE} is generated.

+ * + *

If an error occurred, the return parameters {@code length}, {@code size}, {@code type} and {@code name} will be unmodified.

+ * + *

The returned uniform name can be the name of built-in uniform state as well. The length of the longest uniform name in {@code programObj} is given by + * {@link #GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB}, which can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}.

+ * + *

Each uniform variable, declared in a shader, is broken down into one or more strings using the "." (dot) and "[]" operators, if necessary, to the point + * that it is legal to pass each string back into {@link #glGetUniformLocationARB GetUniformLocationARB}. Each of these strings constitutes one active uniform, and each string is + * assigned an index.

+ * + *

If one or more elements of an array are active, GetActiveUniformARB will return the name of the array in {@code name}, subject to the restrictions + * listed above. The type of the array is returned in {@code type}. The {@code size} parameter contains the highest array element index used, plus one. The + * compiler or linker determines the highest index used. There will be only one active uniform reported by the GL per uniform array.

+ * + *

This command will return as much information about active uniforms as possible. If no information is available, {@code length} will be set to zero and + * {@code name} will be an empty string. This situation could arise if GetActiveUniformARB is issued after a failed link.

+ * + * @param programObj a handle to a program object for which the command {@link #glLinkProgramARB LinkProgramARB} has been issued in the past. It is not necessary for {@code programObj} to have + * been linked successfully. The link could have failed because the number of active uniforms exceeded the limit. + * @param index the uniform index + * @param size a buffer in which to return the uniform size. The size is in units of the type returned in {@code type}. + * @param type a buffer in which to return the uniform type + */ + @NativeType("void") + public static String glGetActiveUniformARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLuint") int index, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type) { + return glGetActiveUniformARB(programObj, index, glGetObjectParameteriARB(programObj, GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB), size, type); + } + + // --- [ glGetUniformfvARB ] --- + + /** Unsafe version of: {@link #glGetUniformfvARB GetUniformfvARB} */ + public static native void nglGetUniformfvARB(int programObj, int location, long params); + + /** + * Returns the floating-point value or values of a uniform. + * + * @param programObj the program object to query + * @param location the uniform variable location + * @param params a buffer in which to return the uniform values + */ + public static void glGetUniformfvARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLint") int location, @NativeType("GLfloat *") FloatBuffer params) { + if (CHECKS) { + check(params, 1); + } + nglGetUniformfvARB(programObj, location, memAddress(params)); + } + + /** + * Returns the floating-point value or values of a uniform. + * + * @param programObj the program object to query + * @param location the uniform variable location + */ + @NativeType("void") + public static float glGetUniformfARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLint") int location) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer params = stack.callocFloat(1); + nglGetUniformfvARB(programObj, location, memAddress(params)); + return params.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetUniformivARB ] --- + + /** Unsafe version of: {@link #glGetUniformivARB GetUniformivARB} */ + public static native void nglGetUniformivARB(int programObj, int location, long params); + + /** + * Returns the integer value or values of a uniform. + * + * @param programObj the program object to query + * @param location the uniform variable location + * @param params a buffer in which to return the uniform values + */ + public static void glGetUniformivARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLint") int location, @NativeType("GLint *") IntBuffer params) { + if (CHECKS) { + check(params, 1); + } + nglGetUniformivARB(programObj, location, memAddress(params)); + } + + /** + * Returns the integer value or values of a uniform. + * + * @param programObj the program object to query + * @param location the uniform variable location + */ + @NativeType("void") + public static int glGetUniformiARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLint") int location) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer params = stack.callocInt(1); + nglGetUniformivARB(programObj, location, memAddress(params)); + return params.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetShaderSourceARB ] --- + + /** + * Unsafe version of: {@link #glGetShaderSourceARB GetShaderSourceARB} + * + * @param maxLength the maximum number of characters the GL is allowed to write into {@code source} + */ + public static native void nglGetShaderSourceARB(int obj, int maxLength, long length, long source); + + /** + * Returns the string making up the source code for a shader object. + * + *

The string {@code source} is a concatenation of the strings passed to OpenGL using {@link #glShaderSourceARB ShaderSourceARB}. The length of this concatenation is given by + * {@link #GL_OBJECT_SHADER_SOURCE_LENGTH_ARB OBJECT_SHADER_SOURCE_LENGTH_ARB}, which can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code obj} is not of type {@link #GL_SHADER_OBJECT_ARB SHADER_OBJECT_ARB}, the error + * {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. If an error occurred, the return parameters {@code length} and {@code source} will be unmodified.

+ * + * @param obj the shader object to query + * @param length a buffer in which to return the actual number of characters written by the GL into {@code source}, excluding the null termination. If + * {@code length} is {@code NULL} then the GL ignores this parameter. + * @param source a buffer in which to return the shader object source + */ + public static void glGetShaderSourceARB(@NativeType("GLhandleARB") int obj, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLcharARB *") ByteBuffer source) { + if (CHECKS) { + checkSafe(length, 1); + } + nglGetShaderSourceARB(obj, source.remaining(), memAddressSafe(length), memAddress(source)); + } + + /** + * Returns the string making up the source code for a shader object. + * + *

The string {@code source} is a concatenation of the strings passed to OpenGL using {@link #glShaderSourceARB ShaderSourceARB}. The length of this concatenation is given by + * {@link #GL_OBJECT_SHADER_SOURCE_LENGTH_ARB OBJECT_SHADER_SOURCE_LENGTH_ARB}, which can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code obj} is not of type {@link #GL_SHADER_OBJECT_ARB SHADER_OBJECT_ARB}, the error + * {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. If an error occurred, the return parameters {@code length} and {@code source} will be unmodified.

+ * + * @param obj the shader object to query + * @param maxLength the maximum number of characters the GL is allowed to write into {@code source} + */ + @NativeType("void") + public static String glGetShaderSourceARB(@NativeType("GLhandleARB") int obj, @NativeType("GLsizei") int maxLength) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + ByteBuffer source = memAlloc(maxLength); + try { + IntBuffer length = stack.ints(0); + nglGetShaderSourceARB(obj, maxLength, memAddress(length), memAddress(source)); + return memUTF8(source, length.get(0)); + } finally { + memFree(source); + stack.setPointer(stackPointer); + } + } + + /** + * Returns the string making up the source code for a shader object. + * + *

The string {@code source} is a concatenation of the strings passed to OpenGL using {@link #glShaderSourceARB ShaderSourceARB}. The length of this concatenation is given by + * {@link #GL_OBJECT_SHADER_SOURCE_LENGTH_ARB OBJECT_SHADER_SOURCE_LENGTH_ARB}, which can be queried with {@link #glGetObjectParameterivARB GetObjectParameterivARB}. If {@code obj} is not of type {@link #GL_SHADER_OBJECT_ARB SHADER_OBJECT_ARB}, the error + * {@link GL11#GL_INVALID_OPERATION INVALID_OPERATION} is generated. If an error occurred, the return parameters {@code length} and {@code source} will be unmodified.

+ * + * @param obj the shader object to query + */ + @NativeType("void") + public static String glGetShaderSourceARB(@NativeType("GLhandleARB") int obj) { + return glGetShaderSourceARB(obj, glGetObjectParameteriARB(obj, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB)); + } + + /** Array version of: {@link #glShaderSourceARB ShaderSourceARB} */ + public static void glShaderSourceARB(@NativeType("GLhandleARB") int shaderObj, @NativeType("GLcharARB const **") PointerBuffer string, @Nullable @NativeType("GLint const *") int[] length) { + long __functionAddress = GL.getICD().glShaderSourceARB; + if (CHECKS) { + check(__functionAddress); + checkSafe(length, string.remaining()); + } + callPPV(shaderObj, string.remaining(), memAddress(string), length, __functionAddress); + } + + /** Array version of: {@link #glUniform1fvARB Uniform1fvARB} */ + public static void glUniform1fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + long __functionAddress = GL.getICD().glUniform1fvARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length, value, __functionAddress); + } + + /** Array version of: {@link #glUniform2fvARB Uniform2fvARB} */ + public static void glUniform2fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + long __functionAddress = GL.getICD().glUniform2fvARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length >> 1, value, __functionAddress); + } + + /** Array version of: {@link #glUniform3fvARB Uniform3fvARB} */ + public static void glUniform3fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + long __functionAddress = GL.getICD().glUniform3fvARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length / 3, value, __functionAddress); + } + + /** Array version of: {@link #glUniform4fvARB Uniform4fvARB} */ + public static void glUniform4fvARB(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + long __functionAddress = GL.getICD().glUniform4fvARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length >> 2, value, __functionAddress); + } + + /** Array version of: {@link #glUniform1ivARB Uniform1ivARB} */ + public static void glUniform1ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + long __functionAddress = GL.getICD().glUniform1ivARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length, value, __functionAddress); + } + + /** Array version of: {@link #glUniform2ivARB Uniform2ivARB} */ + public static void glUniform2ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + long __functionAddress = GL.getICD().glUniform2ivARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length >> 1, value, __functionAddress); + } + + /** Array version of: {@link #glUniform3ivARB Uniform3ivARB} */ + public static void glUniform3ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + long __functionAddress = GL.getICD().glUniform3ivARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length / 3, value, __functionAddress); + } + + /** Array version of: {@link #glUniform4ivARB Uniform4ivARB} */ + public static void glUniform4ivARB(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + long __functionAddress = GL.getICD().glUniform4ivARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length >> 2, value, __functionAddress); + } + + /** Array version of: {@link #glUniformMatrix2fvARB UniformMatrix2fvARB} */ + public static void glUniformMatrix2fvARB(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") float[] value) { + long __functionAddress = GL.getICD().glUniformMatrix2fvARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length >> 2, transpose, value, __functionAddress); + } + + /** Array version of: {@link #glUniformMatrix3fvARB UniformMatrix3fvARB} */ + public static void glUniformMatrix3fvARB(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") float[] value) { + long __functionAddress = GL.getICD().glUniformMatrix3fvARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length / 9, transpose, value, __functionAddress); + } + + /** Array version of: {@link #glUniformMatrix4fvARB UniformMatrix4fvARB} */ + public static void glUniformMatrix4fvARB(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") float[] value) { + long __functionAddress = GL.getICD().glUniformMatrix4fvARB; + if (CHECKS) { + check(__functionAddress); + } + callPV(location, value.length >> 4, transpose, value, __functionAddress); + } + + /** Array version of: {@link #glGetObjectParameterfvARB GetObjectParameterfvARB} */ + public static void glGetObjectParameterfvARB(@NativeType("GLhandleARB") int obj, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] params) { + long __functionAddress = GL.getICD().glGetObjectParameterfvARB; + if (CHECKS) { + check(__functionAddress); + check(params, 1); + } + callPV(obj, pname, params, __functionAddress); + } + + /** Array version of: {@link #glGetObjectParameterivARB GetObjectParameterivARB} */ + public static void glGetObjectParameterivARB(@NativeType("GLhandleARB") int obj, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + long __functionAddress = GL.getICD().glGetObjectParameterivARB; + if (CHECKS) { + check(__functionAddress); + check(params, 1); + } + callPV(obj, pname, params, __functionAddress); + } + + /** Array version of: {@link #glGetInfoLogARB GetInfoLogARB} */ + public static void glGetInfoLogARB(@NativeType("GLhandleARB") int obj, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLcharARB *") ByteBuffer infoLog) { + long __functionAddress = GL.getICD().glGetInfoLogARB; + if (CHECKS) { + check(__functionAddress); + checkSafe(length, 1); + } + callPPV(obj, infoLog.remaining(), length, memAddress(infoLog), __functionAddress); + } + + /** Array version of: {@link #glGetAttachedObjectsARB GetAttachedObjectsARB} */ + public static void glGetAttachedObjectsARB(@NativeType("GLhandleARB") int containerObj, @Nullable @NativeType("GLsizei *") int[] count, @NativeType("GLhandleARB *") int[] obj) { + long __functionAddress = GL.getICD().glGetAttachedObjectsARB; + if (CHECKS) { + check(__functionAddress); + checkSafe(count, 1); + } + callPPV(containerObj, obj.length, count, obj, __functionAddress); + } + + /** Array version of: {@link #glGetActiveUniformARB GetActiveUniformARB} */ + public static void glGetActiveUniformARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLuint") int index, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLint *") int[] size, @NativeType("GLenum *") int[] type, @NativeType("GLcharARB *") ByteBuffer name) { + long __functionAddress = GL.getICD().glGetActiveUniformARB; + if (CHECKS) { + check(__functionAddress); + checkSafe(length, 1); + check(size, 1); + check(type, 1); + } + callPPPPV(programObj, index, name.remaining(), length, size, type, memAddress(name), __functionAddress); + } + + /** Array version of: {@link #glGetUniformfvARB GetUniformfvARB} */ + public static void glGetUniformfvARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLint") int location, @NativeType("GLfloat *") float[] params) { + long __functionAddress = GL.getICD().glGetUniformfvARB; + if (CHECKS) { + check(__functionAddress); + check(params, 1); + } + callPV(programObj, location, params, __functionAddress); + } + + /** Array version of: {@link #glGetUniformivARB GetUniformivARB} */ + public static void glGetUniformivARB(@NativeType("GLhandleARB") int programObj, @NativeType("GLint") int location, @NativeType("GLint *") int[] params) { + long __functionAddress = GL.getICD().glGetUniformivARB; + if (CHECKS) { + check(__functionAddress); + check(params, 1); + } + callPV(programObj, location, params, __functionAddress); + } + + /** Array version of: {@link #glGetShaderSourceARB GetShaderSourceARB} */ + public static void glGetShaderSourceARB(@NativeType("GLhandleARB") int obj, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLcharARB *") ByteBuffer source) { + long __functionAddress = GL.getICD().glGetShaderSourceARB; + if (CHECKS) { + check(__functionAddress); + checkSafe(length, 1); + } + callPPV(obj, source.remaining(), length, memAddress(source), __functionAddress); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/AWTGLCanvas.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/AWTGLCanvas.java new file mode 100644 index 000000000..e97e97de0 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/AWTGLCanvas.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; +import org.lwjgl.PointerBuffer; + +import java.awt.*; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; + +public class AWTGLCanvas extends Canvas implements Drawable, ComponentListener, HierarchyListener { + + private static final long serialVersionUID = 1L; + + private ContextGL mContextGL; + private PixelFormatLWJGL mPixelFormat; + private ContextAttribs mCtxAttrs; + + public void setPixelFormat(final PixelFormatLWJGL pf) throws LWJGLException { + mPixelFormat = pf; + } + + public void setPixelFormat(final PixelFormatLWJGL pf, final ContextAttribs attribs) throws LWJGLException { + mPixelFormat = pf; + mCtxAttrs = attribs; + } + + public PixelFormatLWJGL getPixelFormat() { + return mPixelFormat; + } + + public ContextGL getContext() { + return mContextGL; + } + + public ContextGL createSharedContext() throws LWJGLException { + mContextGL = new ContextGL(getContext().getPeerInfo(), mCtxAttrs, null); + return mContextGL; + } + + public void checkGLError() { + // GL11.glGetError(); + } + + public void initContext(final float r, final float g, final float b) { + Display.setInitialBackground(r, g, b); + } + + public AWTGLCanvas() throws LWJGLException { + Display.create(); + } + + public AWTGLCanvas(PixelFormat pixel_format) throws LWJGLException { + Display.create(pixel_format); + } + + public AWTGLCanvas(GraphicsDevice device, PixelFormat pixel_format) throws LWJGLException { + this(pixel_format); + } + + public AWTGLCanvas(GraphicsDevice device, PixelFormat pixel_format, Drawable drawable) throws LWJGLException { + this(pixel_format); + } + + public AWTGLCanvas(GraphicsDevice device, PixelFormat pixel_format, Drawable drawable, ContextAttribs attribs) throws LWJGLException { + this(pixel_format); + } + + public void addNotify() { + + } + + public void removeNotify() { + + } + + public void setSwapInterval(int swap_interval) { + mContextGL.setSwapInterval(swap_interval); + } + + public void setVSyncEnabled(boolean enabled) { + mContextGL.setSwapInterval(enabled ? 1 : 0); + } + + public void swapBuffers() throws LWJGLException { + mContextGL.swapBuffers(); + } + + public boolean isCurrent() throws LWJGLException { + return mContextGL.isCurrent(); + } + + public void makeCurrent() throws LWJGLException { + mContextGL.makeCurrent(); + } + + public void releaseContext() throws LWJGLException { + mContextGL.releaseCurrent(); + } + + public final void destroy() { + try { + mContextGL.destroy(); + } catch (LWJGLException e) {throw new RuntimeException(e);} + } + + public final void setCLSharingProperties(final PointerBuffer properties) throws LWJGLException { + mContextGL.setCLSharingProperties(properties); + } + + protected void initGL() { + + } + + protected void paintGL() { + + } + + public final void paint(Graphics g) { + + } + + protected void exceptionOccurred(LWJGLException exception) { + + } + + public void update(Graphics g) { + + } + + public void componentShown(ComponentEvent e) { + + } + + public void componentHidden(ComponentEvent e) { + + } + + public void componentResized(ComponentEvent e) { + + } + + public void componentMoved(ComponentEvent e) { + + } + + public void setLocation(int x, int y) { + + } + + public void setLocation(Point p) { + + } + + public void setSize(Dimension d) { + + } + + public void setSize(int width, int height) { + + } + + public void setBounds(int x, int y, int width, int height) { + + } + + public void hierarchyChanged(HierarchyEvent e) { + + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Context.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Context.java new file mode 100644 index 000000000..01c4fded3 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Context.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; + +/** + * @author Spasi + * @since 14/5/2011 + */ +interface Context { + + boolean isCurrent() throws LWJGLException; + + void makeCurrent() throws LWJGLException; + + void releaseCurrent() throws LWJGLException; + + void releaseDrawable() throws LWJGLException; + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextAttribs.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextAttribs.java new file mode 100644 index 000000000..ba1700530 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextAttribs.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +public final class ContextAttribs { + + public ContextAttribs() { + + } + + public ContextAttribs(final int majorVersion, final int minorVersion) { + + } + + public int getMajorVersion() { + return 0; + } + + public int getMinorVersion() { + return 0; + } + + public int getLayerPlane() { + return 0; + } + + public boolean isDebug() { + return false; + } + + public boolean isForwardCompatible() { + return false; + } + + public boolean isProfileCore() { + return false; + } + + public boolean isProfileCompatibility() { + return false; + } + + public boolean isProfileES() { + return false; + } + + public ContextAttribs withLayer(final int layerPlane) { + return null; + } + + public ContextAttribs withDebug(final boolean debug) { + return null; + } + + public ContextAttribs withForwardCompatible(final boolean forwardCompatible) { + return null; + } + + public ContextAttribs withProfileCore(final boolean profileCore) { + return null; + } + + public ContextAttribs withProfileCompatibility(final boolean profileCompatibility) { + return null; + } + + public ContextAttribs withProfileES(final boolean profileES) { + return null; + } + + public ContextAttribs withLoseContextOnReset(final boolean loseContextOnReset) { + return null; + } + + public ContextAttribs withContextResetIsolation(final boolean contextResetIsolation) { + return null; + } + + public String toString() { + return null; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextCapabilities.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextCapabilities.java new file mode 100644 index 000000000..ac8906fe8 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextCapabilities.java @@ -0,0 +1,402 @@ +package org.lwjgl.opengl; + +import java.lang.reflect.Field; + +public class ContextCapabilities { + + org.lwjgl.opengl.GLCapabilities cap = org.lwjgl.opengl.GL.createCapabilities(); + + public ContextCapabilities() { + + Field[] fields = org.lwjgl.opengl.GLCapabilities.class.getFields(); + + try { + for ( Field field : fields ) { + + String name = field.getName(); + + if (name.startsWith("GL_") || name.startsWith("OpenGL")) { + + boolean value = field.getBoolean(cap); + + try { + Field f = this.getClass().getField(name); + f.setBoolean(this, value); + } catch (Exception e) { + } + } + } + } catch (Exception e) { + System.out.println(e); + } + } + + public boolean GL_AMD_blend_minmax_factor; + public boolean GL_AMD_conservative_depth; + public boolean GL_AMD_debug_output; + public boolean GL_AMD_depth_clamp_separate; + public boolean GL_AMD_draw_buffers_blend; + public boolean GL_AMD_interleaved_elements; + public boolean GL_AMD_multi_draw_indirect; + public boolean GL_AMD_name_gen_delete; + public boolean GL_AMD_performance_monitor; + public boolean GL_AMD_pinned_memory; + public boolean GL_AMD_query_buffer_object; + public boolean GL_AMD_sample_positions; + public boolean GL_AMD_seamless_cubemap_per_texture; + public boolean GL_AMD_shader_atomic_counter_ops; + public boolean GL_AMD_shader_stencil_export; + public boolean GL_AMD_shader_trinary_minmax; + public boolean GL_AMD_sparse_texture; + public boolean GL_AMD_stencil_operation_extended; + public boolean GL_AMD_texture_texture4; + public boolean GL_AMD_transform_feedback3_lines_triangles; + public boolean GL_AMD_vertex_shader_layer; + public boolean GL_AMD_vertex_shader_tessellator; + public boolean GL_AMD_vertex_shader_viewport_index; + public boolean GL_APPLE_aux_depth_stencil; + public boolean GL_APPLE_client_storage; + public boolean GL_APPLE_element_array; + public boolean GL_APPLE_fence; + public boolean GL_APPLE_float_pixels; + public boolean GL_APPLE_flush_buffer_range; + public boolean GL_APPLE_object_purgeable; + public boolean GL_APPLE_packed_pixels; + public boolean GL_APPLE_rgb_422; + public boolean GL_APPLE_row_bytes; + public boolean GL_APPLE_texture_range; + public boolean GL_APPLE_vertex_array_object; + public boolean GL_APPLE_vertex_array_range; + public boolean GL_APPLE_vertex_program_evaluators; + public boolean GL_APPLE_ycbcr_422; + public boolean GL_ARB_ES2_compatibility; + public boolean GL_ARB_ES3_compatibility; + public boolean GL_ARB_arrays_of_arrays; + public boolean GL_ARB_base_instance; + public boolean GL_ARB_bindless_texture; + public boolean GL_ARB_blend_func_extended; + public boolean GL_ARB_buffer_storage; + public boolean GL_ARB_cl_event; + public boolean GL_ARB_clear_buffer_object; + public boolean GL_ARB_clear_texture; + public boolean GL_ARB_color_buffer_float; + public boolean GL_ARB_compatibility; + public boolean GL_ARB_compressed_texture_pixel_storage; + public boolean GL_ARB_compute_shader; + public boolean GL_ARB_compute_variable_group_size; + public boolean GL_ARB_conservative_depth; + public boolean GL_ARB_copy_buffer; + public boolean GL_ARB_copy_image; + public boolean GL_ARB_debug_output; + public boolean GL_ARB_depth_buffer_float; + public boolean GL_ARB_depth_clamp; + public boolean GL_ARB_depth_texture; + public boolean GL_ARB_draw_buffers; + public boolean GL_ARB_draw_buffers_blend; + public boolean GL_ARB_draw_elements_base_vertex; + public boolean GL_ARB_draw_indirect; + public boolean GL_ARB_draw_instanced; + public boolean GL_ARB_enhanced_layouts; + public boolean GL_ARB_explicit_attrib_location; + public boolean GL_ARB_explicit_uniform_location; + public boolean GL_ARB_fragment_coord_conventions; + public boolean GL_ARB_fragment_layer_viewport; + public boolean GL_ARB_fragment_program; + public boolean GL_ARB_fragment_program_shadow; + public boolean GL_ARB_fragment_shader; + public boolean GL_ARB_framebuffer_no_attachments; + public boolean GL_ARB_framebuffer_object; + public boolean GL_ARB_framebuffer_sRGB; + public boolean GL_ARB_geometry_shader4; + public boolean GL_ARB_get_program_binary; + public boolean GL_ARB_gpu_shader5; + public boolean GL_ARB_gpu_shader_fp64; + public boolean GL_ARB_half_float_pixel; + public boolean GL_ARB_half_float_vertex; + public boolean GL_ARB_imaging; + public boolean GL_ARB_indirect_parameters; + public boolean GL_ARB_instanced_arrays; + public boolean GL_ARB_internalformat_query; + public boolean GL_ARB_internalformat_query2; + public boolean GL_ARB_invalidate_subdata; + public boolean GL_ARB_map_buffer_alignment; + public boolean GL_ARB_map_buffer_range; + public boolean GL_ARB_matrix_palette; + public boolean GL_ARB_multi_bind; + public boolean GL_ARB_multi_draw_indirect; + public boolean GL_ARB_multisample; + public boolean GL_ARB_multitexture; + public boolean GL_ARB_occlusion_query; + public boolean GL_ARB_occlusion_query2; + public boolean GL_ARB_pixel_buffer_object; + public boolean GL_ARB_point_parameters; + public boolean GL_ARB_point_sprite; + public boolean GL_ARB_program_interface_query; + public boolean GL_ARB_provoking_vertex; + public boolean GL_ARB_query_buffer_object; + public boolean GL_ARB_robust_buffer_access_behavior; + public boolean GL_ARB_robustness; + public boolean GL_ARB_robustness_isolation; + public boolean GL_ARB_sample_shading; + public boolean GL_ARB_sampler_objects; + public boolean GL_ARB_seamless_cube_map; + public boolean GL_ARB_seamless_cubemap_per_texture; + public boolean GL_ARB_separate_shader_objects; + public boolean GL_ARB_shader_atomic_counters; + public boolean GL_ARB_shader_bit_encoding; + public boolean GL_ARB_shader_draw_parameters; + public boolean GL_ARB_shader_group_vote; + public boolean GL_ARB_shader_image_load_store; + public boolean GL_ARB_shader_image_size; + public boolean GL_ARB_shader_objects; + public boolean GL_ARB_shader_precision; + public boolean GL_ARB_shader_stencil_export; + public boolean GL_ARB_shader_storage_buffer_object; + public boolean GL_ARB_shader_subroutine; + public boolean GL_ARB_shader_texture_lod; + public boolean GL_ARB_shading_language_100; + public boolean GL_ARB_shading_language_420pack; + public boolean GL_ARB_shading_language_include; + public boolean GL_ARB_shading_language_packing; + public boolean GL_ARB_shadow; + public boolean GL_ARB_shadow_ambient; + public boolean GL_ARB_sparse_texture; + public boolean GL_ARB_stencil_texturing; + public boolean GL_ARB_sync; + public boolean GL_ARB_tessellation_shader; + public boolean GL_ARB_texture_border_clamp; + public boolean GL_ARB_texture_buffer_object; + public boolean GL_ARB_texture_buffer_object_rgb32; + public boolean GL_ARB_texture_buffer_range; + public boolean GL_ARB_texture_compression; + public boolean GL_ARB_texture_compression_bptc; + public boolean GL_ARB_texture_compression_rgtc; + public boolean GL_ARB_texture_cube_map; + public boolean GL_ARB_texture_cube_map_array; + public boolean GL_ARB_texture_env_add; + public boolean GL_ARB_texture_env_combine; + public boolean GL_ARB_texture_env_crossbar; + public boolean GL_ARB_texture_env_dot3; + public boolean GL_ARB_texture_float;; + public boolean GL_ARB_texture_gather; + public boolean GL_ARB_texture_mirror_clamp_to_edge; + public boolean GL_ARB_texture_mirrored_repeat; + public boolean GL_ARB_texture_multisample; + public boolean GL_ARB_texture_non_power_of_two; + public boolean GL_ARB_texture_query_levels; + public boolean GL_ARB_texture_query_lod; + public boolean GL_ARB_texture_rectangle; + public boolean GL_ARB_texture_rg; + public boolean GL_ARB_texture_rgb10_a2ui; + public boolean GL_ARB_texture_stencil8; + public boolean GL_ARB_texture_storage; + public boolean GL_ARB_texture_storage_multisample; + public boolean GL_ARB_texture_swizzle; + public boolean GL_ARB_texture_view; + public boolean GL_ARB_timer_query; + public boolean GL_ARB_transform_feedback2; + public boolean GL_ARB_transform_feedback3; + public boolean GL_ARB_transform_feedback_instanced; + public boolean GL_ARB_transpose_matrix; + public boolean GL_ARB_uniform_buffer_object; + public boolean GL_ARB_vertex_array_bgra; + public boolean GL_ARB_vertex_array_object; + public boolean GL_ARB_vertex_attrib_64bit; + public boolean GL_ARB_vertex_attrib_binding; + public boolean GL_ARB_vertex_blend; + public boolean GL_ARB_vertex_buffer_object; + public boolean GL_ARB_vertex_program; + public boolean GL_ARB_vertex_shader; + public boolean GL_ARB_vertex_type_10f_11f_11f_rev; + public boolean GL_ARB_vertex_type_2_10_10_10_rev; + public boolean GL_ARB_viewport_array; + public boolean GL_ARB_window_pos; + public boolean GL_ATI_draw_buffers; + public boolean GL_ATI_element_array; + public boolean GL_ATI_envmap_bumpmap; + public boolean GL_ATI_fragment_shader; + public boolean GL_ATI_map_object_buffer; + public boolean GL_ATI_meminfo; + public boolean GL_ATI_pn_triangles; + public boolean GL_ATI_separate_stencil; + public boolean GL_ATI_shader_texture_lod; + public boolean GL_ATI_text_fragment_shader; + public boolean GL_ATI_texture_compression_3dc; + public boolean GL_ATI_texture_env_combine3; + public boolean GL_ATI_texture_float; + public boolean GL_ATI_texture_mirror_once; + public boolean GL_ATI_vertex_array_object; + public boolean GL_ATI_vertex_attrib_array_object; + public boolean GL_ATI_vertex_streams; + public boolean GL_EXT_abgr; + public boolean GL_EXT_bgra; + public boolean GL_EXT_bindable_uniform; + public boolean GL_EXT_blend_color; + public boolean GL_EXT_blend_equation_separate; + public boolean GL_EXT_blend_func_separate; + public boolean GL_EXT_blend_minmax; + public boolean GL_EXT_blend_subtract; + public boolean GL_EXT_Cg_shader; + public boolean GL_EXT_compiled_vertex_array; + public boolean GL_EXT_depth_bounds_test; + public boolean GL_EXT_direct_state_access; + public boolean GL_EXT_draw_buffers2; + public boolean GL_EXT_draw_instanced; + public boolean GL_EXT_draw_range_elements; + public boolean GL_EXT_fog_coord; + public boolean GL_EXT_framebuffer_blit; + public boolean GL_EXT_framebuffer_multisample; + public boolean GL_EXT_framebuffer_multisample_blit_scaled; + public boolean GL_EXT_framebuffer_object; + public boolean GL_EXT_framebuffer_sRGB; + public boolean GL_EXT_geometry_shader4; + public boolean GL_EXT_gpu_program_parameters; + public boolean GL_EXT_gpu_shader4; + public boolean GL_EXT_multi_draw_arrays; + public boolean GL_EXT_packed_depth_stencil; + public boolean GL_EXT_packed_float; + public boolean GL_EXT_packed_pixels; + public boolean GL_EXT_paletted_texture; + public boolean GL_EXT_pixel_buffer_object; + public boolean GL_EXT_point_parameters; + public boolean GL_EXT_provoking_vertex; + public boolean GL_EXT_rescale_normal; + public boolean GL_EXT_secondary_color; + public boolean GL_EXT_separate_shader_objects; + public boolean GL_EXT_separate_specular_color; + public boolean GL_EXT_shader_image_load_store; + public boolean GL_EXT_shadow_funcs; + public boolean GL_EXT_shared_texture_palette; + public boolean GL_EXT_stencil_clear_tag; + public boolean GL_EXT_stencil_two_side; + public boolean GL_EXT_stencil_wrap; + public boolean GL_EXT_texture_3d; + public boolean GL_EXT_texture_array; + public boolean GL_EXT_texture_buffer_object; + public boolean GL_EXT_texture_compression_latc; + public boolean GL_EXT_texture_compression_rgtc; + public boolean GL_EXT_texture_compression_s3tc; + public boolean GL_EXT_texture_env_combine; + public boolean GL_EXT_texture_env_dot3; + public boolean GL_EXT_texture_filter_anisotropic; + public boolean GL_EXT_texture_integer; + public boolean GL_EXT_texture_lod_bias; + public boolean GL_EXT_texture_mirror_clamp; + public boolean GL_EXT_texture_rectangle; + public boolean GL_EXT_texture_sRGB; + public boolean GL_EXT_texture_sRGB_decode; + public boolean GL_EXT_texture_shared_exponent; + public boolean GL_EXT_texture_snorm; + public boolean GL_EXT_texture_swizzle; + public boolean GL_EXT_timer_query; + public boolean GL_EXT_transform_feedback; + public boolean GL_EXT_vertex_array_bgra; + public boolean GL_EXT_vertex_attrib_64bit; + public boolean GL_EXT_vertex_shader; + public boolean GL_EXT_vertex_weighting; + public boolean OpenGL11; + public boolean OpenGL12; + public boolean OpenGL13; + public boolean OpenGL14; + public boolean OpenGL15; + public boolean OpenGL20; + public boolean OpenGL21; + public boolean OpenGL30; + public boolean OpenGL31; + public boolean OpenGL32; + public boolean OpenGL33; + public boolean OpenGL40; + public boolean OpenGL41; + public boolean OpenGL42; + public boolean OpenGL43; + public boolean OpenGL44; + public boolean GL_GREMEDY_frame_terminator; + public boolean GL_GREMEDY_string_marker; + public boolean GL_HP_occlusion_test; + public boolean GL_IBM_rasterpos_clip; + public boolean GL_INTEL_map_texture; + public boolean GL_KHR_debug; + public boolean GL_KHR_texture_compression_astc_ldr; + public boolean GL_NVX_gpu_memory_info; + public boolean GL_NV_bindless_multi_draw_indirect; + public boolean GL_NV_bindless_texture; + public boolean GL_NV_blend_equation_advanced; + public boolean GL_NV_blend_square; + public boolean GL_NV_compute_program5; + public boolean GL_NV_conditional_render; + public boolean GL_NV_copy_depth_to_color; + public boolean GL_NV_copy_image; + public boolean GL_NV_deep_texture3D; + public boolean GL_NV_depth_buffer_float; + public boolean GL_NV_depth_clamp; + public boolean GL_NV_draw_texture; + public boolean GL_NV_evaluators; + public boolean GL_NV_explicit_multisample; + public boolean GL_NV_fence; + public boolean GL_NV_float_buffer; + public boolean GL_NV_fog_distance; + public boolean GL_NV_fragment_program; + public boolean GL_NV_fragment_program2; + public boolean GL_NV_fragment_program4; + public boolean GL_NV_fragment_program_option; + public boolean GL_NV_framebuffer_multisample_coverage; + public boolean GL_NV_geometry_program4; + public boolean GL_NV_geometry_shader4; + public boolean GL_NV_gpu_program4; + public boolean GL_NV_gpu_program5; + public boolean GL_NV_gpu_program5_mem_extended; + public boolean GL_NV_gpu_shader5; + public boolean GL_NV_half_float; + public boolean GL_NV_light_max_exponent; + public boolean GL_NV_multisample_coverage; + public boolean GL_NV_multisample_filter_hint; + public boolean GL_NV_occlusion_query; + public boolean GL_NV_packed_depth_stencil; + public boolean GL_NV_parameter_buffer_object; + public boolean GL_NV_parameter_buffer_object2; + public boolean GL_NV_path_rendering; + public boolean GL_NV_pixel_data_range; + public boolean GL_NV_point_sprite; + public boolean GL_NV_present_video; + public boolean GL_NV_primitive_restart; + public boolean GL_NV_register_combiners; + public boolean GL_NV_register_combiners2; + public boolean GL_NV_shader_atomic_counters; + public boolean GL_NV_shader_atomic_float; + public boolean GL_NV_shader_buffer_load; + public boolean GL_NV_shader_buffer_store; + public boolean GL_NV_shader_storage_buffer_object; + public boolean GL_NV_tessellation_program5; + public boolean GL_NV_texgen_reflection; + public boolean GL_NV_texture_barrier; + public boolean GL_NV_texture_compression_vtc; + public boolean GL_NV_texture_env_combine4; + public boolean GL_NV_texture_expand_normal; + public boolean GL_NV_texture_multisample; + public boolean GL_NV_texture_rectangle; + public boolean GL_NV_texture_shader; + public boolean GL_NV_texture_shader2; + public boolean GL_NV_texture_shader3; + public boolean GL_NV_transform_feedback; + public boolean GL_NV_transform_feedback2; + public boolean GL_NV_vertex_array_range; + public boolean GL_NV_vertex_array_range2; + public boolean GL_NV_vertex_attrib_integer_64bit; + public boolean GL_NV_vertex_buffer_unified_memory; + public boolean GL_NV_vertex_program; + public boolean GL_NV_vertex_program1_1; + public boolean GL_NV_vertex_program2; + public boolean GL_NV_vertex_program2_option; + public boolean GL_NV_vertex_program3; + public boolean GL_NV_vertex_program4; + public boolean GL_NV_video_capture; + public boolean GL_SGIS_generate_mipmap; + public boolean GL_SGIS_texture_lod; + public boolean GL_SUN_slice_accum; + + public static void main(String[] arg) { + System.out.println("START!"); + new ContextCapabilities(); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextGL.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextGL.java new file mode 100644 index 000000000..9df0f9608 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/ContextGL.java @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; +import org.lwjgl.LWJGLUtil; +import org.lwjgl.PointerBuffer; +import org.lwjgl.Sys; + +import org.lwjgl.glfw.GLFW; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +import static org.lwjgl.opengl.GL11.*; + +/** + *

+ * Context encapsulates an OpenGL context. + *

+ *

+ * This class is thread-safe. + * + * @author elias_naur + * @version $Revision$ + * $Id$ + */ +final class ContextGL implements Context { + + /** The platform specific implementation of context methods */ + // private static final ContextImplementation implementation; + + /** The current Context */ + private static final ThreadLocal current_context_local = new ThreadLocal(); + + /** Handle to the native GL rendering context */ + private final ByteBuffer handle; + private final PeerInfo peer_info; + + private final ContextAttribs contextAttribs; + private final boolean forwardCompatible; + + /** Whether the context has been destroyed */ + private boolean destroyed; + + private boolean destroy_requested; + + /** The thread that has this context current, or null. */ + private Thread thread; + + private boolean isCurrent; + + static { + Sys.initialize(); + // implementation = createImplementation(); + } + + PeerInfo getPeerInfo() { + return peer_info; + } + + ContextAttribs getContextAttribs() { + return contextAttribs; + } + + static ContextGL getCurrentContext() { + return current_context_local.get(); + } + + /** Create a context with the specified peer info and shared context */ + ContextGL(PeerInfo peer_info, ContextAttribs attribs, ContextGL shared_context) throws LWJGLException { + ContextGL context_lock = shared_context != null ? shared_context : this; + // If shared_context is not null, synchronize on it to make sure it is not deleted + // while this context is created. Otherwise, simply synchronize on ourself to avoid NPE + synchronized ( context_lock ) { + if ( shared_context != null && shared_context.destroyed ) + throw new IllegalArgumentException("Shared context is destroyed"); + // GLContext.loadOpenGLLibrary(); + // try { + this.peer_info = peer_info; + this.contextAttribs = attribs; +/* + IntBuffer attribList; + if ( attribs != null ) { + attribList = attribs.getAttribList(); + forwardCompatible = attribs.isForwardCompatible(); + } else { + attribList = null; + forwardCompatible = false; + } +*/ + + forwardCompatible = false; + + this.handle = null; + // implementation.create(peer_info, attribList, shared_context != null ? shared_context.handle : null); + /* } catch (LWJGLException e) { + // GLContext.unloadOpenGLLibrary(); + throw e; + } */ + } + } + + /** Release the current context (if any). After this call, no context is current. */ + public void releaseCurrent() throws LWJGLException { + ContextGL current_context = getCurrentContext(); + if ( current_context != null ) { + GLFW.glfwMakeContextCurrent(0l); + isCurrent = false; + current_context_local.set(null); + synchronized ( current_context ) { + current_context.thread = null; + current_context.checkDestroy(); + } + } + } + + /** + * Release the context from its drawable. This is necessary on some platforms, + * like Mac OS X, where binding the context to a drawable and binding the context + * for rendering are two distinct actions and where calling releaseDrawable + * on every releaseCurrentContext results in artifacts. + */ + public synchronized void releaseDrawable() throws LWJGLException { + if ( destroyed ) + throw new IllegalStateException("Context is destroyed"); + // implementation.releaseDrawable(getHandle()); + } + + /** Update the context. Should be called whenever it's drawable is moved or resized */ + public synchronized void update() { + if ( destroyed ) + throw new IllegalStateException("Context is destroyed"); + // implementation.update(getHandle()); + } + + /** Swap the buffers on the current context. Only valid for double-buffered contexts */ + public static void swapBuffers() throws LWJGLException { + Display.swapBuffers(); + } + + private boolean canAccess() { + return thread == null || Thread.currentThread() == thread; + } + + private void checkAccess() { + if ( !canAccess() ) + throw new IllegalStateException("From thread " + Thread.currentThread() + ": " + thread + " already has the context current"); + } + + /** Make the context current */ + public synchronized void makeCurrent() throws LWJGLException { + checkAccess(); + if ( destroyed ) + throw new IllegalStateException("Context is destroyed"); + thread = Thread.currentThread(); + current_context_local.set(this); + GLFW.glfwMakeContextCurrent(Display.Window.handle); + isCurrent = true; + } + + ByteBuffer getHandle() { + return handle; + } + + /** Query whether the context is current */ + public synchronized boolean isCurrent() throws LWJGLException { + if ( destroyed ) + throw new IllegalStateException("Context is destroyed"); + return isCurrent; + } + + private void checkDestroy() { + if ( !destroyed && destroy_requested ) { + try { + releaseDrawable(); + // implementation.destroy(peer_info, handle); + // CallbackUtil.unregisterCallbacks(this); + destroyed = true; + thread = null; + // GLContext.unloadOpenGLLibrary(); + + Display.destroy(); + } catch (LWJGLException e) { + LWJGLUtil.log("Exception occurred while destroying context: " + e); + } + } + } + + /** + * Set the buffer swap interval. This call is a best-attempt at changing + * the monitor swap interval, which is the minimum periodicity of color buffer swaps, + * measured in video frame periods, and is not guaranteed to be successful. + *

+ * A video frame period is the time required to display a full frame of video data. + */ + public static void setSwapInterval(int value) { + GLFW.glfwSwapInterval(value); + } + + /** + * Destroy the context. This method behaves the same as destroy() with the extra + * requirement that the context must be either current to the current thread or not + * current at all. + */ + public synchronized void forceDestroy() throws LWJGLException { + checkAccess(); + destroy(); + } + + /** + * Request destruction of the Context. If the context is current, no context will be current after this call. + * The context is destroyed when no thread has it current. + */ + public synchronized void destroy() throws LWJGLException { + if ( destroyed ) + return; + destroy_requested = true; + boolean was_current = isCurrent(); + int error = GL_NO_ERROR; + if ( was_current ) { + if ( GLContext.getCapabilities() != null && GLContext.getCapabilities().OpenGL11 ) + error = glGetError(); + releaseCurrent(); + } + checkDestroy(); + if ( was_current && error != GL_NO_ERROR ) + throw new OpenGLException(error); + } + + public synchronized void setCLSharingProperties(final PointerBuffer properties) throws LWJGLException { + final ByteBuffer peer_handle = peer_info.lockAndGetHandle(); + try { + /* + switch ( LWJGLUtil.getPlatform() ) { + case LWJGLUtil.PLATFORM_WINDOWS: + final WindowsContextImplementation implWindows = (WindowsContextImplementation)implementation; + properties.put(KHRGLSharing.CL_GL_CONTEXT_KHR).put(implWindows.getHGLRC(handle)); + properties.put(KHRGLSharing.CL_WGL_HDC_KHR).put(implWindows.getHDC(peer_handle)); + break; + case LWJGLUtil.PLATFORM_LINUX: + final LinuxContextImplementation implLinux = (LinuxContextImplementation)implementation; + properties.put(KHRGLSharing.CL_GL_CONTEXT_KHR).put(implLinux.getGLXContext(handle)); + properties.put(KHRGLSharing.CL_GLX_DISPLAY_KHR).put(implLinux.getDisplay(peer_handle)); + break; + case LWJGLUtil.PLATFORM_MACOSX: + if (LWJGLUtil.isMacOSXEqualsOrBetterThan(10, 6)) { // only supported on OS X 10.6+ + // http://oscarbg.blogspot.com/2009/10/about-opencl-opengl-interop.html + final MacOSXContextImplementation implMacOSX = (MacOSXContextImplementation)implementation; + final long CGLShareGroup = implMacOSX.getCGLShareGroup(handle); + properties.put(APPLEGLSharing.CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE).put(CGLShareGroup); + break; + } + default: + throw new UnsupportedOperationException("CL/GL context sharing is not supported on this platform."); + } + */ + } finally { + // peer_info.unlock(); + } + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Display.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Display.java new file mode 100644 index 000000000..06177f461 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Display.java @@ -0,0 +1,1124 @@ +package org.lwjgl.opengl; + +import static org.lwjgl.opengl.GL11.GL_FALSE; +import static org.lwjgl.opengl.GL11.GL_TRUE; +import static org.lwjgl.system.MemoryUtil.NULL; +import static org.lwjgl.glfw.GLFW.*; + +import java.awt.Canvas; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.glfw.*; +import org.lwjgl.LWJGLUtil; +import org.lwjgl.opengl.GL11; +import org.lwjgl.system.MemoryUtil; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; +import org.lwjgl.input.Cursor; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; + +public class Display { + + private static String windowTitle = "Game"; + + private static org.lwjgl.opengl.GLContext context; + + private static DisplayImplementation display_impl; + + private static boolean displayCreated = false; + private static boolean displayFocused = true; + private static boolean displayVisible = true; + private static boolean displayDirty = false; + private static boolean displayResizable = false; + + private static DisplayMode mode, desktopDisplayMode; + + private static int latestEventKey = 0; + + private static int displayX = -1; + private static int displayY = -1; + + private static boolean displayResized = false; + private static int displayWidth = 0; + private static int displayHeight = 0; + private static int displayFramebufferWidth = 0; + private static int displayFramebufferHeight = 0; + + private static boolean latestResized = false; + private static int latestWidth = 0; + private static int latestHeight = 0; + + private static boolean vsyncEnabled = false; + private static boolean displayFullscreen = true; + private static float fps; + + private static boolean window_created; + + /** The Drawable instance that tracks the current Display context */ + private static DrawableLWJGL drawable; + + private static Canvas parent; + + private static GLFWImage.Buffer icons; + + private static int swap_interval; + + static { + Sys.initialize(); // init using dummy sys method + + long monitor = glfwGetPrimaryMonitor(); + GLFWVidMode vidmode = glfwGetVideoMode(monitor); + + int monitorWidth = displayWidth = displayFramebufferWidth = vidmode.width(); + int monitorHeight = displayHeight = displayFramebufferHeight = vidmode.height(); + int monitorBitPerPixel = vidmode.redBits() + vidmode.greenBits() + vidmode.blueBits(); + int monitorRefreshRate = vidmode.refreshRate(); + + mode = desktopDisplayMode = new DisplayMode(monitorWidth, monitorHeight, monitorBitPerPixel, monitorRefreshRate); + LWJGLUtil.log("Initial mode: " + desktopDisplayMode); + + // additional code workaround not called yet! + LWJGLUtil.log("Calling Display.create()"); + try { + create(); + } catch (LWJGLException e) {throw new RuntimeException(e);} + } + + public static void setSwapInterval(int value) { + synchronized ( GlobalLock.lock ) { + swap_interval = value; + if ( isCreated() ) { + drawable.setSwapInterval(swap_interval); + + } + } + } + + private static void makeCurrentAndSetSwapInterval() throws LWJGLException { + makeCurrent(); + try { + drawable.checkGLError(); + } catch (OpenGLException e) { + LWJGLUtil.log("OpenGL error during context creation: " + e.getMessage()); + } + setSwapInterval(swap_interval); + } + + private static void initContext() { + drawable.initContext(0, 0, 0); + update(); + } + + private static void initControls() { + // Automatically create mouse, keyboard and controller + if ( true ) { + if ( !Mouse.isCreated() ) { + try { + Mouse.create(); + } catch (LWJGLException e) { + if ( LWJGLUtil.DEBUG ) { + e.printStackTrace(System.err); + } else { + LWJGLUtil.log("Failed to create Mouse: " + e); + } + } + } + if ( !Keyboard.isCreated() ) { + try { + Keyboard.create(); + } catch (LWJGLException e) { + if ( LWJGLUtil.DEBUG ) { + e.printStackTrace(System.err); + } else { + LWJGLUtil.log("Failed to create Keyboard: " + e); + } + } + } + } + } + + private static void releaseDrawable() { + try { + Context context = drawable.getContext(); + if ( context != null && context.isCurrent() ) { + context.releaseCurrent(); + context.releaseDrawable(); + } + } catch (LWJGLException e) { + LWJGLUtil.log("Exception occurred while trying to release context: " + e); + } + } + + private static void destroyWindow() { + if ( !window_created ) { + return; + } + releaseDrawable(); + + // Automatically destroy keyboard & mouse + if ( Mouse.isCreated() ) { + Mouse.destroy(); + } + if ( Keyboard.isCreated() ) { + Keyboard.destroy(); + } + display_impl.destroyWindow(); + window_created = false; + } + + private static void reset() { + display_impl.resetDisplayMode(); + } + + private static void createWindow() throws LWJGLException { + if ( window_created ) { + return; + } + DisplayMode mode = Display.getDisplayMode(); + display_impl.createWindow(drawable, mode, null, 0, 0 /* getWindowX(), getWindowY() */); + window_created = true; + + displayWidth = mode.getWidth(); + displayHeight = mode.getHeight(); + + // setTitle(title); + initControls(); + + // set cached window icon if exists + /* + if ( cached_icons != null ) { + setIcon(cached_icons); + } else { + + } + */ + + setIcon(new ByteBuffer[] { LWJGLUtil.LWJGLIcon32x32, LWJGLUtil.LWJGLIcon16x16 }); + } + + public static void create(PixelFormat pixel_format, Drawable shared_drawable) throws LWJGLException { + // System.out.println("TODO: Implement Display.create(PixelFormat, + // Drawable)"); // TODO + create(pixel_format); + + final DrawableGL drawable = new DrawableGL() { + public void destroy() { + synchronized ( GlobalLock.lock ) { + if ( !isCreated() ) + return; + + releaseDrawable(); + super.destroy(); + destroyWindow(); + // x = y = -1; + // cached_icons = null; + reset(); + } + } + }; + Display.drawable = drawable; + + try { + drawable.setPixelFormat(pixel_format, null); + try { + createWindow(); + try { + drawable.context = new ContextGL(drawable.peer_info, null /* attribs */, shared_drawable != null ? ((DrawableGL)shared_drawable).getContext() : null); + try { + makeCurrentAndSetSwapInterval(); + initContext(); + } catch (LWJGLException e) { + //drawable.destroy(); + throw e; + } + } catch (LWJGLException e) { + destroyWindow(); + throw e; + } + } catch (LWJGLException e) { + drawable.destroy(); + throw e; + } + } catch (LWJGLException e) { + display_impl.resetDisplayMode(); + throw e; + } + } + + public static void create(PixelFormat pixel_format, ContextAttribs attribs) throws LWJGLException { + // System.out.println("TODO: Implement Display.create(PixelFormat, + // ContextAttribs)"); // TODO + create(pixel_format); + } + + public static void create(PixelFormat format) throws LWJGLException { + glfwWindowHint(GLFW_ACCUM_ALPHA_BITS, format.getAccumulationBitsPerPixel()); + glfwWindowHint(GLFW_ALPHA_BITS, format.getAlphaBits()); + glfwWindowHint(GLFW_AUX_BUFFERS, format.getAuxBuffers()); + glfwWindowHint(GLFW_DEPTH_BITS, format.getDepthBits()); + glfwWindowHint(GLFW_SAMPLES, format.getSamples()); + glfwWindowHint(GLFW_STENCIL_BITS, format.getStencilBits()); + create(); + } + + private static boolean isCreated = false; + public static void create() throws LWJGLException { + if (isCreated) return; + else isCreated = true; + + if (Window.handle != MemoryUtil.NULL) + glfwDestroyWindow(Window.handle); + + long monitor = glfwGetPrimaryMonitor(); + GLFWVidMode vidmode = glfwGetVideoMode(monitor); + + int monitorWidth = vidmode.width(); + int monitorHeight = vidmode.height(); + int monitorBitPerPixel = vidmode.redBits() + vidmode.greenBits() + vidmode.blueBits(); + int monitorRefreshRate = vidmode.refreshRate(); + + desktopDisplayMode = new DisplayMode(monitorWidth, monitorHeight, monitorBitPerPixel, monitorRefreshRate); + + glfwDefaultWindowHints(); + glfwWindowHint(GLFW_VISIBLE, GL_FALSE); + glfwWindowHint(GLFW_RESIZABLE, displayResizable ? GL_TRUE : GL_FALSE); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); + + Window.handle = glfwCreateWindow(mode.getWidth(), mode.getHeight(), windowTitle, NULL, NULL); + if (Window.handle == NULL) + throw new LWJGLException("Failed to create Display window"); + + Window.keyCallback = new GLFWKeyCallback() { + @Override + public void invoke(long window, int key, int scancode, int action, int mods) { + latestEventKey = key; + + // if (action == GLFW_RELEASE || action == GLFW.GLFW_PRESS) { + // Keyboard.addKeyEvent(key, action == GLFW.GLFW_PRESS ? true : + // false); + // } + + Keyboard.addKeyEvent(key, action); + } + }; + + Window.charCallback = new GLFWCharCallback() { + @Override + public void invoke(long window, int codepoint) { + Keyboard.addCharEvent(latestEventKey, (char) codepoint); + } + }; + + Window.cursorEnterCallback = new GLFWCursorEnterCallback() { + @Override + public void invoke(long window, boolean entered) { + Mouse.setMouseInsideWindow(entered == true); + } + }; + + Window.cursorPosCallback = new GLFWCursorPosCallback() { + @Override + public void invoke(long window, double xpos, double ypos) { + Mouse.addMoveEvent(xpos, ypos); + } + }; + + Window.mouseButtonCallback = new GLFWMouseButtonCallback() { + @Override + public void invoke(long window, int button, int action, int mods) { + Mouse.addButtonEvent(button, action == GLFW.GLFW_PRESS ? true : false); + } + }; + + Window.windowFocusCallback = new GLFWWindowFocusCallback() { + @Override + public void invoke(long window, boolean focused) { + displayFocused = focused == true; + } + }; + + Window.windowIconifyCallback = new GLFWWindowIconifyCallback() { + @Override + public void invoke(long window, boolean iconified) { + displayVisible = iconified == false; + } + }; + + Window.windowSizeCallback = new GLFWWindowSizeCallback() { + @Override + public void invoke(long window, int width, int height) { + latestResized = true; + latestWidth = width; + latestHeight = height; + } + }; + + Window.windowPosCallback = new GLFWWindowPosCallback() { + @Override + public void invoke(long window, int xpos, int ypos) { + displayX = xpos; + displayY = ypos; + } + }; + + Window.windowRefreshCallback = new GLFWWindowRefreshCallback() { + @Override + public void invoke(long window) { + displayDirty = true; + } + }; + + Window.framebufferSizeCallback = new GLFWFramebufferSizeCallback() { + @Override + public void invoke(long window, int width, int height) { + displayFramebufferWidth = width; + displayFramebufferHeight = height; + } + }; + + Window.scrollCallback = new GLFWScrollCallback() { + @Override + public void invoke(long window, double xoffset, double yoffset) { + Mouse.addWheelEvent((int) (yoffset * 120)); + } + }; + + Window.setCallbacks(); + + displayWidth = mode.getWidth(); + displayHeight = mode.getHeight(); + + IntBuffer fbw = BufferUtils.createIntBuffer(1); + IntBuffer fbh = BufferUtils.createIntBuffer(1); + glfwGetFramebufferSize(Window.handle, fbw, fbh); + displayFramebufferWidth = fbw.get(0); + displayFramebufferHeight = fbh.get(0); + + glfwSetWindowPos(Window.handle, (monitorWidth - mode.getWidth()) / 2, (monitorHeight - mode.getHeight()) / 2); + + if (displayX == -1) { + displayX = (monitorWidth - mode.getWidth()) / 2; + } + + if (displayY == -1) { + displayY = (monitorHeight - mode.getHeight()) / 2; + } + + glfwMakeContextCurrent(Window.handle); + context = org.lwjgl.opengl.GLContext.createFromCurrent(); + + glfwSwapInterval(0); + glfwShowWindow(Window.handle); + + Mouse.create(); + Keyboard.create(); + + // glfwSetWindowIcon(Window.handle, icons); + display_impl = new DisplayImplementation() { + + @Override + public void setNativeCursor(Object handle) throws LWJGLException { + try { + Mouse.setNativeCursor((Cursor) handle); + } catch (ClassCastException e) { + throw new LWJGLException("Handle is not an instance of cursor"); + } + } + + @Override + public void setCursorPosition(int x, int y) { + Mouse.setCursorPosition(x, y); + } + + @Override + public void readMouse(ByteBuffer buffer) { + + } + + @Override + public void readKeyboard(ByteBuffer buffer) { + // TODO Auto-generated method stub + + } + + @Override + public void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons) { + + } + + @Override + public void pollKeyboard(ByteBuffer keyDownBuffer) { + // TODO Auto-generated method stub + + } + + @Override + public boolean isInsideWindow() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasWheel() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void grabMouse(boolean grab) { + Mouse.setGrabbed(grab); + } + + @Override + public int getNativeCursorCapabilities() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getMinCursorSize() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getMaxCursorSize() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getButtonCount() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void destroyMouse() { + // TODO Auto-generated method stub + + } + + @Override + public void destroyKeyboard() { + // TODO Auto-generated method stub + + } + + @Override + public void destroyCursor(Object cursor_handle) { + // TODO Auto-generated method stub + + } + + @Override + public void createMouse() throws LWJGLException { + // TODO Auto-generated method stub + + } + + @Override + public void createKeyboard() throws LWJGLException { + // TODO Auto-generated method stub + + } + + @Override + public Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, + IntBuffer images, IntBuffer delays) throws LWJGLException { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean wasResized() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void update() { + Display.update(); + } + + @Override + public void switchDisplayMode(DisplayMode mode) throws LWJGLException { + Display.setDisplayMode(mode); + } + + @Override + public void setTitle(String title) { + windowTitle = title; + } + + @Override + public void setResizable(boolean resizable) { + Display.setResizable(resizable); + } + + @Override + public void setPbufferAttrib(PeerInfo handle, int attrib, int value) { + // TODO Auto-generated method stub + + } + + @Override + public int setIcon(ByteBuffer[] icons) { + // TODO Auto-generated method stub + Display.setIcon(icons); + return 0; + } + + @Override + public void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException { + // TODO Auto-generated method stub + + } + + @Override + public void reshape(int x, int y, int width, int height) { + // TODO Auto-generated method stub + + } + + @Override + public void resetDisplayMode() { + try { + Display.setDisplayMode(desktopDisplayMode); + } catch (LWJGLException e) { + } + } + + @Override + public void releaseTexImageFromPbuffer(PeerInfo handle, int buffer) { + // TODO Auto-generated method stub + + } + + @Override + public boolean isVisible() { + // TODO Auto-generated method stub + return Display.displayVisible; + } + + @Override + public boolean isDirty() { + // TODO Auto-generated method stub + return Display.displayDirty; + } + + @Override + public boolean isCloseRequested() { + // TODO Auto-generated method stub + return GLFW.glfwWindowShouldClose(Window.handle); + } + + @Override + public boolean isBufferLost(PeerInfo handle) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isActive() { + // TODO Auto-generated method stub + return Display.displayFocused; + } + + @Override + public DisplayMode init() throws LWJGLException { + // TODO Auto-generated method stub + return desktopDisplayMode; + } + + @Override + public int getY() { + // TODO Auto-generated method stub + return Display.displayY; + } + + @Override + public int getX() { + // TODO Auto-generated method stub + return Display.displayX; + } + + @Override + public int getWidth() { + // TODO Auto-generated method stub + return Display.latestWidth; + } + + @Override + public String getVersion() { + // TODO Auto-generated method stub + return Sys.getVersion(); + } + + @Override + public float getPixelScaleFactor() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getPbufferCapabilities() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getHeight() { + // TODO Auto-generated method stub + return Display.latestHeight; + } + + @Override + public int getGammaRampLength() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public DisplayMode[] getAvailableDisplayModes() throws LWJGLException { + // TODO Auto-generated method stub + return Display.getAvailableDisplayModes(); + } + + @Override + public String getAdapter() { + // TODO Auto-generated method stub + return Display.getAdapter(); + } + + @Override + public void destroyWindow() { + Display.destroy(); + } + + @Override + public void createWindow(DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) + throws LWJGLException { + // TODO Auto-generated method stub + + } + + @Override + public PeerInfo createPeerInfo(PixelFormat pixel_format, ContextAttribs attribs) throws LWJGLException { + // TODO Auto-generated method stub + return null; + } + + @Override + public PeerInfo createPbuffer(int width, int height, PixelFormat pixel_format, ContextAttribs attribs, + IntBuffer pixelFormatCaps, IntBuffer pBufferAttribs) throws LWJGLException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void bindTexImageToPbuffer(PeerInfo handle, int buffer) { + // TODO Auto-generated method stub + + } + }; + + displayCreated = true; + + } + + public static boolean isCreated() { + return displayCreated; + } + + public static boolean isActive() { + return displayFocused; + } + + public static boolean isVisible() { + return displayVisible; + } + + public static org.lwjgl.opengl.GLContext getContext() { + return context; + } + + public static void setLocation(int new_x, int new_y) { + if (Window.handle == 0L) { + Display.displayX = new_x; + Display.displayY = new_y; + } else { + GLFW.glfwSetWindowPos(Window.handle, new_x, new_y); + } + } + + public static void setVSyncEnabled(boolean sync) { + vsyncEnabled = sync; + } + + public static long getWindow() { + return Window.handle; + } + + public static void update() { + update(true); + } + + public static void update(boolean processMessages) { + try { + swapBuffers(); + displayDirty = false; + + } catch (LWJGLException e) { + throw new RuntimeException(e); + } + + if (processMessages) + processMessages(); + } + + public static void processMessages() { + glfwPollEvents(); + Keyboard.poll(); + Mouse.poll(); + + if (latestResized) { + latestResized = false; + displayResized = true; + displayWidth = latestWidth; + displayHeight = latestHeight; + } else { + displayResized = false; + } + } + + /** Return the last parent set with setParent(). */ + public static Canvas getParent() { + return parent; + } + + /** + * Set the parent of the Display. If parent is null, the Display will appear as a top level window. + * If parent is not null, the Display is made a child of the parent. A parent's isDisplayable() must be true when + * setParent() is called and remain true until setParent() is called again with + * null or a different parent. This generally means that the parent component must remain added to it's parent container.

+ * It is not advisable to call this method from an AWT thread, since the context will be made current on the thread + * and it is difficult to predict which AWT thread will process any given AWT event.

+ * While the Display is in fullscreen mode, the current parent will be ignored. Additionally, when a non null parent is specified, + * the Dispaly will inherit the size of the parent, disregarding the currently set display mode.

+ */ + public static void setParent(Canvas parent) throws LWJGLException { + if ( Display.parent != parent ) { + Display.parent = parent; + /* + if ( !isCreated() ) + return; + destroyWindow(); + try { + if ( isFullscreen() ) { + switchDisplayMode(); + } else { + display_impl.resetDisplayMode(); + } + createWindow(); + makeCurrentAndSetSwapInterval(); + } catch (LWJGLException e) { + drawable.destroy(); + display_impl.resetDisplayMode(); + throw e; + } + */ + } + } + + public static void swapBuffers() throws LWJGLException { + glfwSwapBuffers(Window.handle); + } + + public static void destroy() { + Window.releaseCallbacks(); + glfwDestroyWindow(Window.handle); + + displayCreated = false; + } + + public static void setDisplayMode(DisplayMode dm) throws LWJGLException { + mode = dm; + newCurrentWindow(GLFW.glfwCreateWindow(dm.getWidth(), dm.getHeight(), windowTitle, 0, 0)); + } + + public static DisplayMode getDisplayMode() { + return mode; + } + + public static DisplayMode[] getAvailableDisplayModes() throws LWJGLException { + GLFWVidMode.Buffer modes = GLFW.glfwGetVideoModes(GLFW.glfwGetPrimaryMonitor()); + + DisplayMode[] displayModes = new DisplayMode[modes.capacity()]; + + for (int i = 0; i < modes.capacity(); i++) { + modes.position(i); + + int w = modes.width(); + int h = modes.height(); + int b = modes.redBits() + modes.greenBits() + modes.blueBits(); + int r = modes.refreshRate(); + + displayModes[i] = new DisplayMode(w, h, b, r); + } + + return displayModes; + } + + public static DisplayMode getDesktopDisplayMode() { + long mon = GLFW.glfwGetPrimaryMonitor(); + GLFWVidMode mode = GLFW.glfwGetVideoMode(mon); + return new DisplayMode(mode.width(), mode.height(), mode.redBits() + mode.greenBits() + mode.blueBits(), + mode.refreshRate()); + } + + public static boolean wasResized() { + return displayResized; + } + + public static int getX() { + return displayX; + } + + public static int getY() { + return displayY; + } + + public static int getWidth() { + return displayWidth; + } + + public static int getHeight() { + return displayHeight; + } + + public static int getFramebufferWidth() { + return displayFramebufferWidth; + } + + public static int getFramebufferHeight() { + return displayFramebufferHeight; + } + + public static void setTitle(String title) { + windowTitle = title; + } + + public static boolean isCloseRequested() { + return glfwWindowShouldClose(Window.handle) == true; + } + + public static boolean isDirty() { + return displayDirty; + } + + public static void setInitialBackground(float red, float green, float blue) { + // System.out.println("TODO: Implement Display.setInitialBackground(float, float, float)"); + + if (Window.handle != MemoryUtil.NULL) { + GL11.glClearColor(red, green, blue, 1f); + GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); + } + } + + public static int setIcon(java.nio.ByteBuffer[] icons) { + // TODO + try { + if (Window.handle == MemoryUtil.NULL) { + Display.icons = new GLFWImage.Buffer(icons[1]); + } else { + glfwSetWindowIcon(Window.handle, new GLFWImage.Buffer(icons[0])); + } + } catch (NullPointerException e) { + LWJGLUtil.log("Couldn't set icon"); + e.printStackTrace(); + } + return 0; + } + + public static void setResizable(boolean resizable) { + displayResizable = resizable; + if (displayResizable ^ resizable) { + if (Window.handle != 0) { + IntBuffer width = BufferUtils.createIntBuffer(1); + IntBuffer height = BufferUtils.createIntBuffer(1); + GLFW.glfwGetWindowSize(Window.handle, width, height); + width.rewind(); + height.rewind(); + + GLFW.glfwDefaultWindowHints(); + glfwWindowHint(GLFW_VISIBLE, displayVisible ? GL_TRUE : GL_FALSE); + glfwWindowHint(GLFW_RESIZABLE, displayResizable ? GL_TRUE : GL_FALSE); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); + + newCurrentWindow(GLFW.glfwCreateWindow(width.get(), height.get(), windowTitle, + GLFW.glfwGetWindowMonitor(Window.handle), NULL)); + } + } + displayResizable = resizable; + } + + public static boolean isResizable() { + return displayResizable; + } + + public static void setDisplayModeAndFullscreen(DisplayMode mode) throws LWJGLException { + Display.mode = mode; + newCurrentWindow(glfwCreateWindow(mode.getWidth(), mode.getHeight(), windowTitle, + mode.isFullscreenCapable() ? glfwGetPrimaryMonitor() : NULL, NULL)); + } + + public static void setFullscreen(boolean fullscreen) throws LWJGLException { + System.out.println("LWJGLX: switch fullscreen to " + fullscreen); + if (isFullscreen() ^ fullscreen) { + if (fullscreen && (!mode.isFullscreenCapable())) + throw new LWJGLException("Display mode is not fullscreen capable"); + if (Window.handle != 0) { + IntBuffer width = BufferUtils.createIntBuffer(1); + IntBuffer height = BufferUtils.createIntBuffer(1); + glfwGetWindowSize(Window.handle, width, height); + width.rewind(); + height.rewind(); + + glfwDefaultWindowHints(); + glfwWindowHint(GLFW_VISIBLE, displayVisible ? GL_TRUE : GL_FALSE); + glfwWindowHint(GLFW_RESIZABLE, displayResizable ? GL_TRUE : GL_FALSE); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); + + if (fullscreen) + newCurrentWindow(glfwCreateWindow(width.get(), height.get(), windowTitle, + glfwGetPrimaryMonitor(), NULL)); + else + newCurrentWindow(glfwCreateWindow(width.get(), height.get(), windowTitle, NULL, NULL)); + } + } + displayFullscreen = fullscreen; + } + + public static boolean isFullscreen() { + return displayFullscreen; + } + + public static void releaseContext() throws LWJGLException { + glfwMakeContextCurrent(0); + } + + public static boolean isCurrent() throws LWJGLException { + return glfwGetCurrentContext() == Window.handle; + } + + public static void makeCurrent() throws LWJGLException { + if (!isCurrent()) { + // -glfwMakeContextCurrent(Window.handle); + } + } + + public static java.lang.String getAdapter() { + // TODO + return "GeNotSupportedAdapter"; + } + + public static java.lang.String getVersion() { + // TODO + return "1.0 NOT SUPPORTED"; + } + + /** + * An accurate sync method that will attempt to run at a constant frame + * rate. It should be called once every frame. + * + * @param fps + * - the desired frame rate, in frames per second + */ + public static void sync(int fps) { + if (vsyncEnabled) + Sync.sync(fps); + } + + public static Drawable getDrawable() { + return drawable; + } + + static DisplayImplementation getImplementation() { + return display_impl; + } + + private static void newCurrentWindow(long newWindow) { + if (Window.handle != MemoryUtil.NULL) + glfwDestroyWindow(Window.handle); + Window.handle = newWindow; + try { + Mouse.setNativeCursor(Mouse.getCurrentCursor()); + } catch (LWJGLException e) { + System.err.println("Failed to set new window cursor!"); + e.printStackTrace(); + } + GLFW.glfwSetWindowTitle(newWindow, windowTitle); + Window.setCallbacks(); + + // glfwMakeContextCurrent(Window.handle); + context = org.lwjgl.opengl.GLContext.createFromCurrent(); + + glfwSwapInterval(0); + glfwShowWindow(Window.handle); + } + + static class Window { + static long handle; + + static GLFWKeyCallback keyCallback; + static GLFWCharCallback charCallback; + static GLFWCursorEnterCallback cursorEnterCallback; + static GLFWCursorPosCallback cursorPosCallback; + static GLFWMouseButtonCallback mouseButtonCallback; + static GLFWWindowFocusCallback windowFocusCallback; + static GLFWWindowIconifyCallback windowIconifyCallback; + static GLFWWindowSizeCallback windowSizeCallback; + static GLFWWindowPosCallback windowPosCallback; + static GLFWWindowRefreshCallback windowRefreshCallback; + static GLFWFramebufferSizeCallback framebufferSizeCallback; + static GLFWScrollCallback scrollCallback; + + public static void setCallbacks() { + glfwSetKeyCallback(handle, keyCallback); + glfwSetCharCallback(handle, charCallback); + glfwSetCursorEnterCallback(handle, cursorEnterCallback); + glfwSetCursorPosCallback(handle, cursorPosCallback); + glfwSetMouseButtonCallback(handle, mouseButtonCallback); + glfwSetWindowFocusCallback(handle, windowFocusCallback); + glfwSetWindowIconifyCallback(handle, windowIconifyCallback); + glfwSetWindowSizeCallback(handle, windowSizeCallback); + glfwSetWindowPosCallback(handle, windowPosCallback); + glfwSetWindowRefreshCallback(handle, windowRefreshCallback); + glfwSetFramebufferSizeCallback(handle, framebufferSizeCallback); + glfwSetScrollCallback(handle, scrollCallback); + } + + public static void releaseCallbacks() { + Callbacks.glfwFreeCallbacks(handle); + keyCallback = null; + charCallback = null; + cursorEnterCallback = null; + cursorPosCallback = null; + mouseButtonCallback = null; + windowFocusCallback = null; + windowIconifyCallback = null; + windowSizeCallback = null; + windowPosCallback = null; + windowRefreshCallback = null; + framebufferSizeCallback = null; + scrollCallback = null; + System.gc(); + } + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayImplementation.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayImplementation.java new file mode 100644 index 000000000..7f76555f2 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayImplementation.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * This is the Display implementation interface. Display delegates + * to implementors of this interface. There is one DisplayImplementation + * for each supported platform. + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.awt.Canvas; + +import org.lwjgl.LWJGLException; + +interface DisplayImplementation extends InputImplementation { + + void createWindow(DrawableLWJGL drawable, DisplayMode mode, Canvas parent, int x, int y) throws LWJGLException; + + void destroyWindow(); + + void switchDisplayMode(DisplayMode mode) throws LWJGLException; + + /** + * Reset the display mode to whatever it was when LWJGL was initialized. + * Fails silently. + */ + void resetDisplayMode(); + + /** + * Return the length of the gamma ramp arrays. Returns 0 if gamma settings are + * unsupported. + * + * @return the length of each gamma ramp array, or 0 if gamma settings are unsupported. + */ + int getGammaRampLength(); + + /** + * Method to set the gamma ramp. + */ + void setGammaRamp(FloatBuffer gammaRamp) throws LWJGLException; + + /** + * Get the driver adapter string. This is a unique string describing the actual card's hardware, eg. "Geforce2", "PS2", + * "Radeon9700". If the adapter cannot be determined, this function returns null. + * @return a String + */ + String getAdapter(); + + /** + * Get the driver version. This is a vendor/adapter specific version string. If the version cannot be determined, + * this function returns null. + * @return a String + */ + String getVersion(); + + /** + * Initialize and return the current display mode. + */ + DisplayMode init() throws LWJGLException; + + /** + * Implementation of setTitle(). This will read the window's title member + * and stash it in the native title of the window. + */ + void setTitle(String title); + + boolean isCloseRequested(); + + boolean isVisible(); + boolean isActive(); + + boolean isDirty(); + + /** + * Create the native PeerInfo. + * @throws LWJGLException + */ + PeerInfo createPeerInfo(PixelFormat pixel_format, ContextAttribs attribs) throws LWJGLException; + +// void destroyPeerInfo(); + + /** + * Updates the windows internal state. This must be called at least once per video frame + * to handle window close requests, moves, paints, etc. + */ + void update(); + + void reshape(int x, int y, int width, int height); + + /** + * Method for getting displaymodes + */ + DisplayMode[] getAvailableDisplayModes() throws LWJGLException; + + /* Pbuffer */ + int getPbufferCapabilities(); + + /** + * Method to test for buffer integrity + */ + boolean isBufferLost(PeerInfo handle); + + /** + * Method to create a Pbuffer + */ + PeerInfo createPbuffer(int width, int height, PixelFormat pixel_format, ContextAttribs attribs, + IntBuffer pixelFormatCaps, + IntBuffer pBufferAttribs) throws LWJGLException; + + void setPbufferAttrib(PeerInfo handle, int attrib, int value); + + void bindTexImageToPbuffer(PeerInfo handle, int buffer); + + void releaseTexImageFromPbuffer(PeerInfo handle, int buffer); + + /** + * Sets one or more icons for the Display. + *

    + *
  • On Windows you should supply at least one 16x16 icon and one 32x32.
  • + *
  • Linux (and similar platforms) expect one 32x32 icon.
  • + *
  • Mac OS X should be supplied one 128x128 icon
  • + *
+ * The implementation will use the supplied ByteBuffers with image data in RGBA and perform any conversions nescesarry for the specific platform. + * + * @param icons Array of icons in RGBA mode + * @return number of icons used. + */ + int setIcon(ByteBuffer[] icons); + + /** + * Enable or disable the Display window to be resized. + * + * @param resizable set to true to make the Display window resizable; + * false to disable resizing on the Display window. + */ + void setResizable(boolean resizable); + + /** + * @return true if the Display window has been resized since this method was last called. + */ + boolean wasResized(); + + /** + * @return this method will return the width of the Display window. + */ + int getWidth(); + + /** + * @return this method will return the height of the Display window. + */ + int getHeight(); + + /** + * @return this method will return the top-left x position of the Display window. + */ + int getX(); + + /** + * @return this method will return the top-left y position of the Display window. + */ + int getY(); + + /** + * @return this method will return the pixel scale factor of the Display window useful for high resolution modes. + */ + float getPixelScaleFactor(); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayMode.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayMode.java new file mode 100644 index 000000000..23bd84aca --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DisplayMode.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * + * This class encapsulates the properties for a given display mode. + * This class is not instantiable, and is aquired from the Display. + * getAvailableDisplayModes() method. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ + +public final class DisplayMode { + + /** properties of the display mode */ + private final int width, height, bpp, freq; + /** If true, this instance can be used for fullscreen modes */ + private final boolean fullscreen; + + /** + * Construct a display mode. DisplayModes constructed through the + * public constructor can only be used to specify the dimensions of + * the Display in windowed mode. To get the available DisplayModes for + * fullscreen modes, use Display.getAvailableDisplayModes(). + * + * @param width The Display width. + * @param height The Display height. + * @see Display + */ + public DisplayMode(int width, int height) { + this(width, height, 0, 0, false); + } + + DisplayMode(int width, int height, int bpp, int freq) { + this(width, height, bpp, freq, true); + } + + private DisplayMode(int width, int height, int bpp, int freq, boolean fullscreen) { + this.width = width; + this.height = height; + this.bpp = bpp; + this.freq = freq; + this.fullscreen = fullscreen; + } + + /** True if this instance can be used for fullscreen modes */ + public boolean isFullscreenCapable() { + return fullscreen; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public int getBitsPerPixel() { + return bpp; + } + + public int getFrequency() { + return freq; + } + + /** + * Tests for DisplayMode equality + * + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof DisplayMode)) { + return false; + } + + DisplayMode dm = (DisplayMode) obj; + return dm.width == width + && dm.height == height + && dm.bpp == bpp + && dm.freq == freq; + } + + /** + * Retrieves the hashcode for this object + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return width ^ height ^ freq ^ bpp; + } + + /** + * Retrieves a String representation of this DisplayMode + * + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(32); + sb.append(width); + sb.append(" x "); + sb.append(height); + sb.append(" x "); + sb.append(bpp); + sb.append(" @"); + sb.append(freq); + sb.append("Hz"); + return sb.toString(); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Drawable.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Drawable.java new file mode 100644 index 000000000..d5fdc4b82 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Drawable.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; +import org.lwjgl.PointerBuffer; + +/** + * The Drawable interface describes an OpenGL drawable with an associated + * Context. + * + * @author elias_naur + */ + +public interface Drawable { + + /** Returns true if the Drawable's context is current in the current thread. */ + boolean isCurrent() throws LWJGLException; + + /** + * Makes the Drawable's context current in the current thread. + * + * @throws LWJGLException + */ + void makeCurrent() throws LWJGLException; + + /** + * If the Drawable's context is current in the current thread, no context will be current after a call to this method. + * + * @throws LWJGLException + */ + void releaseContext() throws LWJGLException; + + /** Destroys the Drawable. */ + void destroy(); + + /** + * Sets the appropriate khr_gl_sharing properties in the target PointerBuffer, + * so that if it is used in a clCreateContext(FromType) call, the created CL + * context will be sharing objects with this Drawable's GL context. After a + * call to this method, the target buffer position will have advanced by 2 to 4 positions, + * depending on the implementation. + * + * @param properties The target properties buffer. It must have at least 4 positions remaining. + */ + void setCLSharingProperties(PointerBuffer properties) throws LWJGLException; + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableGL.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableGL.java new file mode 100644 index 000000000..85b9bbce8 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableGL.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; +import org.lwjgl.LWJGLUtil; +import org.lwjgl.PointerBuffer; + +import static org.lwjgl.opengl.GL11.*; + +/** @author Spasi */ +abstract class DrawableGL implements DrawableLWJGL { + + /** The PixelFormat used to create the drawable. */ + protected PixelFormat pixel_format; + + /** Handle to the native GL rendering context */ + protected PeerInfo peer_info; + + /** The OpenGL Context. */ + protected ContextGL context; + + protected DrawableGL() { + } + + public void setPixelFormat(final PixelFormatLWJGL pf) throws LWJGLException { + throw new UnsupportedOperationException(); + } + + public void setPixelFormat(final PixelFormatLWJGL pf, final ContextAttribs attribs) throws LWJGLException { + this.pixel_format = (PixelFormat)pf; + this.peer_info = Display.getImplementation().createPeerInfo(pixel_format, attribs); + } + + public PixelFormatLWJGL getPixelFormat() { + return pixel_format; + } + + public ContextGL getContext() { + synchronized ( GlobalLock.lock ) { + return context; + } + } + + public ContextGL createSharedContext() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + return new ContextGL(peer_info, context.getContextAttribs(), context); + // return null; + } + } + + public void checkGLError() { + Util.checkGLError(); + } + + public void setSwapInterval(final int swap_interval) { + ContextGL.setSwapInterval(swap_interval); + } + + public void swapBuffers() throws LWJGLException { + ContextGL.swapBuffers(); + } + + public void initContext(final float r, final float g, final float b) { + // set background clear color + glClearColor(r, g, b, 0.0f); + // Clear window to avoid the desktop "showing through" + glClear(GL_COLOR_BUFFER_BIT); + } + + public boolean isCurrent() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + return context.isCurrent(); + } + } + + public void makeCurrent() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + context.makeCurrent(); + } + } + + public void releaseContext() throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + if ( context.isCurrent() ) + context.releaseCurrent(); + } + } + + public void destroy() { + synchronized ( GlobalLock.lock ) { + if ( context == null ) + return; + + try { + releaseContext(); + + context.forceDestroy(); + context = null; + + if ( peer_info != null ) { + peer_info.destroy(); + peer_info = null; + } + } catch (LWJGLException e) { + LWJGLUtil.log("Exception occurred while destroying Drawable: " + e); + } + } + } + + public void setCLSharingProperties(final PointerBuffer properties) throws LWJGLException { + synchronized ( GlobalLock.lock ) { + checkDestroyed(); + context.setCLSharingProperties(properties); + } + } + + protected final void checkDestroyed() { + if ( context == null ) + throw new IllegalStateException("The Drawable has no context available."); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableLWJGL.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableLWJGL.java new file mode 100644 index 000000000..f80ad4645 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/DrawableLWJGL.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; + +/** + * [INTERNAL USE ONLY] + * + * @author Spasi + */ +interface DrawableLWJGL extends Drawable { + + void setPixelFormat(PixelFormatLWJGL pf) throws LWJGLException; + + void setPixelFormat(PixelFormatLWJGL pf, ContextAttribs attribs) throws LWJGLException; + + PixelFormatLWJGL getPixelFormat(); + + /** + * [INTERNAL USE ONLY] Returns the Drawable's Context. + * + * @return the Drawable's Context + */ + Context getContext(); + + /** + * [INTERNAL USE ONLY] Creates a new Context that is shared with the Drawable's Context. + * + * @return a Context shared with the Drawable's Context. + */ + Context createSharedContext() throws LWJGLException; + + void checkGLError(); + + void setSwapInterval(int swap_interval); + + void swapBuffers() throws LWJGLException; + + void initContext(final float r, final float g, final float b); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTAbgr.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTAbgr.java new file mode 100644 index 000000000..606f4a08e --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTAbgr.java @@ -0,0 +1,7 @@ +package org.lwjgl.opengl; + +import org.lwjgl.opengl.EXTABGR; + +public class EXTAbgr { + public final static int GL_ABGR_EXT = EXTABGR.GL_ABGR_EXT; +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTTextureRectangle.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTTextureRectangle.java new file mode 100644 index 000000000..ba3c9c5c0 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/EXTTextureRectangle.java @@ -0,0 +1,8 @@ +package org.lwjgl.opengl; + +public class EXTTextureRectangle { + public final static int GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT = 34040; + public final static int GL_PROXY_TEXTURE_RECTANGLE_EXT = 34039; + public final static int GL_TEXTURE_BINDING_RECTANGLE_EXT = 34038; + public final static int GL_TEXTURE_RECTANGLE_EXT = 34037; +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL.java new file mode 100644 index 000000000..c86cd67c3 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL.java @@ -0,0 +1,743 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + */ +package org.lwjgl.opengl; + +import org.lwjgl.system.*; +import org.lwjgl.system.macosx.*; +import org.lwjgl.system.windows.*; +import org.lwjgl.glfw.*; + +import javax.annotation.*; +import java.nio.*; +import java.util.*; + +import static java.lang.Math.*; +import static org.lwjgl.opengl.GL32C.*; +import static org.lwjgl.opengl.GLX.*; +import static org.lwjgl.opengl.GLX11.*; +import static org.lwjgl.opengl.WGL.*; +import static org.lwjgl.system.APIUtil.*; +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.MemoryUtil.*; +import static org.lwjgl.system.linux.X11.*; +import static org.lwjgl.system.windows.GDI32.*; +import static org.lwjgl.system.windows.User32.*; +import static org.lwjgl.system.windows.WindowsUtil.*; + +/** + * This class must be used before any OpenGL function is called. It has the following responsibilities: + *
    + *
  • Loads the OpenGL native library into the JVM process.
  • + *
  • Creates instances of {@link GLCapabilities} classes. A {@code GLCapabilities} instance contains flags for functionality that is available in an OpenGL + * context. Internally, it also contains function pointers that are only valid in that specific OpenGL context.
  • + *
  • Maintains thread-local state for {@code GLCapabilities} instances, corresponding to OpenGL contexts that are current in those threads.
  • + *
+ * + *

Library lifecycle

+ *

The OpenGL library is loaded automatically when this class is initialized. Set the {@link Configuration#OPENGL_EXPLICIT_INIT} option to override this + * behavior. Manual loading/unloading can be achieved with the {@link #create} and {@link #destroy} functions. The name of the library loaded can be overridden + * with the {@link Configuration#OPENGL_LIBRARY_NAME} option. The maximum OpenGL version loaded can be set with the {@link Configuration#OPENGL_MAXVERSION} + * option. This can be useful to ensure that no functionality above a specific version is used during development.

+ * + *

GLCapabilities creation

+ *

Instances of {@code GLCapabilities} can be created with the {@link #createCapabilities} method. An OpenGL context must be current in the current thread + * before it is called. Calling this method is expensive, so the {@code GLCapabilities} instance should be associated with the OpenGL context and reused as + * necessary.

+ * + *

Thread-local state

+ *

Before a function for a given OpenGL context can be called, the corresponding {@code GLCapabilities} instance must be passed to the + * {@link #setCapabilities} method. The user is also responsible for clearing the current {@code GLCapabilities} instance when the context is destroyed or made + * current in another thread.

+ * + *

Note that the {@link #createCapabilities} method implicitly calls {@link #setCapabilities} with the newly created instance.

+ */ +public final class GL { + + @Nullable + private static final APIVersion MAX_VERSION; + + @Nullable + private static FunctionProvider functionProvider; + + private static final ThreadLocal capabilitiesTLS = new ThreadLocal<>(); + + private static ICD icd = new ICDStatic(); + + @Nullable + private static WGLCapabilities capabilitiesWGL; + + @Nullable + private static GLXCapabilities capabilitiesGLXClient; + @Nullable + private static GLXCapabilities capabilitiesGLX; + + private static final boolean isUsingRegal; + + static { + isUsingRegal = System.getProperty("org.lwjgl.opengl.libname").contains("libRegal.so"); + // if (isUsingRegal) + + + Library.loadSystem(System::load, System::loadLibrary, GL.class, "org.lwjgl.opengl", Platform.mapLibraryNameBundled("lwjgl_opengl")); + + MAX_VERSION = apiParseVersion(Configuration.OPENGL_MAXVERSION); + + if (!Configuration.OPENGL_EXPLICIT_INIT.get(false)) { + create(); + } + } + + private static native void nativeRegalMakeCurrent(); + + private GL() {} + + /** Ensures that the lwjgl_opengl shared library has been loaded. */ + static void initialize() { + // intentionally empty to trigger static initializer + } + + /** Loads the OpenGL native library, using the default library name. */ + public static void create() { + SharedLibrary GL; + switch (Platform.get()) { + case LINUX: + GL = Library.loadNative(GL.class, "org.lwjgl.opengl", Configuration.OPENGL_LIBRARY_NAME, "libGL.so.1", "libGL.so"); + break; + case MACOSX: + String override = Configuration.OPENGL_LIBRARY_NAME.get(); + GL = override != null + ? Library.loadNative(GL.class, "org.lwjgl.opengl", override) + : MacOSXLibrary.getWithIdentifier("com.apple.opengl"); + break; + case WINDOWS: + GL = Library.loadNative(GL.class, "org.lwjgl.opengl", Configuration.OPENGL_LIBRARY_NAME, "opengl32"); + break; + default: + throw new IllegalStateException(); + } + create(GL); + } + + /** + * Loads the OpenGL native library, using the specified library name. + * + * @param libName the native library name + */ + public static void create(String libName) { + create(Library.loadNative(GL.class, "org.lwjgl.opengl", libName)); + } + + private abstract static class SharedLibraryGL extends SharedLibrary.Delegate { + + SharedLibraryGL(SharedLibrary library) { + super(library); + } + abstract long getExtensionAddress(long name); + + @Override + public long getFunctionAddress(ByteBuffer functionName) { + long address = getExtensionAddress(memAddress(functionName)); + if (address == NULL) { + address = library.getFunctionAddress(functionName); + if (address == NULL && DEBUG_FUNCTIONS) { + apiLog("Failed to locate address for GL function " + memASCII(functionName)); + } + } + + return address; + } + + } + + private static void create(SharedLibrary OPENGL) { + FunctionProvider functionProvider; + try { + switch (Platform.get()) { + case WINDOWS: + functionProvider = new SharedLibraryGL(OPENGL) { + private final long wglGetProcAddress = library.getFunctionAddress("wglGetProcAddress"); + + @Override + long getExtensionAddress(long name) { + return callPP(name, wglGetProcAddress); + } + }; + break; + case LINUX: + functionProvider = new SharedLibraryGL(OPENGL) { + private final long glXGetProcAddress; + + { + long GetProcAddress = library.getFunctionAddress(isUsingRegal ? "glGetProcAddressREGAL" : "glXGetProcAddress"); + if (GetProcAddress == NULL) { + GetProcAddress = library.getFunctionAddress("glXGetProcAddressARB"); + } + + glXGetProcAddress = GetProcAddress; + } + + @Override + long getExtensionAddress(long name) { + return glXGetProcAddress == NULL ? NULL : callPP(name, glXGetProcAddress); + } + }; + break; + case MACOSX: + functionProvider = new SharedLibraryGL(OPENGL) { + @Override + long getExtensionAddress(long name) { + return NULL; + } + }; + break; + default: + throw new IllegalStateException(); + } + create(functionProvider); + } catch (RuntimeException e) { + OPENGL.free(); + throw e; + } + } + + /** + * Initializes OpenGL with the specified {@link FunctionProvider}. This method can be used to implement custom OpenGL library loading. + * + * @param functionProvider the provider of OpenGL function addresses + */ + public static void create(FunctionProvider functionProvider) { + if (GL.functionProvider != null) { + throw new IllegalStateException("OpenGL library has already been loaded."); + } + + GL.functionProvider = functionProvider; + ThreadLocalUtil.setFunctionMissingAddresses(GLCapabilities.class, 3); + } + + /** Unloads the OpenGL native library. */ + public static void destroy() { + if (functionProvider == null) { + return; + } + + ThreadLocalUtil.setFunctionMissingAddresses(null, 3); + + capabilitiesWGL = null; + capabilitiesGLX = null; + + if (functionProvider instanceof NativeResource) { + ((NativeResource)functionProvider).free(); + } + functionProvider = null; + } + + /** Returns the {@link FunctionProvider} for the OpenGL native library. */ + @Nullable + public static FunctionProvider getFunctionProvider() { + return functionProvider; + } + + /** + * Sets the {@link GLCapabilities} of the OpenGL context that is current in the current thread. + * + *

This {@code GLCapabilities} instance will be used by any OpenGL call in the current thread, until {@code setCapabilities} is called again with a + * different value.

+ */ + public static void setCapabilities(@Nullable GLCapabilities caps) { + capabilitiesTLS.set(caps); + ThreadLocalUtil.setEnv(caps == null ? NULL : memAddress(caps.addresses), 3); + icd.set(caps); + } + + /** + * Returns the {@link GLCapabilities} of the OpenGL context that is current in the current thread. + * + * @throws IllegalStateException if {@link #setCapabilities} has never been called in the current thread or was last called with a {@code null} value + */ + public static GLCapabilities getCapabilities() { + return checkCapabilities(capabilitiesTLS.get()); + } + + private static GLCapabilities checkCapabilities(@Nullable GLCapabilities caps) { + if (CHECKS && caps == null) { + throw new IllegalStateException( + "No GLCapabilities instance set for the current thread. Possible solutions:\n" + + "\ta) Call GL.createCapabilities() after making a context current in the current thread.\n" + + "\tb) Call GL.setCapabilities() if a GLCapabilities instance already exists for the current context." + ); + } + //noinspection ConstantConditions + return caps; + } + + /** + * Returns the WGL capabilities. + * + *

This method may only be used on Windows.

+ */ + public static WGLCapabilities getCapabilitiesWGL() { + if (capabilitiesWGL == null) { + capabilitiesWGL = createCapabilitiesWGLDummy(); + } + + return capabilitiesWGL; + } + + /** Returns the GLX client capabilities. */ + static GLXCapabilities getCapabilitiesGLXClient() { + if (capabilitiesGLXClient == null) { + capabilitiesGLXClient = initCapabilitiesGLX(true); + } + + return capabilitiesGLXClient; + } + + /** + * Returns the GLX capabilities. + * + *

This method may only be used on Linux.

+ */ + public static GLXCapabilities getCapabilitiesGLX() { + if (capabilitiesGLX == null) { + capabilitiesGLX = initCapabilitiesGLX(false); + } + + return capabilitiesGLX; + } + + private static GLXCapabilities initCapabilitiesGLX(boolean client) { + long display = nXOpenDisplay(NULL); + try { + return createCapabilitiesGLX(display, client ? -1 : XDefaultScreen(display)); + } finally { + XCloseDisplay(display); + } + } + + /** + * Creates a new {@link GLCapabilities} instance for the OpenGL context that is current in the current thread. + * + *

Depending on the current context, the instance returned may or may not contain the deprecated functionality removed since OpenGL version 3.1.

+ * + *

This method calls {@link #setCapabilities(GLCapabilities)} with the new instance before returning.

+ * + * @return the GLCapabilities instance + */ + public static GLCapabilities createCapabilities() { + return createCapabilities(false); + } + + /** + * Creates a new {@link GLCapabilities} instance for the OpenGL context that is current in the current thread. + * + *

Depending on the current context, the instance returned may or may not contain the deprecated functionality removed since OpenGL version 3.1. The + * {@code forwardCompatible} flag will force LWJGL to not load the deprecated functions, even if the current context exposes them.

+ * + *

This method calls {@link #setCapabilities(GLCapabilities)} with the new instance before returning.

+ * + * @param forwardCompatible if true, LWJGL will create forward compatible capabilities + * + * @return the GLCapabilities instance + */ + @SuppressWarnings("AssignmentToMethodParameter") + public static GLCapabilities createCapabilities(boolean forwardCompatible) { + // This fixed framebuffer issue on 1.13+ 64-bit by another making current + GLFW.nativeEglMakeCurrent(1); + + if (isUsingRegal /* && Long.parseLong(System.getProperty("glfwstub.internal.glthreadid", "-1")) != Thread.currentThread().getId() */) { + nativeRegalMakeCurrent(); + } + // System.setProperty("glfwstub.internal.glthreadid", Long.toString(Thread.currentThread().getId())); + + FunctionProvider functionProvider = GL.functionProvider; + if (functionProvider == null) { + throw new IllegalStateException("OpenGL library has not been loaded."); + } + + GLCapabilities caps = null; + + try { + // We don't have a current ContextCapabilities when this method is called + // so we have to use the native bindings directly. + long GetError = functionProvider.getFunctionAddress("glGetError"); + long GetString = functionProvider.getFunctionAddress("glGetString"); + long GetIntegerv = functionProvider.getFunctionAddress("glGetIntegerv"); + + if (GetError == NULL || GetString == NULL || GetIntegerv == NULL) { + throw new IllegalStateException("Core OpenGL functions could not be found. Make sure that the OpenGL library has been loaded correctly."); + } + + int errorCode = callI(GetError); + if (errorCode != GL_NO_ERROR) { + apiLog(String.format("An OpenGL context was in an error state before the creation of its capabilities instance. Error: 0x%X", errorCode)); + } + + int majorVersion; + int minorVersion; + + try (MemoryStack stack = stackPush()) { + IntBuffer version = stack.ints(0); + + // Try the 3.0+ version query first + callPV(GL_MAJOR_VERSION, memAddress(version), GetIntegerv); + if (callI(GetError) == GL_NO_ERROR && 3 <= (majorVersion = version.get(0))) { + // We're on an 3.0+ context. + callPV(GL_MINOR_VERSION, memAddress(version), GetIntegerv); + minorVersion = version.get(0); + } else { + // Fallback to the string query. + String versionString = memUTF8Safe(callP(GL_VERSION, GetString)); + if (versionString == null || callI(GetError) != GL_NO_ERROR) { + throw new IllegalStateException("There is no OpenGL context current in the current thread."); + } + + APIVersion apiVersion = apiParseVersion(versionString); + + majorVersion = apiVersion.major; + minorVersion = apiVersion.minor; + } + } + + if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 1)) { + throw new IllegalStateException("OpenGL 1.1 is required."); + } + + int[] GL_VERSIONS = { + 5, // OpenGL 1.1 to 1.5 + 1, // OpenGL 2.0 to 2.1 + 3, // OpenGL 3.0 to 3.3 + 6, // OpenGL 4.0 to 4.6 + }; + + Set supportedExtensions = new HashSet<>(512); + + int maxMajor = min(majorVersion, GL_VERSIONS.length); + if (MAX_VERSION != null) { + maxMajor = min(MAX_VERSION.major, maxMajor); + } + for (int M = 1; M <= maxMajor; M++) { + int maxMinor = GL_VERSIONS[M - 1]; + if (M == majorVersion) { + maxMinor = min(minorVersion, maxMinor); + } + if (MAX_VERSION != null && M == MAX_VERSION.major) { + maxMinor = min(MAX_VERSION.minor, maxMinor); + } + + for (int m = M == 1 ? 1 : 0; m <= maxMinor; m++) { + supportedExtensions.add(String.format("OpenGL%d%d", M, m)); + } + } + + if (majorVersion < 3) { + // Parse EXTENSIONS string + String extensionsString = memASCIISafe(callP(GL_EXTENSIONS, GetString)); + if (extensionsString != null) { + StringTokenizer tokenizer = new StringTokenizer(extensionsString); + while (tokenizer.hasMoreTokens()) { + supportedExtensions.add(tokenizer.nextToken()); + } + } + } else { + // Use indexed EXTENSIONS + try (MemoryStack stack = stackPush()) { + IntBuffer pi = stack.ints(0); + + callPV(GL_NUM_EXTENSIONS, memAddress(pi), GetIntegerv); + int extensionCount = pi.get(0); + + long GetStringi = apiGetFunctionAddress(functionProvider, "glGetStringi"); + for (int i = 0; i < extensionCount; i++) { + supportedExtensions.add(memASCII(callP(GL_EXTENSIONS, i, GetStringi))); + } + + // In real drivers, we may encounter the following weird scenarios: + // - 3.1 context without GL_ARB_compatibility but with deprecated functionality exposed and working. + // - Core or forward-compatible context with GL_ARB_compatibility exposed, but not working when used. + // We ignore these and go by the spec. + + // Force forwardCompatible to true if the context is a forward-compatible context. + callPV(GL_CONTEXT_FLAGS, memAddress(pi), GetIntegerv); + if ((pi.get(0) & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) != 0) { + forwardCompatible = true; + } else { + // Force forwardCompatible to true if the context is a core profile context. + if ((3 < majorVersion || 1 <= minorVersion)) { // OpenGL 3.1+ + if (3 < majorVersion || 2 <= minorVersion) { // OpenGL 3.2+ + callPV(GL_CONTEXT_PROFILE_MASK, memAddress(pi), GetIntegerv); + if ((pi.get(0) & GL_CONTEXT_CORE_PROFILE_BIT) != 0) { + forwardCompatible = true; + } + } else { + forwardCompatible = !supportedExtensions.contains("GL_ARB_compatibility"); + } + } + } + } + } + + return caps = new GLCapabilities(functionProvider, supportedExtensions, forwardCompatible); + } finally { + setCapabilities(caps); + } + } + + /** Creates a dummy context and retrieves the WGL capabilities. */ + private static WGLCapabilities createCapabilitiesWGLDummy() { + long hdc = wglGetCurrentDC(); // just use the current context if one exists + if (hdc != NULL) { + return createCapabilitiesWGL(hdc); + } + + short classAtom = 0; + long hwnd = NULL; + long hglrc = NULL; + try (MemoryStack stack = stackPush()) { + WNDCLASSEX wc = WNDCLASSEX.callocStack(stack) + .cbSize(WNDCLASSEX.SIZEOF) + .style(CS_HREDRAW | CS_VREDRAW) + .hInstance(WindowsLibrary.HINSTANCE) + .lpszClassName(stack.UTF16("WGL")); + + memPutAddress( + wc.address() + WNDCLASSEX.LPFNWNDPROC, + User32.Functions.DefWindowProc + ); + + classAtom = RegisterClassEx(wc); + if (classAtom == 0) { + throw new IllegalStateException("Failed to register WGL window class"); + } + + hwnd = check(nCreateWindowEx( + 0, classAtom & 0xFFFF, NULL, + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, + 0, 0, 1, 1, + NULL, NULL, NULL, NULL + )); + + hdc = check(GetDC(hwnd)); + + PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.callocStack(stack) + .nSize((short)PIXELFORMATDESCRIPTOR.SIZEOF) + .nVersion((short)1) + .dwFlags(PFD_SUPPORT_OPENGL); // we don't care about anything else + + int pixelFormat = ChoosePixelFormat(hdc, pfd); + if (pixelFormat == 0) { + windowsThrowException("Failed to choose an OpenGL-compatible pixel format"); + } + + if (DescribePixelFormat(hdc, pixelFormat, pfd) == 0) { + windowsThrowException("Failed to obtain pixel format information"); + } + + if (!SetPixelFormat(hdc, pixelFormat, pfd)) { + windowsThrowException("Failed to set the pixel format"); + } + + hglrc = check(wglCreateContext(hdc)); + wglMakeCurrent(hdc, hglrc); + + return createCapabilitiesWGL(hdc); + } finally { + if (hglrc != NULL) { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hglrc); + } + + if (hwnd != NULL) { + DestroyWindow(hwnd); + } + + if (classAtom != 0) { + nUnregisterClass(classAtom & 0xFFFF, WindowsLibrary.HINSTANCE); + } + } + } + + /** + * Creates a {@link WGLCapabilities} instance for the context that is current in the current thread. + * + *

This method may only be used on Windows.

+ */ + public static WGLCapabilities createCapabilitiesWGL() { + long hdc = wglGetCurrentDC(); + if (hdc == NULL) { + throw new IllegalStateException("Failed to retrieve the device context of the current OpenGL context"); + } + + return createCapabilitiesWGL(hdc); + } + + /** + * Creates a {@link WGLCapabilities} instance for the specified device context. + * + * @param hdc the device context handle ({@code HDC}) + */ + private static WGLCapabilities createCapabilitiesWGL(long hdc) { + FunctionProvider functionProvider = GL.functionProvider; + if (functionProvider == null) { + throw new IllegalStateException("OpenGL library has not been loaded."); + } + + String extensionsString = null; + + long wglGetExtensionsString = functionProvider.getFunctionAddress("wglGetExtensionsStringARB"); + if (wglGetExtensionsString != NULL) { + extensionsString = memASCII(callPP(hdc, wglGetExtensionsString)); + } else { + wglGetExtensionsString = functionProvider.getFunctionAddress("wglGetExtensionsStringEXT"); + if (wglGetExtensionsString != NULL) { + extensionsString = memASCII(callP(wglGetExtensionsString)); + } + } + + Set supportedExtensions = new HashSet<>(32); + + if (extensionsString != null) { + StringTokenizer tokenizer = new StringTokenizer(extensionsString); + while (tokenizer.hasMoreTokens()) { + supportedExtensions.add(tokenizer.nextToken()); + } + } + + return new WGLCapabilities(functionProvider, supportedExtensions); + } + + /** + * Creates a {@link GLXCapabilities} instance for the default screen of the specified X connection. + * + *

This method may only be used on Linux.

+ * + * @param display the X connection handle ({@code DISPLAY}) + */ + public static GLXCapabilities createCapabilitiesGLX(long display) { + return createCapabilitiesGLX(display, XDefaultScreen(display)); + } + + /** + * Creates a {@link GLXCapabilities} instance for the specified screen of the specified X connection. + * + *

This method may only be used on Linux.

+ * + * @param display the X connection handle ({@code DISPLAY}) + * @param screen the screen index + */ + public static GLXCapabilities createCapabilitiesGLX(long display, int screen) { + FunctionProvider functionProvider = GL.functionProvider; + if (functionProvider == null) { + throw new IllegalStateException("OpenGL library has not been loaded."); + } + + int majorVersion = 1; + int minorVersion = 4; + + Set supportedExtensions = new HashSet<>(32); + + int[][] GLX_VERSIONS = { + {1, 2, 3, 4} + }; + + try (MemoryStack stack = stackPush()) { + IntBuffer piMajor = stack.ints(0); + IntBuffer piMinor = stack.ints(0); + + if (!glXQueryVersion(display, piMajor, piMinor)) { + throw new IllegalStateException("Failed to query GLX version"); + } + + majorVersion = piMajor.get(0); + minorVersion = piMinor.get(0); + if (majorVersion != 1) { + throw new IllegalStateException("Invalid GLX major version: " + majorVersion); + } + } + + for (int major = 1; major <= GLX_VERSIONS.length; major++) { + int[] minors = GLX_VERSIONS[major - 1]; + for (int minor : minors) { + if (major < majorVersion || (major == majorVersion && minor <= minorVersion)) { + supportedExtensions.add("GLX" + major + minor); + } + } + } + + if (1 <= minorVersion) { + String extensionsString; + + if (screen == -1) { + long glXGetClientString = functionProvider.getFunctionAddress("glXGetClientString"); + extensionsString = memASCIISafe(callPP(display, GLX_EXTENSIONS, glXGetClientString)); + } else { + long glXQueryExtensionsString = functionProvider.getFunctionAddress("glXQueryExtensionsString"); + extensionsString = memASCIISafe(callPP(display, screen, glXQueryExtensionsString)); + } + + if (extensionsString != null) { + StringTokenizer tokenizer = new StringTokenizer(extensionsString); + while (tokenizer.hasMoreTokens()) { + supportedExtensions.add(tokenizer.nextToken()); + } + } + } + + return new GLXCapabilities(functionProvider, supportedExtensions); + } + + // Only used by array overloads + static GLCapabilities getICD() { + return checkCapabilities(icd.get()); + } + + /** Function pointer provider. */ + private interface ICD { + default void set(@Nullable GLCapabilities caps) {} + @Nullable GLCapabilities get(); + } + + /** + * Write-once {@link ICD}. + * + *

This is the default implementation that skips the thread-local lookup. When a new GLCapabilities is set, we compare it to the write-once capabilities. + * If different function pointers are found, we fall back to the expensive lookup.

+ */ + private static class ICDStatic implements ICD { + + @Nullable + private static GLCapabilities tempCaps; + + @Override + public void set(@Nullable GLCapabilities caps) { + if (tempCaps == null) { + tempCaps = caps; + } else if (caps != null && caps != tempCaps && ThreadLocalUtil.areCapabilitiesDifferent(tempCaps.addresses, caps.addresses)) { + apiLog("[WARNING] Incompatible context detected. Falling back to thread-local lookup for GL contexts."); + icd = GL::getCapabilities; // fall back to thread/process lookup + } + } + + @Override + public GLCapabilities get() { + return WriteOnce.caps; + } + + private static final class WriteOnce { + // This will be initialized the first time get() above is called + @Nullable + static final GLCapabilities caps = ICDStatic.tempCaps; + + static { + if (caps == null) { + throw new IllegalStateException("No GLCapabilities instance has been set"); + } + } + } + + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL11.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL11.java new file mode 100644 index 000000000..32835e5e2 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL11.java @@ -0,0 +1,10225 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.opengl; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; +import static org.lwjgl.system.JNI.*; +import static org.lwjgl.system.MemoryStack.*; +import static org.lwjgl.system.MemoryUtil.*; + +/** + * The OpenGL functionality up to version 1.1. Includes the deprecated symbols of the Compatibility Profile. + * + *

Extensions promoted to core in this release:

+ * + * + */ +public class GL11 { +// -- Begin LWJGL2 Bridge -- + public static void glColorPointer(int size, boolean unsigned, int stride, java.nio.ByteBuffer pointer) { + glColorPointer(size, unsigned ? GL11.GL_UNSIGNED_BYTE : GL11.GL_BYTE, stride, pointer); + } + + public static void glColorPointer(int size, int stride, FloatBuffer pointer) { + glColorPointer(size, GL11.GL_FLOAT, stride, pointer); + } + + public static void glFog(int p1, java.nio.FloatBuffer p2) { + glFogfv(p1, p2); + } + + public static void glFog(int p1, java.nio.IntBuffer p2) { + glFogiv(p1, p2); + } + + public static void glGetBoolean(int p1, java.nio.ByteBuffer p2) { + glGetBooleanv(p1, p2); + } + + public static void glGetDouble(int p1, java.nio.DoubleBuffer p2) { + glGetDoublev(p1, p2); + } + + public static void glGetFloat(int p1, FloatBuffer p2) { + glGetFloatv(p1, p2); + } + + public static void glGetInteger(int p1, IntBuffer p2) { + glGetIntegerv(p1, p2); + } + + public static void glGetLight(int p1, int p2, FloatBuffer p3) { + glGetLightfv(p1, p2, p3); + } + + public static void glGetLight(int p1, int p2, IntBuffer p3) { + glGetLightiv(p1, p2, p3); + } + + public static void glGetMap(int p1, int p2, DoubleBuffer p3) { + glGetMapdv(p1, p2, p3); + } + + public static void glGetMap(int p1, int p2, FloatBuffer p3) { + glGetMapfv(p1, p2, p3); + } + + public static void glGetMap(int p1, int p2, IntBuffer p3) { + glGetMapiv(p1, p2, p3); + } + + public static void glGetMaterial(int p1, int p2, FloatBuffer p3) { + glGetMaterialfv(p1, p2, p3); + } + + public static void glGetMaterial(int p1, int p2, IntBuffer p3) { + glGetMaterialiv(p1, p2, p3); + } + + public static void glGetPixelMap(int p1, FloatBuffer p2) { + glGetPixelMapfv(p1, p2); + } + + public static void glGetPixelMapu(int p1, IntBuffer p2) { + glGetPixelMapuiv(p1, p2); + } + + public static void glGetPixelMapu(int p1, ShortBuffer p2) { + glGetPixelMapusv(p1, p2); + } + + public static void glGetTexEnv(int p1, int p2, FloatBuffer p3) { + glGetTexEnvfv(p1, p2, p3); + } + + public static void glGetTexEnv(int p1, int p2, IntBuffer p3) { + glGetTexEnviv(p1, p2, p3); + } + + public static void glGetTexGen(int p1, int p2, DoubleBuffer p3) { + glGetTexGendv(p1, p2, p3); + } + + public static void glGetTexGen(int p1, int p2, FloatBuffer p3) { + glGetTexGenfv(p1, p2, p3); + } + + public static void glGetTexGen(int p1, int p2, IntBuffer p3) { + glGetTexGeniv(p1, p2, p3); + } + + public static void glGetTexLevelParameter(int target, int level, int pname, FloatBuffer params) { + glGetTexLevelParameterfv(target, level, pname, params); + } + + public static void glGetTexLevelParameter(int target, int level, int pname, IntBuffer params) { + glGetTexLevelParameteriv(target, level, pname, params); + } + + public static void glGetTexParameter(int target, int pname, FloatBuffer params) { + glGetTexParameterfv(target, pname, params); + } + + public static void glGetTexParameter(int target, int pname, IntBuffer params) { + glGetTexParameteriv(target, pname, params); + } + + public static void glLight(int light, int pname, FloatBuffer params) { + glLightfv(light, pname, params); + } + + public static void glLight(int light, int pname, IntBuffer params) { + glLightiv(light, pname, params); + } + + public static void glLightModel(int pname, FloatBuffer params) { + glLightModelfv(pname, params); + } + + public static void glLightModel(int pname, IntBuffer params) { + glLightModeliv(pname, params); + } + + public static void glLoadMatrix(DoubleBuffer m) { + glLoadMatrixd(m); + } + + public static void glLoadMatrix(FloatBuffer m) { + glLoadMatrixf(m); + } + + public static void glMaterial(int p1, int p2, java.nio.FloatBuffer p3) { + glMaterialfv(p1, p2, p3); + } + + public static void glMaterial(int p1, int p2, java.nio.IntBuffer p3) { + glMaterialiv(p1, p2, p3); + } + + public static void glMultMatrix(java.nio.DoubleBuffer p1) { + glMultMatrixd(p1); + } + + public static void glMultMatrix(java.nio.FloatBuffer p1) { + glMultMatrixf(p1); + } + + public static void glNormalPointer(int stride, ByteBuffer pointer) { + glNormalPointer(GL11.GL_BYTE, stride, pointer); + } + + public static void glNormalPointer(int stride, FloatBuffer pointer) { + glNormalPointer(GL11.GL_FLOAT, stride, pointer); + } + + public static void glNormalPointer(int stride, IntBuffer pointer) { + glNormalPointer(GL11.GL_INT, stride, pointer); + } + + public static void glNormalPointer(int stride, ShortBuffer pointer) { + glNormalPointer(GL11.GL_SHORT, stride, pointer); + } + + public static void glPixelMap(int p1, java.nio.FloatBuffer p2) { + glPixelMapfv(p1, p2); + } + + public static void glPixelMapu(int p1, java.nio.IntBuffer p2) { + glPixelMapuiv(p1, p2); + } + + public static void glPixelMapu(int p1, java.nio.ShortBuffer p2) { + glPixelMapusv(p1, p2); + } + + // todo texcoordptr bytebuffer + public static void glTexCoordPointer(int size, int stride, FloatBuffer pointer) { + glTexCoordPointer(size, GL11.GL_FLOAT, stride, pointer); + } + + public static void glTexCoordPointer(int size, int stride, IntBuffer pointer) { + glTexCoordPointer(size, GL11.GL_INT, stride, pointer); + } + + public static void glTexCoordPointer(int size, int stride, ShortBuffer pointer) { + glTexCoordPointer(size, GL11.GL_SHORT, stride, pointer); + } + + public static void glTexEnv(int p1, int p2, java.nio.FloatBuffer p3) { + glTexEnvfv(p1, p2, p3); + } + + public static void glTexEnv(int p1, int p2, java.nio.IntBuffer p3) { + glTexEnviv(p1, p2, p3); + } + + public static void glTexGen(int p1, int p2, java.nio.DoubleBuffer p3) { + glTexGendv(p1, p2, p3); + } + + public static void glTexGen(int p1, int p2, java.nio.FloatBuffer p3) { + glTexGenfv(p1, p2, p3); + } + + public static void glTexGen(int p1, int p2, java.nio.IntBuffer p3) { + glTexGeniv(p1, p2, p3); + } + + public static void glVertexPointer(int size, int stride, FloatBuffer pointer) { + glVertexPointer(size, GL11.GL_FLOAT, stride, pointer); + } + + public static void glVertexPointer(int size, int stride, IntBuffer pointer) { + glVertexPointer(size, GL11.GL_INT, stride, pointer); + } + + public static void glVertexPointer(int size, int stride, ShortBuffer pointer) { + glVertexPointer(size, GL11.GL_SHORT, stride, pointer); + } +// ------- end test duplicate --------- + + /** AccumOp */ + public static final int + GL_ACCUM = 0x100, + GL_LOAD = 0x101, + GL_RETURN = 0x102, + GL_MULT = 0x103, + GL_ADD = 0x104; + + /** AlphaFunction */ + public static final int + GL_NEVER = 0x200, + GL_LESS = 0x201, + GL_EQUAL = 0x202, + GL_LEQUAL = 0x203, + GL_GREATER = 0x204, + GL_NOTEQUAL = 0x205, + GL_GEQUAL = 0x206, + GL_ALWAYS = 0x207; + + /** AttribMask */ + public static final int + GL_CURRENT_BIT = 0x1, + GL_POINT_BIT = 0x2, + GL_LINE_BIT = 0x4, + GL_POLYGON_BIT = 0x8, + GL_POLYGON_STIPPLE_BIT = 0x10, + GL_PIXEL_MODE_BIT = 0x20, + GL_LIGHTING_BIT = 0x40, + GL_FOG_BIT = 0x80, + GL_DEPTH_BUFFER_BIT = 0x100, + GL_ACCUM_BUFFER_BIT = 0x200, + GL_STENCIL_BUFFER_BIT = 0x400, + GL_VIEWPORT_BIT = 0x800, + GL_TRANSFORM_BIT = 0x1000, + GL_ENABLE_BIT = 0x2000, + GL_COLOR_BUFFER_BIT = 0x4000, + GL_HINT_BIT = 0x8000, + GL_EVAL_BIT = 0x10000, + GL_LIST_BIT = 0x20000, + GL_TEXTURE_BIT = 0x40000, + GL_SCISSOR_BIT = 0x80000, + GL_ALL_ATTRIB_BITS = 0xFFFFF; + + /** BeginMode */ + public static final int + GL_POINTS = 0x0, + GL_LINES = 0x1, + GL_LINE_LOOP = 0x2, + GL_LINE_STRIP = 0x3, + GL_TRIANGLES = 0x4, + GL_TRIANGLE_STRIP = 0x5, + GL_TRIANGLE_FAN = 0x6, + GL_QUADS = 0x7, + GL_QUAD_STRIP = 0x8, + GL_POLYGON = 0x9; + + /** BlendingFactorDest */ + public static final int + GL_ZERO = 0, + GL_ONE = 1, + GL_SRC_COLOR = 0x300, + GL_ONE_MINUS_SRC_COLOR = 0x301, + GL_SRC_ALPHA = 0x302, + GL_ONE_MINUS_SRC_ALPHA = 0x303, + GL_DST_ALPHA = 0x304, + GL_ONE_MINUS_DST_ALPHA = 0x305; + + /** BlendingFactorSrc */ + public static final int + GL_DST_COLOR = 0x306, + GL_ONE_MINUS_DST_COLOR = 0x307, + GL_SRC_ALPHA_SATURATE = 0x308; + + /** Boolean */ + public static final int + GL_TRUE = 1, + GL_FALSE = 0; + + /** ClipPlaneName */ + public static final int + GL_CLIP_PLANE0 = 0x3000, + GL_CLIP_PLANE1 = 0x3001, + GL_CLIP_PLANE2 = 0x3002, + GL_CLIP_PLANE3 = 0x3003, + GL_CLIP_PLANE4 = 0x3004, + GL_CLIP_PLANE5 = 0x3005; + + /** DataType */ + public static final int + 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_3_BYTES = 0x1408, + GL_4_BYTES = 0x1409, + GL_DOUBLE = 0x140A; + + /** DrawBufferMode */ + public static final int + GL_NONE = 0, + GL_FRONT_LEFT = 0x400, + GL_FRONT_RIGHT = 0x401, + GL_BACK_LEFT = 0x402, + GL_BACK_RIGHT = 0x403, + GL_FRONT = 0x404, + GL_BACK = 0x405, + GL_LEFT = 0x406, + GL_RIGHT = 0x407, + GL_FRONT_AND_BACK = 0x408, + GL_AUX0 = 0x409, + GL_AUX1 = 0x40A, + GL_AUX2 = 0x40B, + GL_AUX3 = 0x40C; + + /** ErrorCode */ + public static final int + GL_NO_ERROR = 0, + GL_INVALID_ENUM = 0x500, + GL_INVALID_VALUE = 0x501, + GL_INVALID_OPERATION = 0x502, + GL_STACK_OVERFLOW = 0x503, + GL_STACK_UNDERFLOW = 0x504, + GL_OUT_OF_MEMORY = 0x505; + + /** FeedBackMode */ + public static final int + GL_2D = 0x600, + GL_3D = 0x601, + GL_3D_COLOR = 0x602, + GL_3D_COLOR_TEXTURE = 0x603, + GL_4D_COLOR_TEXTURE = 0x604; + + /** FeedBackToken */ + public static final int + GL_PASS_THROUGH_TOKEN = 0x700, + GL_POINT_TOKEN = 0x701, + GL_LINE_TOKEN = 0x702, + GL_POLYGON_TOKEN = 0x703, + GL_BITMAP_TOKEN = 0x704, + GL_DRAW_PIXEL_TOKEN = 0x705, + GL_COPY_PIXEL_TOKEN = 0x706, + GL_LINE_RESET_TOKEN = 0x707; + + /** FogMode */ + public static final int + GL_EXP = 0x800, + GL_EXP2 = 0x801; + + /** FrontFaceDirection */ + public static final int + GL_CW = 0x900, + GL_CCW = 0x901; + + /** GetMapTarget */ + public static final int + GL_COEFF = 0xA00, + GL_ORDER = 0xA01, + GL_DOMAIN = 0xA02; + + /** GetTarget */ + public static final int + GL_CURRENT_COLOR = 0xB00, + GL_CURRENT_INDEX = 0xB01, + GL_CURRENT_NORMAL = 0xB02, + GL_CURRENT_TEXTURE_COORDS = 0xB03, + GL_CURRENT_RASTER_COLOR = 0xB04, + GL_CURRENT_RASTER_INDEX = 0xB05, + GL_CURRENT_RASTER_TEXTURE_COORDS = 0xB06, + GL_CURRENT_RASTER_POSITION = 0xB07, + GL_CURRENT_RASTER_POSITION_VALID = 0xB08, + GL_CURRENT_RASTER_DISTANCE = 0xB09, + GL_POINT_SMOOTH = 0xB10, + GL_POINT_SIZE = 0xB11, + GL_POINT_SIZE_RANGE = 0xB12, + GL_POINT_SIZE_GRANULARITY = 0xB13, + GL_LINE_SMOOTH = 0xB20, + GL_LINE_WIDTH = 0xB21, + GL_LINE_WIDTH_RANGE = 0xB22, + GL_LINE_WIDTH_GRANULARITY = 0xB23, + GL_LINE_STIPPLE = 0xB24, + GL_LINE_STIPPLE_PATTERN = 0xB25, + GL_LINE_STIPPLE_REPEAT = 0xB26, + GL_LIST_MODE = 0xB30, + GL_MAX_LIST_NESTING = 0xB31, + GL_LIST_BASE = 0xB32, + GL_LIST_INDEX = 0xB33, + GL_POLYGON_MODE = 0xB40, + GL_POLYGON_SMOOTH = 0xB41, + GL_POLYGON_STIPPLE = 0xB42, + GL_EDGE_FLAG = 0xB43, + GL_CULL_FACE = 0xB44, + GL_CULL_FACE_MODE = 0xB45, + GL_FRONT_FACE = 0xB46, + GL_LIGHTING = 0xB50, + GL_LIGHT_MODEL_LOCAL_VIEWER = 0xB51, + GL_LIGHT_MODEL_TWO_SIDE = 0xB52, + GL_LIGHT_MODEL_AMBIENT = 0xB53, + GL_SHADE_MODEL = 0xB54, + GL_COLOR_MATERIAL_FACE = 0xB55, + GL_COLOR_MATERIAL_PARAMETER = 0xB56, + GL_COLOR_MATERIAL = 0xB57, + GL_FOG = 0xB60, + GL_FOG_INDEX = 0xB61, + GL_FOG_DENSITY = 0xB62, + GL_FOG_START = 0xB63, + GL_FOG_END = 0xB64, + GL_FOG_MODE = 0xB65, + GL_FOG_COLOR = 0xB66, + GL_DEPTH_RANGE = 0xB70, + GL_DEPTH_TEST = 0xB71, + GL_DEPTH_WRITEMASK = 0xB72, + GL_DEPTH_CLEAR_VALUE = 0xB73, + GL_DEPTH_FUNC = 0xB74, + GL_ACCUM_CLEAR_VALUE = 0xB80, + GL_STENCIL_TEST = 0xB90, + GL_STENCIL_CLEAR_VALUE = 0xB91, + GL_STENCIL_FUNC = 0xB92, + GL_STENCIL_VALUE_MASK = 0xB93, + GL_STENCIL_FAIL = 0xB94, + GL_STENCIL_PASS_DEPTH_FAIL = 0xB95, + GL_STENCIL_PASS_DEPTH_PASS = 0xB96, + GL_STENCIL_REF = 0xB97, + GL_STENCIL_WRITEMASK = 0xB98, + GL_MATRIX_MODE = 0xBA0, + GL_NORMALIZE = 0xBA1, + GL_VIEWPORT = 0xBA2, + GL_MODELVIEW_STACK_DEPTH = 0xBA3, + GL_PROJECTION_STACK_DEPTH = 0xBA4, + GL_TEXTURE_STACK_DEPTH = 0xBA5, + GL_MODELVIEW_MATRIX = 0xBA6, + GL_PROJECTION_MATRIX = 0xBA7, + GL_TEXTURE_MATRIX = 0xBA8, + GL_ATTRIB_STACK_DEPTH = 0xBB0, + GL_CLIENT_ATTRIB_STACK_DEPTH = 0xBB1, + GL_ALPHA_TEST = 0xBC0, + GL_ALPHA_TEST_FUNC = 0xBC1, + GL_ALPHA_TEST_REF = 0xBC2, + GL_DITHER = 0xBD0, + GL_BLEND_DST = 0xBE0, + GL_BLEND_SRC = 0xBE1, + GL_BLEND = 0xBE2, + GL_LOGIC_OP_MODE = 0xBF0, + GL_INDEX_LOGIC_OP = 0xBF1, + GL_LOGIC_OP = 0xBF1, + GL_COLOR_LOGIC_OP = 0xBF2, + GL_AUX_BUFFERS = 0xC00, + GL_DRAW_BUFFER = 0xC01, + GL_READ_BUFFER = 0xC02, + GL_SCISSOR_BOX = 0xC10, + GL_SCISSOR_TEST = 0xC11, + GL_INDEX_CLEAR_VALUE = 0xC20, + GL_INDEX_WRITEMASK = 0xC21, + GL_COLOR_CLEAR_VALUE = 0xC22, + GL_COLOR_WRITEMASK = 0xC23, + GL_INDEX_MODE = 0xC30, + GL_RGBA_MODE = 0xC31, + GL_DOUBLEBUFFER = 0xC32, + GL_STEREO = 0xC33, + GL_RENDER_MODE = 0xC40, + GL_PERSPECTIVE_CORRECTION_HINT = 0xC50, + GL_POINT_SMOOTH_HINT = 0xC51, + GL_LINE_SMOOTH_HINT = 0xC52, + GL_POLYGON_SMOOTH_HINT = 0xC53, + GL_FOG_HINT = 0xC54, + GL_TEXTURE_GEN_S = 0xC60, + GL_TEXTURE_GEN_T = 0xC61, + GL_TEXTURE_GEN_R = 0xC62, + GL_TEXTURE_GEN_Q = 0xC63, + GL_PIXEL_MAP_I_TO_I = 0xC70, + GL_PIXEL_MAP_S_TO_S = 0xC71, + GL_PIXEL_MAP_I_TO_R = 0xC72, + GL_PIXEL_MAP_I_TO_G = 0xC73, + GL_PIXEL_MAP_I_TO_B = 0xC74, + GL_PIXEL_MAP_I_TO_A = 0xC75, + GL_PIXEL_MAP_R_TO_R = 0xC76, + GL_PIXEL_MAP_G_TO_G = 0xC77, + GL_PIXEL_MAP_B_TO_B = 0xC78, + GL_PIXEL_MAP_A_TO_A = 0xC79, + GL_PIXEL_MAP_I_TO_I_SIZE = 0xCB0, + GL_PIXEL_MAP_S_TO_S_SIZE = 0xCB1, + GL_PIXEL_MAP_I_TO_R_SIZE = 0xCB2, + GL_PIXEL_MAP_I_TO_G_SIZE = 0xCB3, + GL_PIXEL_MAP_I_TO_B_SIZE = 0xCB4, + GL_PIXEL_MAP_I_TO_A_SIZE = 0xCB5, + GL_PIXEL_MAP_R_TO_R_SIZE = 0xCB6, + GL_PIXEL_MAP_G_TO_G_SIZE = 0xCB7, + GL_PIXEL_MAP_B_TO_B_SIZE = 0xCB8, + GL_PIXEL_MAP_A_TO_A_SIZE = 0xCB9, + GL_UNPACK_SWAP_BYTES = 0xCF0, + GL_UNPACK_LSB_FIRST = 0xCF1, + GL_UNPACK_ROW_LENGTH = 0xCF2, + GL_UNPACK_SKIP_ROWS = 0xCF3, + GL_UNPACK_SKIP_PIXELS = 0xCF4, + GL_UNPACK_ALIGNMENT = 0xCF5, + GL_PACK_SWAP_BYTES = 0xD00, + GL_PACK_LSB_FIRST = 0xD01, + GL_PACK_ROW_LENGTH = 0xD02, + GL_PACK_SKIP_ROWS = 0xD03, + GL_PACK_SKIP_PIXELS = 0xD04, + GL_PACK_ALIGNMENT = 0xD05, + GL_MAP_COLOR = 0xD10, + GL_MAP_STENCIL = 0xD11, + GL_INDEX_SHIFT = 0xD12, + GL_INDEX_OFFSET = 0xD13, + GL_RED_SCALE = 0xD14, + GL_RED_BIAS = 0xD15, + GL_ZOOM_X = 0xD16, + GL_ZOOM_Y = 0xD17, + GL_GREEN_SCALE = 0xD18, + GL_GREEN_BIAS = 0xD19, + GL_BLUE_SCALE = 0xD1A, + GL_BLUE_BIAS = 0xD1B, + GL_ALPHA_SCALE = 0xD1C, + GL_ALPHA_BIAS = 0xD1D, + GL_DEPTH_SCALE = 0xD1E, + GL_DEPTH_BIAS = 0xD1F, + GL_MAX_EVAL_ORDER = 0xD30, + GL_MAX_LIGHTS = 0xD31, + GL_MAX_CLIP_PLANES = 0xD32, + GL_MAX_TEXTURE_SIZE = 0xD33, + GL_MAX_PIXEL_MAP_TABLE = 0xD34, + GL_MAX_ATTRIB_STACK_DEPTH = 0xD35, + GL_MAX_MODELVIEW_STACK_DEPTH = 0xD36, + GL_MAX_NAME_STACK_DEPTH = 0xD37, + GL_MAX_PROJECTION_STACK_DEPTH = 0xD38, + GL_MAX_TEXTURE_STACK_DEPTH = 0xD39, + GL_MAX_VIEWPORT_DIMS = 0xD3A, + GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = 0xD3B, + GL_SUBPIXEL_BITS = 0xD50, + GL_INDEX_BITS = 0xD51, + GL_RED_BITS = 0xD52, + GL_GREEN_BITS = 0xD53, + GL_BLUE_BITS = 0xD54, + GL_ALPHA_BITS = 0xD55, + GL_DEPTH_BITS = 0xD56, + GL_STENCIL_BITS = 0xD57, + GL_ACCUM_RED_BITS = 0xD58, + GL_ACCUM_GREEN_BITS = 0xD59, + GL_ACCUM_BLUE_BITS = 0xD5A, + GL_ACCUM_ALPHA_BITS = 0xD5B, + GL_NAME_STACK_DEPTH = 0xD70, + GL_AUTO_NORMAL = 0xD80, + GL_MAP1_COLOR_4 = 0xD90, + GL_MAP1_INDEX = 0xD91, + GL_MAP1_NORMAL = 0xD92, + GL_MAP1_TEXTURE_COORD_1 = 0xD93, + GL_MAP1_TEXTURE_COORD_2 = 0xD94, + GL_MAP1_TEXTURE_COORD_3 = 0xD95, + GL_MAP1_TEXTURE_COORD_4 = 0xD96, + GL_MAP1_VERTEX_3 = 0xD97, + GL_MAP1_VERTEX_4 = 0xD98, + GL_MAP2_COLOR_4 = 0xDB0, + GL_MAP2_INDEX = 0xDB1, + GL_MAP2_NORMAL = 0xDB2, + GL_MAP2_TEXTURE_COORD_1 = 0xDB3, + GL_MAP2_TEXTURE_COORD_2 = 0xDB4, + GL_MAP2_TEXTURE_COORD_3 = 0xDB5, + GL_MAP2_TEXTURE_COORD_4 = 0xDB6, + GL_MAP2_VERTEX_3 = 0xDB7, + GL_MAP2_VERTEX_4 = 0xDB8, + GL_MAP1_GRID_DOMAIN = 0xDD0, + GL_MAP1_GRID_SEGMENTS = 0xDD1, + GL_MAP2_GRID_DOMAIN = 0xDD2, + GL_MAP2_GRID_SEGMENTS = 0xDD3, + GL_TEXTURE_1D = 0xDE0, + GL_TEXTURE_2D = 0xDE1, + GL_FEEDBACK_BUFFER_POINTER = 0xDF0, + GL_FEEDBACK_BUFFER_SIZE = 0xDF1, + GL_FEEDBACK_BUFFER_TYPE = 0xDF2, + GL_SELECTION_BUFFER_POINTER = 0xDF3, + GL_SELECTION_BUFFER_SIZE = 0xDF4; + + /** GetTextureParameter */ + public static final int + 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 = 0x1005; + + /** HintMode */ + public static final int + GL_DONT_CARE = 0x1100, + GL_FASTEST = 0x1101, + GL_NICEST = 0x1102; + + /** LightName */ + public static final int + GL_LIGHT0 = 0x4000, + GL_LIGHT1 = 0x4001, + GL_LIGHT2 = 0x4002, + GL_LIGHT3 = 0x4003, + GL_LIGHT4 = 0x4004, + GL_LIGHT5 = 0x4005, + GL_LIGHT6 = 0x4006, + GL_LIGHT7 = 0x4007; + + /** LightParameter */ + public static final int + 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; + + /** ListMode */ + public static final int + GL_COMPILE = 0x1300, + GL_COMPILE_AND_EXECUTE = 0x1301; + + /** LogicOp */ + public static final int + GL_CLEAR = 0x1500, + GL_AND = 0x1501, + GL_AND_REVERSE = 0x1502, + GL_COPY = 0x1503, + GL_AND_INVERTED = 0x1504, + GL_NOOP = 0x1505, + GL_XOR = 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; + + /** MaterialParameter */ + public static final int + GL_EMISSION = 0x1600, + GL_SHININESS = 0x1601, + GL_AMBIENT_AND_DIFFUSE = 0x1602, + GL_COLOR_INDEXES = 0x1603; + + /** MatrixMode */ + public static final int + GL_MODELVIEW = 0x1700, + GL_PROJECTION = 0x1701, + GL_TEXTURE = 0x1702; + + /** PixelCopyType */ + public static final int + GL_COLOR = 0x1800, + GL_DEPTH = 0x1801, + GL_STENCIL = 0x1802; + + /** PixelFormat */ + public static final int + GL_COLOR_INDEX = 0x1900, + GL_STENCIL_INDEX = 0x1901, + GL_DEPTH_COMPONENT = 0x1902, + GL_RED = 0x1903, + GL_GREEN = 0x1904, + GL_BLUE = 0x1905, + GL_ALPHA = 0x1906, + GL_RGB = 0x1907, + GL_RGBA = 0x1908, + GL_LUMINANCE = 0x1909, + GL_LUMINANCE_ALPHA = 0x190A; + + /** PixelType */ + public static final int GL_BITMAP = 0x1A00; + + /** PolygonMode */ + public static final int + GL_POINT = 0x1B00, + GL_LINE = 0x1B01, + GL_FILL = 0x1B02; + + /** RenderingMode */ + public static final int + GL_RENDER = 0x1C00, + GL_FEEDBACK = 0x1C01, + GL_SELECT = 0x1C02; + + /** ShadingModel */ + public static final int + GL_FLAT = 0x1D00, + GL_SMOOTH = 0x1D01; + + /** StencilOp */ + public static final int + GL_KEEP = 0x1E00, + GL_REPLACE = 0x1E01, + GL_INCR = 0x1E02, + GL_DECR = 0x1E03; + + /** StringName */ + public static final int + GL_VENDOR = 0x1F00, + GL_RENDERER = 0x1F01, + GL_VERSION = 0x1F02, + GL_EXTENSIONS = 0x1F03; + + /** TextureCoordName */ + public static final int + GL_S = 0x2000, + GL_T = 0x2001, + GL_R = 0x2002, + GL_Q = 0x2003; + + /** TextureEnvMode */ + public static final int + GL_MODULATE = 0x2100, + GL_DECAL = 0x2101; + + /** TextureEnvParameter */ + public static final int + GL_TEXTURE_ENV_MODE = 0x2200, + GL_TEXTURE_ENV_COLOR = 0x2201; + + /** TextureEnvTarget */ + public static final int GL_TEXTURE_ENV = 0x2300; + + /** TextureGenMode */ + public static final int + GL_EYE_LINEAR = 0x2400, + GL_OBJECT_LINEAR = 0x2401, + GL_SPHERE_MAP = 0x2402; + + /** TextureGenParameter */ + public static final int + GL_TEXTURE_GEN_MODE = 0x2500, + GL_OBJECT_PLANE = 0x2501, + GL_EYE_PLANE = 0x2502; + + /** TextureMagFilter */ + public static final int + GL_NEAREST = 0x2600, + GL_LINEAR = 0x2601; + + /** TextureMinFilter */ + public static final int + GL_NEAREST_MIPMAP_NEAREST = 0x2700, + GL_LINEAR_MIPMAP_NEAREST = 0x2701, + GL_NEAREST_MIPMAP_LINEAR = 0x2702, + GL_LINEAR_MIPMAP_LINEAR = 0x2703; + + /** TextureParameterName */ + public static final int + GL_TEXTURE_MAG_FILTER = 0x2800, + GL_TEXTURE_MIN_FILTER = 0x2801, + GL_TEXTURE_WRAP_S = 0x2802, + GL_TEXTURE_WRAP_T = 0x2803; + + /** TextureWrapMode */ + public static final int + GL_CLAMP = 0x2900, + GL_REPEAT = 0x2901; + + /** ClientAttribMask */ + public static final int + GL_CLIENT_PIXEL_STORE_BIT = 0x1, + GL_CLIENT_VERTEX_ARRAY_BIT = 0x2, + GL_CLIENT_ALL_ATTRIB_BITS = 0xFFFFFFFF; + + /** polygon_offset */ + public static final int + GL_POLYGON_OFFSET_FACTOR = 0x8038, + GL_POLYGON_OFFSET_UNITS = 0x2A00, + GL_POLYGON_OFFSET_POINT = 0x2A01, + GL_POLYGON_OFFSET_LINE = 0x2A02, + GL_POLYGON_OFFSET_FILL = 0x8037; + + /** texture */ + public static final int + GL_ALPHA4 = 0x803B, + GL_ALPHA8 = 0x803C, + GL_ALPHA12 = 0x803D, + GL_ALPHA16 = 0x803E, + GL_LUMINANCE4 = 0x803F, + GL_LUMINANCE8 = 0x8040, + GL_LUMINANCE12 = 0x8041, + GL_LUMINANCE16 = 0x8042, + GL_LUMINANCE4_ALPHA4 = 0x8043, + GL_LUMINANCE6_ALPHA2 = 0x8044, + GL_LUMINANCE8_ALPHA8 = 0x8045, + GL_LUMINANCE12_ALPHA4 = 0x8046, + GL_LUMINANCE12_ALPHA12 = 0x8047, + GL_LUMINANCE16_ALPHA16 = 0x8048, + GL_INTENSITY = 0x8049, + GL_INTENSITY4 = 0x804A, + GL_INTENSITY8 = 0x804B, + GL_INTENSITY12 = 0x804C, + GL_INTENSITY16 = 0x804D, + GL_R3_G3_B2 = 0x2A10, + GL_RGB4 = 0x804F, + GL_RGB5 = 0x8050, + GL_RGB8 = 0x8051, + GL_RGB10 = 0x8052, + GL_RGB12 = 0x8053, + GL_RGB16 = 0x8054, + GL_RGBA2 = 0x8055, + GL_RGBA4 = 0x8056, + GL_RGB5_A1 = 0x8057, + GL_RGBA8 = 0x8058, + GL_RGB10_A2 = 0x8059, + GL_RGBA12 = 0x805A, + GL_RGBA16 = 0x805B, + GL_TEXTURE_RED_SIZE = 0x805C, + GL_TEXTURE_GREEN_SIZE = 0x805D, + GL_TEXTURE_BLUE_SIZE = 0x805E, + GL_TEXTURE_ALPHA_SIZE = 0x805F, + GL_TEXTURE_LUMINANCE_SIZE = 0x8060, + GL_TEXTURE_INTENSITY_SIZE = 0x8061, + GL_PROXY_TEXTURE_1D = 0x8063, + GL_PROXY_TEXTURE_2D = 0x8064; + + /** texture_object */ + public static final int + GL_TEXTURE_PRIORITY = 0x8066, + GL_TEXTURE_RESIDENT = 0x8067, + GL_TEXTURE_BINDING_1D = 0x8068, + GL_TEXTURE_BINDING_2D = 0x8069; + + /** vertex_array */ + public static final int + GL_VERTEX_ARRAY = 0x8074, + GL_NORMAL_ARRAY = 0x8075, + GL_COLOR_ARRAY = 0x8076, + GL_INDEX_ARRAY = 0x8077, + GL_TEXTURE_COORD_ARRAY = 0x8078, + GL_EDGE_FLAG_ARRAY = 0x8079, + GL_VERTEX_ARRAY_SIZE = 0x807A, + GL_VERTEX_ARRAY_TYPE = 0x807B, + GL_VERTEX_ARRAY_STRIDE = 0x807C, + GL_NORMAL_ARRAY_TYPE = 0x807E, + GL_NORMAL_ARRAY_STRIDE = 0x807F, + GL_COLOR_ARRAY_SIZE = 0x8081, + GL_COLOR_ARRAY_TYPE = 0x8082, + GL_COLOR_ARRAY_STRIDE = 0x8083, + GL_INDEX_ARRAY_TYPE = 0x8085, + GL_INDEX_ARRAY_STRIDE = 0x8086, + GL_TEXTURE_COORD_ARRAY_SIZE = 0x8088, + GL_TEXTURE_COORD_ARRAY_TYPE = 0x8089, + GL_TEXTURE_COORD_ARRAY_STRIDE = 0x808A, + GL_EDGE_FLAG_ARRAY_STRIDE = 0x808C, + GL_VERTEX_ARRAY_POINTER = 0x808E, + GL_NORMAL_ARRAY_POINTER = 0x808F, + GL_COLOR_ARRAY_POINTER = 0x8090, + GL_INDEX_ARRAY_POINTER = 0x8091, + GL_TEXTURE_COORD_ARRAY_POINTER = 0x8092, + GL_EDGE_FLAG_ARRAY_POINTER = 0x8093, + 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; + + static { GL.initialize(); } + + protected GL11() { + throw new UnsupportedOperationException(); + } + + static boolean isAvailable(GLCapabilities caps, java.util.Set ext, boolean fc) { + return (fc || checkFunctions( + caps.glAccum, caps.glAlphaFunc, caps.glAreTexturesResident, caps.glArrayElement, caps.glBegin, caps.glBitmap, caps.glCallList, caps.glCallLists, + caps.glClearAccum, caps.glClearIndex, caps.glClipPlane, caps.glColor3b, caps.glColor3s, caps.glColor3i, caps.glColor3f, caps.glColor3d, + caps.glColor3ub, caps.glColor3us, caps.glColor3ui, caps.glColor3bv, caps.glColor3sv, caps.glColor3iv, caps.glColor3fv, caps.glColor3dv, + caps.glColor3ubv, caps.glColor3usv, caps.glColor3uiv, caps.glColor4b, caps.glColor4s, caps.glColor4i, caps.glColor4f, caps.glColor4d, + caps.glColor4ub, caps.glColor4us, caps.glColor4ui, caps.glColor4bv, caps.glColor4sv, caps.glColor4iv, caps.glColor4fv, caps.glColor4dv, + caps.glColor4ubv, caps.glColor4usv, caps.glColor4uiv, caps.glColorMaterial, caps.glColorPointer, caps.glCopyPixels, caps.glDeleteLists, + caps.glDrawPixels, caps.glEdgeFlag, caps.glEdgeFlagv, caps.glEdgeFlagPointer, caps.glEnd, caps.glEvalCoord1f, caps.glEvalCoord1fv, + caps.glEvalCoord1d, caps.glEvalCoord1dv, caps.glEvalCoord2f, caps.glEvalCoord2fv, caps.glEvalCoord2d, caps.glEvalCoord2dv, caps.glEvalMesh1, + caps.glEvalMesh2, caps.glEvalPoint1, caps.glEvalPoint2, caps.glFeedbackBuffer, caps.glFogi, caps.glFogiv, caps.glFogf, caps.glFogfv, + caps.glGenLists, caps.glGetClipPlane, caps.glGetLightiv, caps.glGetLightfv, caps.glGetMapiv, caps.glGetMapfv, caps.glGetMapdv, caps.glGetMaterialiv, + caps.glGetMaterialfv, caps.glGetPixelMapfv, caps.glGetPixelMapusv, caps.glGetPixelMapuiv, caps.glGetPolygonStipple, caps.glGetTexEnviv, + caps.glGetTexEnvfv, caps.glGetTexGeniv, caps.glGetTexGenfv, caps.glGetTexGendv, caps.glIndexi, caps.glIndexub, caps.glIndexs, caps.glIndexf, + caps.glIndexd, caps.glIndexiv, caps.glIndexubv, caps.glIndexsv, caps.glIndexfv, caps.glIndexdv, caps.glIndexMask, caps.glIndexPointer, + caps.glInitNames, caps.glInterleavedArrays, caps.glIsList, caps.glLightModeli, caps.glLightModelf, caps.glLightModeliv, caps.glLightModelfv, + caps.glLighti, caps.glLightf, caps.glLightiv, caps.glLightfv, caps.glLineStipple, caps.glListBase, caps.glLoadMatrixf, caps.glLoadMatrixd, + caps.glLoadIdentity, caps.glLoadName, caps.glMap1f, caps.glMap1d, caps.glMap2f, caps.glMap2d, caps.glMapGrid1f, caps.glMapGrid1d, caps.glMapGrid2f, + caps.glMapGrid2d, caps.glMateriali, caps.glMaterialf, caps.glMaterialiv, caps.glMaterialfv, caps.glMatrixMode, caps.glMultMatrixf, + caps.glMultMatrixd, caps.glFrustum, caps.glNewList, caps.glEndList, caps.glNormal3f, caps.glNormal3b, caps.glNormal3s, caps.glNormal3i, + caps.glNormal3d, caps.glNormal3fv, caps.glNormal3bv, caps.glNormal3sv, caps.glNormal3iv, caps.glNormal3dv, caps.glNormalPointer, caps.glOrtho, + caps.glPassThrough, caps.glPixelMapfv, caps.glPixelMapusv, caps.glPixelMapuiv, caps.glPixelTransferi, caps.glPixelTransferf, caps.glPixelZoom, + caps.glPolygonStipple, caps.glPushAttrib, caps.glPushClientAttrib, caps.glPopAttrib, caps.glPopClientAttrib, caps.glPopMatrix, caps.glPopName, + caps.glPrioritizeTextures, caps.glPushMatrix, caps.glPushName, caps.glRasterPos2i, caps.glRasterPos2s, caps.glRasterPos2f, caps.glRasterPos2d, + caps.glRasterPos2iv, caps.glRasterPos2sv, caps.glRasterPos2fv, caps.glRasterPos2dv, caps.glRasterPos3i, caps.glRasterPos3s, caps.glRasterPos3f, + caps.glRasterPos3d, caps.glRasterPos3iv, caps.glRasterPos3sv, caps.glRasterPos3fv, caps.glRasterPos3dv, caps.glRasterPos4i, caps.glRasterPos4s, + caps.glRasterPos4f, caps.glRasterPos4d, caps.glRasterPos4iv, caps.glRasterPos4sv, caps.glRasterPos4fv, caps.glRasterPos4dv, caps.glRecti, + caps.glRects, caps.glRectf, caps.glRectd, caps.glRectiv, caps.glRectsv, caps.glRectfv, caps.glRectdv, caps.glRenderMode, caps.glRotatef, + caps.glRotated, caps.glScalef, caps.glScaled, caps.glSelectBuffer, caps.glShadeModel, caps.glTexCoord1f, caps.glTexCoord1s, caps.glTexCoord1i, + caps.glTexCoord1d, caps.glTexCoord1fv, caps.glTexCoord1sv, caps.glTexCoord1iv, caps.glTexCoord1dv, caps.glTexCoord2f, caps.glTexCoord2s, + caps.glTexCoord2i, caps.glTexCoord2d, caps.glTexCoord2fv, caps.glTexCoord2sv, caps.glTexCoord2iv, caps.glTexCoord2dv, caps.glTexCoord3f, + caps.glTexCoord3s, caps.glTexCoord3i, caps.glTexCoord3d, caps.glTexCoord3fv, caps.glTexCoord3sv, caps.glTexCoord3iv, caps.glTexCoord3dv, + caps.glTexCoord4f, caps.glTexCoord4s, caps.glTexCoord4i, caps.glTexCoord4d, caps.glTexCoord4fv, caps.glTexCoord4sv, caps.glTexCoord4iv, + caps.glTexCoord4dv, caps.glTexCoordPointer, caps.glTexEnvi, caps.glTexEnviv, caps.glTexEnvf, caps.glTexEnvfv, caps.glTexGeni, caps.glTexGeniv, + caps.glTexGenf, caps.glTexGenfv, caps.glTexGend, caps.glTexGendv, caps.glTranslatef, caps.glTranslated, caps.glVertex2f, caps.glVertex2s, + caps.glVertex2i, caps.glVertex2d, caps.glVertex2fv, caps.glVertex2sv, caps.glVertex2iv, caps.glVertex2dv, caps.glVertex3f, caps.glVertex3s, + caps.glVertex3i, caps.glVertex3d, caps.glVertex3fv, caps.glVertex3sv, caps.glVertex3iv, caps.glVertex3dv, caps.glVertex4f, caps.glVertex4s, + caps.glVertex4i, caps.glVertex4d, caps.glVertex4fv, caps.glVertex4sv, caps.glVertex4iv, caps.glVertex4dv, caps.glVertexPointer + )) && checkFunctions( + caps.glEnable, caps.glDisable, caps.glBindTexture, caps.glBlendFunc, caps.glClear, caps.glClearColor, caps.glClearDepth, caps.glClearStencil, + caps.glColorMask, caps.glCullFace, caps.glDepthFunc, caps.glDepthMask, caps.glDepthRange, + ext.contains("GL_NV_vertex_buffer_unified_memory") ? caps.glDisableClientState : -1L, caps.glDrawArrays, caps.glDrawBuffer, caps.glDrawElements, + ext.contains("GL_NV_vertex_buffer_unified_memory") ? caps.glEnableClientState : -1L, caps.glFinish, caps.glFlush, caps.glFrontFace, + caps.glGenTextures, caps.glDeleteTextures, caps.glGetBooleanv, caps.glGetFloatv, caps.glGetIntegerv, caps.glGetDoublev, caps.glGetError, + caps.glGetPointerv, caps.glGetString, caps.glGetTexImage, caps.glGetTexLevelParameteriv, caps.glGetTexLevelParameterfv, caps.glGetTexParameteriv, + caps.glGetTexParameterfv, caps.glHint, caps.glIsEnabled, caps.glIsTexture, caps.glLineWidth, caps.glLogicOp, caps.glPixelStorei, caps.glPixelStoref, + caps.glPointSize, caps.glPolygonMode, caps.glPolygonOffset, caps.glReadBuffer, caps.glReadPixels, caps.glScissor, caps.glStencilFunc, + caps.glStencilMask, caps.glStencilOp, caps.glTexImage1D, caps.glTexImage2D, caps.glCopyTexImage1D, caps.glCopyTexImage2D, caps.glCopyTexSubImage1D, + caps.glCopyTexSubImage2D, caps.glTexParameteri, caps.glTexParameteriv, caps.glTexParameterf, caps.glTexParameterfv, caps.glTexSubImage1D, + caps.glTexSubImage2D, caps.glViewport + ); + } + + // --- [ glEnable ] --- + + /** + * Enables the specified OpenGL state. + * + * @param target the OpenGL state to enable + * + * @see Reference Page + */ + public static void glEnable(@NativeType("GLenum") int target) { + GL11C.glEnable(target); + } + + // --- [ glDisable ] --- + + /** + * Disables the specified OpenGL state. + * + * @param target the OpenGL state to disable + * + * @see Reference Page + */ + public static void glDisable(@NativeType("GLenum") int target) { + GL11C.glDisable(target); + } + + // --- [ glAccum ] --- + + /** + * Each portion of a pixel in the accumulation buffer consists of four values: one for each of R, G, B, and A. The accumulation buffer is controlled + * exclusively through the use of this method (except for clearing it). + * + * @param op a symbolic constant indicating an accumulation buffer operation + * @param value a floating-point value to be used in that operation. One of:
{@link #GL_ACCUM ACCUM}{@link #GL_LOAD LOAD}{@link #GL_RETURN RETURN}{@link #GL_MULT MULT}{@link #GL_ADD ADD}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glAccum(@NativeType("GLenum") int op, @NativeType("GLfloat") float value); + + // --- [ glAlphaFunc ] --- + + /** + * The alpha test discards a fragment conditionally based on the outcome of a comparison between the incoming fragment’s alpha value and a constant value. + * The comparison is enabled or disabled with the generic {@link #glEnable Enable} and {@link #glDisable Disable} commands using the symbolic constant {@link #GL_ALPHA_TEST ALPHA_TEST}. + * When disabled, it is as if the comparison always passes. The test is controlled with this method. + * + * @param func a symbolic constant indicating the alpha test function. One of:
{@link #GL_NEVER NEVER}{@link #GL_ALWAYS ALWAYS}{@link #GL_LESS LESS}{@link #GL_LEQUAL LEQUAL}{@link #GL_EQUAL EQUAL}{@link #GL_GEQUAL GEQUAL}{@link #GL_GREATER GREATER}{@link #GL_NOTEQUAL NOTEQUAL}
+ * @param ref a reference value clamped to the range [0, 1]. When performing the alpha test, the GL will convert the reference value to the same representation as the fragment's alpha value (floating-point or fixed-point). + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glAlphaFunc(@NativeType("GLenum") int func, @NativeType("GLfloat") float ref); + + // --- [ glAreTexturesResident ] --- + + /** + * Unsafe version of: {@link #glAreTexturesResident AreTexturesResident} + * + * @param n the number of texture objects in {@code textures} + */ + public static native boolean nglAreTexturesResident(int n, long textures, long residences); + + /** + * Returns {@link #GL_TRUE TRUE} if all of the texture objects named in textures are resident, or if the implementation does not distinguish a working set. If + * at least one of the texture objects named in textures is not resident, then {@link #GL_FALSE FALSE} is returned, and the residence of each texture object is + * returned in residences. Otherwise the contents of residences are not changed. + * + * @param textures an array of texture objects + * @param residences returns the residences of each texture object + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("GLboolean") + public static boolean glAreTexturesResident(@NativeType("GLuint const *") IntBuffer textures, @NativeType("GLboolean *") ByteBuffer residences) { + if (CHECKS) { + check(residences, textures.remaining()); + } + return nglAreTexturesResident(textures.remaining(), memAddress(textures), memAddress(residences)); + } + + /** + * Returns {@link #GL_TRUE TRUE} if all of the texture objects named in textures are resident, or if the implementation does not distinguish a working set. If + * at least one of the texture objects named in textures is not resident, then {@link #GL_FALSE FALSE} is returned, and the residence of each texture object is + * returned in residences. Otherwise the contents of residences are not changed. + * + * @param residences returns the residences of each texture object + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("GLboolean") + public static boolean glAreTexturesResident(@NativeType("GLuint const *") int texture, @NativeType("GLboolean *") ByteBuffer residences) { + if (CHECKS) { + check(residences, 1); + } + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer textures = stack.ints(texture); + return nglAreTexturesResident(1, memAddress(textures), memAddress(residences)); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glArrayElement ] --- + + /** + * Transfers the ith element of every enabled, non-instanced array, and the first element of every enabled, instanced array to the GL. + * + * @param i the element to transfer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glArrayElement(@NativeType("GLint") int i); + + // --- [ glBegin ] --- + + /** + * Begins the definition of vertex attributes of a sequence of primitives to be transferred to the GL. + * + * @param mode the primitive type being defined. One of:
{@link #GL_POINTS POINTS}{@link #GL_LINE_STRIP LINE_STRIP}{@link #GL_LINE_LOOP LINE_LOOP}{@link #GL_LINES LINES}{@link #GL_TRIANGLE_STRIP TRIANGLE_STRIP}{@link #GL_TRIANGLE_FAN TRIANGLE_FAN}{@link #GL_TRIANGLES TRIANGLES}
{@link GL32#GL_LINES_ADJACENCY LINES_ADJACENCY}{@link GL32#GL_LINE_STRIP_ADJACENCY LINE_STRIP_ADJACENCY}{@link GL32#GL_TRIANGLES_ADJACENCY TRIANGLES_ADJACENCY}{@link GL32#GL_TRIANGLE_STRIP_ADJACENCY TRIANGLE_STRIP_ADJACENCY}{@link GL40#GL_PATCHES PATCHES}{@link #GL_POLYGON POLYGON}{@link #GL_QUADS QUADS}
{@link #GL_QUAD_STRIP QUAD_STRIP}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glBegin(@NativeType("GLenum") int mode); + + // --- [ glBindTexture ] --- + + /** + * Binds the a texture to a texture target. + * + *

While a texture object is bound, GL operations on the target to which it is bound affect the bound object, and queries of the target to which it is + * bound return state from the bound object. If texture mapping of the dimensionality of the target to which a texture object is bound is enabled, the + * state of the bound texture object directs the texturing operation.

+ * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL40#GL_TEXTURE_CUBE_MAP_ARRAY TEXTURE_CUBE_MAP_ARRAY}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL32#GL_TEXTURE_2D_MULTISAMPLE TEXTURE_2D_MULTISAMPLE}
{@link GL32#GL_TEXTURE_2D_MULTISAMPLE_ARRAY TEXTURE_2D_MULTISAMPLE_ARRAY}
+ * @param texture the texture object to bind + * + * @see Reference Page + */ + public static void glBindTexture(@NativeType("GLenum") int target, @NativeType("GLuint") int texture) { + GL11C.glBindTexture(target, texture); + } + + // --- [ glBitmap ] --- + + /** Unsafe version of: {@link #glBitmap Bitmap} */ + public static native void nglBitmap(int w, int h, float xOrig, float yOrig, float xInc, float yInc, long data); + + /** + * Sents a bitmap to the GL. Bitmaps are rectangles of zeros and ones specifying a particular pattern of fragments to be produced. Each of these fragments + * has the same associated data. These data are those associated with the current raster position. + * + * @param w the bitmap width + * @param h the bitmap width + * @param xOrig the bitmap origin x coordinate + * @param yOrig the bitmap origin y coordinate + * @param xInc the x increment added to the raster position + * @param yInc the y increment added to the raster position + * @param data the buffer containing the bitmap data. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glBitmap(@NativeType("GLsizei") int w, @NativeType("GLsizei") int h, @NativeType("GLfloat") float xOrig, @NativeType("GLfloat") float yOrig, @NativeType("GLfloat") float xInc, @NativeType("GLfloat") float yInc, @Nullable @NativeType("GLubyte const *") ByteBuffer data) { + if (CHECKS) { + checkSafe(data, ((w + 7) >> 3) * h); + } + nglBitmap(w, h, xOrig, yOrig, xInc, yInc, memAddressSafe(data)); + } + + /** + * Sents a bitmap to the GL. Bitmaps are rectangles of zeros and ones specifying a particular pattern of fragments to be produced. Each of these fragments + * has the same associated data. These data are those associated with the current raster position. + * + * @param w the bitmap width + * @param h the bitmap width + * @param xOrig the bitmap origin x coordinate + * @param yOrig the bitmap origin y coordinate + * @param xInc the x increment added to the raster position + * @param yInc the y increment added to the raster position + * @param data the buffer containing the bitmap data. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glBitmap(@NativeType("GLsizei") int w, @NativeType("GLsizei") int h, @NativeType("GLfloat") float xOrig, @NativeType("GLfloat") float yOrig, @NativeType("GLfloat") float xInc, @NativeType("GLfloat") float yInc, @Nullable @NativeType("GLubyte const *") long data) { + nglBitmap(w, h, xOrig, yOrig, xInc, yInc, data); + } + + // --- [ glBlendFunc ] --- + + /** + * Specifies the weighting factors used by the blend equation, for both RGB and alpha functions and for all draw buffers. + * + * @param sfactor the source weighting factor. One of:
{@link GL11C#GL_ZERO ZERO}{@link GL11C#GL_ONE ONE}{@link GL11C#GL_SRC_COLOR SRC_COLOR}{@link GL11C#GL_ONE_MINUS_SRC_COLOR ONE_MINUS_SRC_COLOR}{@link GL11C#GL_DST_COLOR DST_COLOR}
{@link GL11C#GL_ONE_MINUS_DST_COLOR ONE_MINUS_DST_COLOR}{@link GL11C#GL_SRC_ALPHA SRC_ALPHA}{@link GL11C#GL_ONE_MINUS_SRC_ALPHA ONE_MINUS_SRC_ALPHA}{@link GL11C#GL_DST_ALPHA DST_ALPHA}{@link GL11C#GL_ONE_MINUS_DST_ALPHA ONE_MINUS_DST_ALPHA}
{@link GL14#GL_CONSTANT_COLOR CONSTANT_COLOR}{@link GL14#GL_ONE_MINUS_CONSTANT_COLOR ONE_MINUS_CONSTANT_COLOR}{@link GL14#GL_CONSTANT_ALPHA CONSTANT_ALPHA}{@link GL14#GL_ONE_MINUS_CONSTANT_ALPHA ONE_MINUS_CONSTANT_ALPHA}{@link GL11C#GL_SRC_ALPHA_SATURATE SRC_ALPHA_SATURATE}
{@link GL33#GL_SRC1_COLOR SRC1_COLOR}{@link GL33#GL_ONE_MINUS_SRC1_COLOR ONE_MINUS_SRC1_COLOR}{@link GL15#GL_SRC1_ALPHA SRC1_ALPHA}{@link GL33#GL_ONE_MINUS_SRC1_ALPHA ONE_MINUS_SRC1_ALPHA}
+ * @param dfactor the destination weighting factor + * + * @see Reference Page + */ + public static void glBlendFunc(@NativeType("GLenum") int sfactor, @NativeType("GLenum") int dfactor) { + GL11C.glBlendFunc(sfactor, dfactor); + } + + // --- [ glCallList ] --- + + /** + * Executes a display list. Causes the commands saved in the display list to be executed, in order, just as if they were issued without using a display list. + * + * @param list the index of the display list to be called + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glCallList(@NativeType("GLuint") int list); + + // --- [ glCallLists ] --- + + /** + * Unsafe version of: {@link #glCallLists CallLists} + * + * @param n the number of display lists to be called + * @param type the data type of each element in {@code lists}. One of:
{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_INT INT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link #GL_FLOAT FLOAT}{@link #GL_2_BYTES 2_BYTES}{@link #GL_3_BYTES 3_BYTES}{@link #GL_4_BYTES 4_BYTES}
+ */ + public static native void nglCallLists(int n, int type, long lists); + + /** + * Provides an efficient means for executing a number of display lists. + * + * @param type the data type of each element in {@code lists}. One of:
{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_INT INT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link #GL_FLOAT FLOAT}{@link #GL_2_BYTES 2_BYTES}{@link #GL_3_BYTES 3_BYTES}{@link #GL_4_BYTES 4_BYTES}
+ * @param lists an array of offsets. Each offset is added to the display list base to obtain the display list number. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glCallLists(@NativeType("GLenum") int type, @NativeType("void const *") ByteBuffer lists) { + nglCallLists(lists.remaining() / GLChecks.typeToBytes(type), type, memAddress(lists)); + } + + /** + * Provides an efficient means for executing a number of display lists. + * + * @param lists an array of offsets. Each offset is added to the display list base to obtain the display list number. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glCallLists(@NativeType("void const *") ByteBuffer lists) { + nglCallLists(lists.remaining(), GL11.GL_UNSIGNED_BYTE, memAddress(lists)); + } + + /** + * Provides an efficient means for executing a number of display lists. + * + * @param lists an array of offsets. Each offset is added to the display list base to obtain the display list number. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glCallLists(@NativeType("void const *") ShortBuffer lists) { + nglCallLists(lists.remaining(), GL11.GL_UNSIGNED_SHORT, memAddress(lists)); + } + + /** + * Provides an efficient means for executing a number of display lists. + * + * @param lists an array of offsets. Each offset is added to the display list base to obtain the display list number. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glCallLists(@NativeType("void const *") IntBuffer lists) { + nglCallLists(lists.remaining(), GL11.GL_UNSIGNED_INT, memAddress(lists)); + } + + // --- [ glClear ] --- + + /** + * Sets portions of every pixel in a particular buffer to the same value. The value to which each buffer is cleared depends on the setting of the clear + * value for that buffer. + * + * @param mask Zero or the bitwise OR of one or more values indicating which buffers are to be cleared. One or more of:
{@link GL11C#GL_COLOR_BUFFER_BIT COLOR_BUFFER_BIT}{@link GL11C#GL_DEPTH_BUFFER_BIT DEPTH_BUFFER_BIT}{@link GL11C#GL_STENCIL_BUFFER_BIT STENCIL_BUFFER_BIT}
+ * + * @see Reference Page + */ + public static void glClear(@NativeType("GLbitfield") int mask) { + GL11C.glClear(mask); + } + + // --- [ glClearAccum ] --- + + /** + * Sets the clear values for the accumulation buffer. These values are clamped to the range [-1,1] when they are specified. + * + * @param red the value to which to clear the R values of the accumulation buffer + * @param green the value to which to clear the G values of the accumulation buffer + * @param blue the value to which to clear the B values of the accumulation buffer + * @param alpha the value to which to clear the A values of the accumulation buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glClearAccum(@NativeType("GLfloat") float red, @NativeType("GLfloat") float green, @NativeType("GLfloat") float blue, @NativeType("GLfloat") float alpha); + + // --- [ glClearColor ] --- + + /** + * Sets the clear value for fixed-point and floating-point color buffers in RGBA mode. The specified components are stored as floating-point values. + * + * @param red the value to which to clear the R channel of the color buffer + * @param green the value to which to clear the G channel of the color buffer + * @param blue the value to which to clear the B channel of the color buffer + * @param alpha the value to which to clear the A channel of the color buffer + * + * @see Reference Page + */ + public static void glClearColor(@NativeType("GLfloat") float red, @NativeType("GLfloat") float green, @NativeType("GLfloat") float blue, @NativeType("GLfloat") float alpha) { + GL11C.glClearColor(red, green, blue, alpha); + } + + // --- [ glClearDepth ] --- + + /** + * Sets the depth value used when clearing the depth buffer. When clearing a fixedpoint depth buffer, {@code depth} is clamped to the range [0,1] and + * converted to fixed-point. No conversion is applied when clearing a floating-point depth buffer. + * + * @param depth the value to which to clear the depth buffer + * + * @see Reference Page + */ + public static void glClearDepth(@NativeType("GLdouble") double depth) { + GL11C.glClearDepth(depth); + } + + // --- [ glClearIndex ] --- + + /** + * sets the clear color index. index is converted to a fixed-point value with unspecified precision to the left of the binary point; the integer part of + * this value is then masked with 2m – 1, where {@code m} is the number of bits in a color index value stored in the + * framebuffer. + * + * @param index the value to which to clear the color buffer in color index mode + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glClearIndex(@NativeType("GLfloat") float index); + + // --- [ glClearStencil ] --- + + /** + * Sets the value to which to clear the stencil buffer. {@code s} is masked to the number of bitplanes in the stencil buffer. + * + * @param s the value to which to clear the stencil buffer + * + * @see Reference Page + */ + public static void glClearStencil(@NativeType("GLint") int s) { + GL11C.glClearStencil(s); + } + + // --- [ glClipPlane ] --- + + /** Unsafe version of: {@link #glClipPlane ClipPlane} */ + public static native void nglClipPlane(int plane, long equation); + + /** + * Specifies a client-defined clip plane. + * + *

The value of the first argument, {@code plane}, is a symbolic constant, CLIP_PLANEi, where i is an integer between 0 and n – 1, indicating one of + * n client-defined clip planes. {@code equation} is an array of four double-precision floating-point values. These are the coefficients of a plane + * equation in object coordinates: p1, p2, p3, and p4 (in that order).

+ * + * @param plane the clip plane to define + * @param equation the clip plane coefficients + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glClipPlane(@NativeType("GLenum") int plane, @NativeType("GLdouble const *") DoubleBuffer equation) { + if (CHECKS) { + check(equation, 4); + } + nglClipPlane(plane, memAddress(equation)); + } + + // --- [ glColor3b ] --- + + /** + * Sets the R, G, and B components of the current color. The alpha component is set to 1.0. + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3b(@NativeType("GLbyte") byte red, @NativeType("GLbyte") byte green, @NativeType("GLbyte") byte blue); + + // --- [ glColor3s ] --- + + /** + * Short version of {@link #glColor3b Color3b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3s(@NativeType("GLshort") short red, @NativeType("GLshort") short green, @NativeType("GLshort") short blue); + + // --- [ glColor3i ] --- + + /** + * Integer version of {@link #glColor3b Color3b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3i(@NativeType("GLint") int red, @NativeType("GLint") int green, @NativeType("GLint") int blue); + + // --- [ glColor3f ] --- + + /** + * Float version of {@link #glColor3b Color3b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3f(@NativeType("GLfloat") float red, @NativeType("GLfloat") float green, @NativeType("GLfloat") float blue); + + // --- [ glColor3d ] --- + + /** + * Double version of {@link #glColor3b Color3b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3d(@NativeType("GLdouble") double red, @NativeType("GLdouble") double green, @NativeType("GLdouble") double blue); + + // --- [ glColor3ub ] --- + + /** + * Unsigned version of {@link #glColor3b Color3b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3ub(@NativeType("GLubyte") byte red, @NativeType("GLubyte") byte green, @NativeType("GLubyte") byte blue); + + // --- [ glColor3us ] --- + + /** + * Unsigned short version of {@link #glColor3b Color3b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3us(@NativeType("GLushort") short red, @NativeType("GLushort") short green, @NativeType("GLushort") short blue); + + // --- [ glColor3ui ] --- + + /** + * Unsigned int version of {@link #glColor3b Color3b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor3ui(@NativeType("GLint") int red, @NativeType("GLint") int green, @NativeType("GLint") int blue); + + // --- [ glColor3bv ] --- + + /** Unsafe version of: {@link #glColor3bv Color3bv} */ + public static native void nglColor3bv(long v); + + /** + * Byte pointer version of {@link #glColor3b Color3b}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3bv(@NativeType("GLbyte const *") ByteBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3bv(memAddress(v)); + } + + // --- [ glColor3sv ] --- + + /** Unsafe version of: {@link #glColor3sv Color3sv} */ + public static native void nglColor3sv(long v); + + /** + * Pointer version of {@link #glColor3s Color3s}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3sv(@NativeType("GLshort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3sv(memAddress(v)); + } + + // --- [ glColor3iv ] --- + + /** Unsafe version of: {@link #glColor3iv Color3iv} */ + public static native void nglColor3iv(long v); + + /** + * Pointer version of {@link #glColor3i Color3i}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3iv(@NativeType("GLint const *") IntBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3iv(memAddress(v)); + } + + // --- [ glColor3fv ] --- + + /** Unsafe version of: {@link #glColor3fv Color3fv} */ + public static native void nglColor3fv(long v); + + /** + * Pointer version of {@link #glColor3f Color3f}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3fv(@NativeType("GLfloat const *") FloatBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3fv(memAddress(v)); + } + + // --- [ glColor3dv ] --- + + /** Unsafe version of: {@link #glColor3dv Color3dv} */ + public static native void nglColor3dv(long v); + + /** + * Pointer version of {@link #glColor3d Color3d}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3dv(@NativeType("GLdouble const *") DoubleBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3dv(memAddress(v)); + } + + // --- [ glColor3ubv ] --- + + /** Unsafe version of: {@link #glColor3ubv Color3ubv} */ + public static native void nglColor3ubv(long v); + + /** + * Pointer version of {@link #glColor3ub Color3ub}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3ubv(@NativeType("GLubyte const *") ByteBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3ubv(memAddress(v)); + } + + // --- [ glColor3usv ] --- + + /** Unsafe version of: {@link #glColor3usv Color3usv} */ + public static native void nglColor3usv(long v); + + /** + * Pointer version of {@link #glColor3us Color3us}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3usv(@NativeType("GLushort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3usv(memAddress(v)); + } + + // --- [ glColor3uiv ] --- + + /** Unsafe version of: {@link #glColor3uiv Color3uiv} */ + public static native void nglColor3uiv(long v); + + /** + * Pointer version of {@link #glColor3ui Color3ui}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3uiv(@NativeType("GLuint const *") IntBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglColor3uiv(memAddress(v)); + } + + // --- [ glColor4b ] --- + + /** + * Sets the current color. + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4b(@NativeType("GLbyte") byte red, @NativeType("GLbyte") byte green, @NativeType("GLbyte") byte blue, @NativeType("GLbyte") byte alpha); + + // --- [ glColor4s ] --- + + /** + * Short version of {@link #glColor4b Color4b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4s(@NativeType("GLshort") short red, @NativeType("GLshort") short green, @NativeType("GLshort") short blue, @NativeType("GLshort") short alpha); + + // --- [ glColor4i ] --- + + /** + * Integer version of {@link #glColor4b Color4b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4i(@NativeType("GLint") int red, @NativeType("GLint") int green, @NativeType("GLint") int blue, @NativeType("GLint") int alpha); + + // --- [ glColor4f ] --- + + /** + * Float version of {@link #glColor4b Color4b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4f(@NativeType("GLfloat") float red, @NativeType("GLfloat") float green, @NativeType("GLfloat") float blue, @NativeType("GLfloat") float alpha); + + // --- [ glColor4d ] --- + + /** + * Double version of {@link #glColor4b Color4b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4d(@NativeType("GLdouble") double red, @NativeType("GLdouble") double green, @NativeType("GLdouble") double blue, @NativeType("GLdouble") double alpha); + + // --- [ glColor4ub ] --- + + /** + * Unsigned version of {@link #glColor4b Color4b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4ub(@NativeType("GLubyte") byte red, @NativeType("GLubyte") byte green, @NativeType("GLubyte") byte blue, @NativeType("GLubyte") byte alpha); + + // --- [ glColor4us ] --- + + /** + * Unsigned short version of {@link #glColor4b Color4b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4us(@NativeType("GLushort") short red, @NativeType("GLushort") short green, @NativeType("GLushort") short blue, @NativeType("GLushort") short alpha); + + // --- [ glColor4ui ] --- + + /** + * Unsigned int version of {@link #glColor4b Color4b} + * + * @param red the red component of the current color + * @param green the green component of the current color + * @param blue the blue component of the current color + * @param alpha the alpha component of the current color + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColor4ui(@NativeType("GLint") int red, @NativeType("GLint") int green, @NativeType("GLint") int blue, @NativeType("GLint") int alpha); + + // --- [ glColor4bv ] --- + + /** Unsafe version of: {@link #glColor4bv Color4bv} */ + public static native void nglColor4bv(long v); + + /** + * Pointer version of {@link #glColor4b Color4b}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4bv(@NativeType("GLbyte const *") ByteBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4bv(memAddress(v)); + } + + // --- [ glColor4sv ] --- + + /** Unsafe version of: {@link #glColor4sv Color4sv} */ + public static native void nglColor4sv(long v); + + /** + * Pointer version of {@link #glColor4s Color4s}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4sv(@NativeType("GLshort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4sv(memAddress(v)); + } + + // --- [ glColor4iv ] --- + + /** Unsafe version of: {@link #glColor4iv Color4iv} */ + public static native void nglColor4iv(long v); + + /** + * Pointer version of {@link #glColor4i Color4i}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4iv(@NativeType("GLint const *") IntBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4iv(memAddress(v)); + } + + // --- [ glColor4fv ] --- + + /** Unsafe version of: {@link #glColor4fv Color4fv} */ + public static native void nglColor4fv(long v); + + /** + * Pointer version of {@link #glColor4f Color4f}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4fv(@NativeType("GLfloat const *") FloatBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4fv(memAddress(v)); + } + + // --- [ glColor4dv ] --- + + /** Unsafe version of: {@link #glColor4dv Color4dv} */ + public static native void nglColor4dv(long v); + + /** + * Pointer version of {@link #glColor4d Color4d}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4dv(@NativeType("GLdouble const *") DoubleBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4dv(memAddress(v)); + } + + // --- [ glColor4ubv ] --- + + /** Unsafe version of: {@link #glColor4ubv Color4ubv} */ + public static native void nglColor4ubv(long v); + + /** + * Pointer version of {@link #glColor4ub Color4ub}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4ubv(@NativeType("GLubyte const *") ByteBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4ubv(memAddress(v)); + } + + // --- [ glColor4usv ] --- + + /** Unsafe version of: {@link #glColor4usv Color4usv} */ + public static native void nglColor4usv(long v); + + /** + * Pointer version of {@link #glColor4us Color4us}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4usv(@NativeType("GLushort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4usv(memAddress(v)); + } + + // --- [ glColor4uiv ] --- + + /** Unsafe version of: {@link #glColor4uiv Color4uiv} */ + public static native void nglColor4uiv(long v); + + /** + * Pointer version of {@link #glColor4ui Color4ui}. + * + * @param v the color buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4uiv(@NativeType("GLuint const *") IntBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglColor4uiv(memAddress(v)); + } + + // --- [ glColorMask ] --- + + /** + * Masks the writing of R, G, B and A values to all draw buffers. In the initial state, all color values are enabled for writing for all draw buffers. + * + * @param red whether R values are written or not + * @param green whether G values are written or not + * @param blue whether B values are written or not + * @param alpha whether A values are written or not + * + * @see Reference Page + */ + public static void glColorMask(@NativeType("GLboolean") boolean red, @NativeType("GLboolean") boolean green, @NativeType("GLboolean") boolean blue, @NativeType("GLboolean") boolean alpha) { + GL11C.glColorMask(red, green, blue, alpha); + } + + // --- [ glColorMaterial ] --- + + /** + * It is possible to attach one or more material properties to the current color, so that they continuously track its component values. This behavior is + * enabled and disabled by calling {@link #glEnable Enable} or {@link #glDisable Disable} with the symbolic value {@link #GL_COLOR_MATERIAL COLOR_MATERIAL}. This function controls which + * of these modes is selected. + * + * @param face specifies which material face is affected by the current color. One of:
{@link #GL_FRONT FRONT}{@link #GL_BACK BACK}{@link #GL_FRONT_AND_BACK FRONT_AND_BACK}
+ * @param mode specifies which material property or properties track the current color. One of:
{@link #GL_EMISSION EMISSION}{@link #GL_AMBIENT AMBIENT}{@link #GL_DIFFUSE DIFFUSE}{@link #GL_SPECULAR SPECULAR}{@link #GL_AMBIENT_AND_DIFFUSE AMBIENT_AND_DIFFUSE}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glColorMaterial(@NativeType("GLenum") int face, @NativeType("GLenum") int mode); + + // --- [ glColorPointer ] --- + + /** Unsafe version of: {@link #glColorPointer ColorPointer} */ + public static native void nglColorPointer(int size, int type, int stride, long pointer); + + /** + * Specifies the location and organization of a color array. + * + * @param size the number of values per vertex that are stored in the array, as well as their component ordering. One of:
34{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_INT INT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}
{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColorPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + nglColorPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a color array. + * + * @param size the number of values per vertex that are stored in the array, as well as their component ordering. One of:
34{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_INT INT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}
{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColorPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") long pointer) { + nglColorPointer(size, type, stride, pointer); + } + + /** + * Specifies the location and organization of a color array. + * + * @param size the number of values per vertex that are stored in the array, as well as their component ordering. One of:
34{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_INT INT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}
{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColorPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ShortBuffer pointer) { + nglColorPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a color array. + * + * @param size the number of values per vertex that are stored in the array, as well as their component ordering. One of:
34{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_INT INT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}
{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColorPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") IntBuffer pointer) { + nglColorPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a color array. + * + * @param size the number of values per vertex that are stored in the array, as well as their component ordering. One of:
34{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_INT INT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}
{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColorPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") FloatBuffer pointer) { + nglColorPointer(size, type, stride, memAddress(pointer)); + } + + // --- [ glCopyPixels ] --- + + /** + * Transfers a rectangle of pixel values from one region of the read framebuffer to another in the draw framebuffer + * + * @param x the left framebuffer pixel coordinate + * @param y the lower framebuffer pixel coordinate + * @param width the rectangle width + * @param height the rectangle height + * @param type Indicates the type of values to be transfered. One of:
{@link #GL_COLOR COLOR}{@link #GL_STENCIL STENCIL}{@link #GL_DEPTH DEPTH}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glCopyPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int type); + + // --- [ glCullFace ] --- + + /** + * Specifies which polygon faces are culled if {@link GL11C#GL_CULL_FACE CULL_FACE} is enabled. Front-facing polygons are rasterized if either culling is disabled or the + * CullFace mode is {@link GL11C#GL_BACK BACK} while back-facing polygons are rasterized only if either culling is disabled or the CullFace mode is + * {@link GL11C#GL_FRONT FRONT}. The initial setting of the CullFace mode is {@link GL11C#GL_BACK BACK}. Initially, culling is disabled. + * + * @param mode the CullFace mode. One of:
{@link GL11C#GL_FRONT FRONT}{@link GL11C#GL_BACK BACK}{@link GL11C#GL_FRONT_AND_BACK FRONT_AND_BACK}
+ * + * @see Reference Page + */ + public static void glCullFace(@NativeType("GLenum") int mode) { + GL11C.glCullFace(mode); + } + + // --- [ glDeleteLists ] --- + + /** + * Deletes a contiguous group of display lists. All information about the display lists is lost, and the indices become unused. Indices to which no display + * list corresponds are ignored. If {@code range} is zero, nothing happens. + * + * @param list the index of the first display list to be deleted + * @param range the number of display lists to be deleted + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glDeleteLists(@NativeType("GLuint") int list, @NativeType("GLsizei") int range); + + // --- [ glDepthFunc ] --- + + /** + * Specifies the comparison that takes place during the depth buffer test (when {@link GL11C#GL_DEPTH_TEST DEPTH_TEST} is enabled). + * + * @param func the depth test comparison. One of:
{@link GL11C#GL_NEVER NEVER}{@link GL11C#GL_ALWAYS ALWAYS}{@link GL11C#GL_LESS LESS}{@link GL11C#GL_LEQUAL LEQUAL}{@link GL11C#GL_EQUAL EQUAL}{@link GL11C#GL_GREATER GREATER}{@link GL11C#GL_GEQUAL GEQUAL}{@link GL11C#GL_NOTEQUAL NOTEQUAL}
+ * + * @see Reference Page + */ + public static void glDepthFunc(@NativeType("GLenum") int func) { + GL11C.glDepthFunc(func); + } + + // --- [ glDepthMask ] --- + + /** + * Masks the writing of depth values to the depth buffer. In the initial state, the depth buffer is enabled for writing. + * + * @param flag whether depth values are written or not. + * + * @see Reference Page + */ + public static void glDepthMask(@NativeType("GLboolean") boolean flag) { + GL11C.glDepthMask(flag); + } + + // --- [ glDepthRange ] --- + + /** + * Sets the depth range for all viewports to the same values. + * + * @param zNear the near depth range + * @param zFar the far depth range + * + * @see Reference Page + */ + public static void glDepthRange(@NativeType("GLdouble") double zNear, @NativeType("GLdouble") double zFar) { + GL11C.glDepthRange(zNear, zFar); + } + + // --- [ glDisableClientState ] --- + + /** + * Disables a client-side capability. + * + *

If the {@link NVVertexBufferUnifiedMemory} extension is supported, this function is available even in a core profile context.

+ * + * @param cap the capability to disable. One of:
{@link #GL_COLOR_ARRAY COLOR_ARRAY}{@link #GL_EDGE_FLAG_ARRAY EDGE_FLAG_ARRAY}{@link GL15#GL_FOG_COORD_ARRAY FOG_COORD_ARRAY}{@link #GL_INDEX_ARRAY INDEX_ARRAY}
{@link #GL_NORMAL_ARRAY NORMAL_ARRAY}{@link GL14#GL_SECONDARY_COLOR_ARRAY SECONDARY_COLOR_ARRAY}{@link #GL_TEXTURE_COORD_ARRAY TEXTURE_COORD_ARRAY}{@link #GL_VERTEX_ARRAY VERTEX_ARRAY}
{@link NVVertexBufferUnifiedMemory#GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV VERTEX_ATTRIB_ARRAY_UNIFIED_NV}{@link NVVertexBufferUnifiedMemory#GL_ELEMENT_ARRAY_UNIFIED_NV ELEMENT_ARRAY_UNIFIED_NV}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glDisableClientState(@NativeType("GLenum") int cap); + + // --- [ glDrawArrays ] --- + + /** + * Constructs a sequence of geometric primitives by successively transferring elements for {@code count} vertices. Elements {@code first} through + * first + count – 1 of each enabled non-instanced array are transferred to the GL. + * + *

If an array corresponding to an attribute required by a vertex shader is not enabled, then the corresponding element is taken from the current attribute + * state. If an array is enabled, the corresponding current vertex attribute value is unaffected by the execution of this function.

+ * + * @param mode the kind of primitives being constructed + * @param first the first vertex to transfer to the GL + * @param count the number of vertices after {@code first} to transfer to the GL + * + * @see Reference Page + */ + public static void glDrawArrays(@NativeType("GLenum") int mode, @NativeType("GLint") int first, @NativeType("GLsizei") int count) { + GL11C.glDrawArrays(mode, first, count); + } + + // --- [ glDrawBuffer ] --- + + /** + * Defines the color buffer to which fragment color zero is written. + * + *

Acceptable values for {@code buf} depend on whether the GL is using the default framebuffer (i.e., {@link GL30#GL_DRAW_FRAMEBUFFER_BINDING DRAW_FRAMEBUFFER_BINDING} is zero), or + * a framebuffer object (i.e., {@link GL30#GL_DRAW_FRAMEBUFFER_BINDING DRAW_FRAMEBUFFER_BINDING} is non-zero). In the initial state, the GL is bound to the default framebuffer.

+ * + * @param buf the color buffer to draw to. One of:
{@link GL11C#GL_NONE NONE}{@link GL11C#GL_FRONT_LEFT FRONT_LEFT}{@link GL11C#GL_FRONT_RIGHT FRONT_RIGHT}{@link GL11C#GL_BACK_LEFT BACK_LEFT}{@link GL11C#GL_BACK_RIGHT BACK_RIGHT}{@link GL11C#GL_FRONT FRONT}{@link GL11C#GL_BACK BACK}{@link GL11C#GL_LEFT LEFT}
{@link GL11C#GL_RIGHT RIGHT}{@link GL11C#GL_FRONT_AND_BACK FRONT_AND_BACK}{@link GL30#GL_COLOR_ATTACHMENT0 COLOR_ATTACHMENT0}GL30.GL_COLOR_ATTACHMENT[1-15]
+ * + * @see Reference Page + */ + public static void glDrawBuffer(@NativeType("GLenum") int buf) { + GL11C.glDrawBuffer(buf); + } + + // --- [ glDrawElements ] --- + + /** + * Unsafe version of: {@link #glDrawElements DrawElements} + * + * @param count the number of vertices to transfer to the GL + * @param type indicates the type of index values in {@code indices}. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_UNSIGNED_INT UNSIGNED_INT}
+ */ + public static void nglDrawElements(int mode, int count, int type, long indices) { + GL11C.nglDrawElements(mode, count, type, indices); + } + + /** + * Constructs a sequence of geometric primitives by successively transferring elements for {@code count} vertices to the GL. + * The ith element transferred by {@code DrawElements} will be taken from element {@code indices[i]} (if no element array buffer is bound), or + * from the element whose index is stored in the currently bound element array buffer at offset {@code indices + i}. + * + * @param mode the kind of primitives being constructed. One of:
{@link GL11C#GL_POINTS POINTS}{@link GL11C#GL_LINE_STRIP LINE_STRIP}{@link GL11C#GL_LINE_LOOP LINE_LOOP}{@link GL11C#GL_LINES LINES}{@link GL11C#GL_TRIANGLE_STRIP TRIANGLE_STRIP}{@link GL11C#GL_TRIANGLE_FAN TRIANGLE_FAN}
{@link GL11C#GL_TRIANGLES TRIANGLES}{@link GL32#GL_LINES_ADJACENCY LINES_ADJACENCY}{@link GL32#GL_LINE_STRIP_ADJACENCY LINE_STRIP_ADJACENCY}{@link GL32#GL_TRIANGLES_ADJACENCY TRIANGLES_ADJACENCY}{@link GL32#GL_TRIANGLE_STRIP_ADJACENCY TRIANGLE_STRIP_ADJACENCY}{@link GL40#GL_PATCHES PATCHES}
+ * @param count the number of vertices to transfer to the GL + * @param type indicates the type of index values in {@code indices}. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}
+ * @param indices the index values + * + * @see Reference Page + */ + public static void glDrawElements(@NativeType("GLenum") int mode, @NativeType("GLsizei") int count, @NativeType("GLenum") int type, @NativeType("void const *") long indices) { + GL11C.glDrawElements(mode, count, type, indices); + } + + /** + * Constructs a sequence of geometric primitives by successively transferring elements for {@code count} vertices to the GL. + * The ith element transferred by {@code DrawElements} will be taken from element {@code indices[i]} (if no element array buffer is bound), or + * from the element whose index is stored in the currently bound element array buffer at offset {@code indices + i}. + * + * @param mode the kind of primitives being constructed. One of:
{@link GL11C#GL_POINTS POINTS}{@link GL11C#GL_LINE_STRIP LINE_STRIP}{@link GL11C#GL_LINE_LOOP LINE_LOOP}{@link GL11C#GL_LINES LINES}{@link GL11C#GL_TRIANGLE_STRIP TRIANGLE_STRIP}{@link GL11C#GL_TRIANGLE_FAN TRIANGLE_FAN}
{@link GL11C#GL_TRIANGLES TRIANGLES}{@link GL32#GL_LINES_ADJACENCY LINES_ADJACENCY}{@link GL32#GL_LINE_STRIP_ADJACENCY LINE_STRIP_ADJACENCY}{@link GL32#GL_TRIANGLES_ADJACENCY TRIANGLES_ADJACENCY}{@link GL32#GL_TRIANGLE_STRIP_ADJACENCY TRIANGLE_STRIP_ADJACENCY}{@link GL40#GL_PATCHES PATCHES}
+ * @param type indicates the type of index values in {@code indices}. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}
+ * @param indices the index values + * + * @see Reference Page + */ + public static void glDrawElements(@NativeType("GLenum") int mode, @NativeType("GLenum") int type, @NativeType("void const *") ByteBuffer indices) { + GL11C.glDrawElements(mode, type, indices); + } + + /** + * Constructs a sequence of geometric primitives by successively transferring elements for {@code count} vertices to the GL. + * The ith element transferred by {@code DrawElements} will be taken from element {@code indices[i]} (if no element array buffer is bound), or + * from the element whose index is stored in the currently bound element array buffer at offset {@code indices + i}. + * + * @param mode the kind of primitives being constructed. One of:
{@link GL11C#GL_POINTS POINTS}{@link GL11C#GL_LINE_STRIP LINE_STRIP}{@link GL11C#GL_LINE_LOOP LINE_LOOP}{@link GL11C#GL_LINES LINES}{@link GL11C#GL_TRIANGLE_STRIP TRIANGLE_STRIP}{@link GL11C#GL_TRIANGLE_FAN TRIANGLE_FAN}
{@link GL11C#GL_TRIANGLES TRIANGLES}{@link GL32#GL_LINES_ADJACENCY LINES_ADJACENCY}{@link GL32#GL_LINE_STRIP_ADJACENCY LINE_STRIP_ADJACENCY}{@link GL32#GL_TRIANGLES_ADJACENCY TRIANGLES_ADJACENCY}{@link GL32#GL_TRIANGLE_STRIP_ADJACENCY TRIANGLE_STRIP_ADJACENCY}{@link GL40#GL_PATCHES PATCHES}
+ * @param indices the index values + * + * @see Reference Page + */ + public static void glDrawElements(@NativeType("GLenum") int mode, @NativeType("void const *") ByteBuffer indices) { + GL11C.glDrawElements(mode, indices); + } + + /** + * Constructs a sequence of geometric primitives by successively transferring elements for {@code count} vertices to the GL. + * The ith element transferred by {@code DrawElements} will be taken from element {@code indices[i]} (if no element array buffer is bound), or + * from the element whose index is stored in the currently bound element array buffer at offset {@code indices + i}. + * + * @param mode the kind of primitives being constructed. One of:
{@link GL11C#GL_POINTS POINTS}{@link GL11C#GL_LINE_STRIP LINE_STRIP}{@link GL11C#GL_LINE_LOOP LINE_LOOP}{@link GL11C#GL_LINES LINES}{@link GL11C#GL_TRIANGLE_STRIP TRIANGLE_STRIP}{@link GL11C#GL_TRIANGLE_FAN TRIANGLE_FAN}
{@link GL11C#GL_TRIANGLES TRIANGLES}{@link GL32#GL_LINES_ADJACENCY LINES_ADJACENCY}{@link GL32#GL_LINE_STRIP_ADJACENCY LINE_STRIP_ADJACENCY}{@link GL32#GL_TRIANGLES_ADJACENCY TRIANGLES_ADJACENCY}{@link GL32#GL_TRIANGLE_STRIP_ADJACENCY TRIANGLE_STRIP_ADJACENCY}{@link GL40#GL_PATCHES PATCHES}
+ * @param indices the index values + * + * @see Reference Page + */ + public static void glDrawElements(@NativeType("GLenum") int mode, @NativeType("void const *") ShortBuffer indices) { + GL11C.glDrawElements(mode, indices); + } + + /** + * Constructs a sequence of geometric primitives by successively transferring elements for {@code count} vertices to the GL. + * The ith element transferred by {@code DrawElements} will be taken from element {@code indices[i]} (if no element array buffer is bound), or + * from the element whose index is stored in the currently bound element array buffer at offset {@code indices + i}. + * + * @param mode the kind of primitives being constructed. One of:
{@link GL11C#GL_POINTS POINTS}{@link GL11C#GL_LINE_STRIP LINE_STRIP}{@link GL11C#GL_LINE_LOOP LINE_LOOP}{@link GL11C#GL_LINES LINES}{@link GL11C#GL_TRIANGLE_STRIP TRIANGLE_STRIP}{@link GL11C#GL_TRIANGLE_FAN TRIANGLE_FAN}
{@link GL11C#GL_TRIANGLES TRIANGLES}{@link GL32#GL_LINES_ADJACENCY LINES_ADJACENCY}{@link GL32#GL_LINE_STRIP_ADJACENCY LINE_STRIP_ADJACENCY}{@link GL32#GL_TRIANGLES_ADJACENCY TRIANGLES_ADJACENCY}{@link GL32#GL_TRIANGLE_STRIP_ADJACENCY TRIANGLE_STRIP_ADJACENCY}{@link GL40#GL_PATCHES PATCHES}
+ * @param indices the index values + * + * @see Reference Page + */ + public static void glDrawElements(@NativeType("GLenum") int mode, @NativeType("void const *") IntBuffer indices) { + GL11C.glDrawElements(mode, indices); + } + + // --- [ glDrawPixels ] --- + + /** Unsafe version of: {@link #glDrawPixels DrawPixels} */ + public static native void nglDrawPixels(int width, int height, int format, int type, long pixels); + + /** + * Draws a pixel rectangle to the active draw buffers. + * + * @param width the pixel rectangle width + * @param height the pixel rectangle height + * @param format the pixel data format. One of:
{@link #GL_RED RED}{@link #GL_GREEN GREEN}{@link #GL_BLUE BLUE}{@link #GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link #GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link #GL_STENCIL_INDEX STENCIL_INDEX}{@link #GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}{@link #GL_LUMINANCE LUMINANCE}{@link #GL_LUMINANCE_ALPHA LUMINANCE_ALPHA}
+ * @param type the pixel data type. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_SHORT SHORT}
{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
{@link #GL_BITMAP BITMAP}
+ * @param pixels the pixel data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") ByteBuffer pixels) { + nglDrawPixels(width, height, format, type, memAddress(pixels)); + } + + /** + * Draws a pixel rectangle to the active draw buffers. + * + * @param width the pixel rectangle width + * @param height the pixel rectangle height + * @param format the pixel data format. One of:
{@link #GL_RED RED}{@link #GL_GREEN GREEN}{@link #GL_BLUE BLUE}{@link #GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link #GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link #GL_STENCIL_INDEX STENCIL_INDEX}{@link #GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}{@link #GL_LUMINANCE LUMINANCE}{@link #GL_LUMINANCE_ALPHA LUMINANCE_ALPHA}
+ * @param type the pixel data type. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_SHORT SHORT}
{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
{@link #GL_BITMAP BITMAP}
+ * @param pixels the pixel data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") long pixels) { + nglDrawPixels(width, height, format, type, pixels); + } + + /** + * Draws a pixel rectangle to the active draw buffers. + * + * @param width the pixel rectangle width + * @param height the pixel rectangle height + * @param format the pixel data format. One of:
{@link #GL_RED RED}{@link #GL_GREEN GREEN}{@link #GL_BLUE BLUE}{@link #GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link #GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link #GL_STENCIL_INDEX STENCIL_INDEX}{@link #GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}{@link #GL_LUMINANCE LUMINANCE}{@link #GL_LUMINANCE_ALPHA LUMINANCE_ALPHA}
+ * @param type the pixel data type. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_SHORT SHORT}
{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
{@link #GL_BITMAP BITMAP}
+ * @param pixels the pixel data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") ShortBuffer pixels) { + nglDrawPixels(width, height, format, type, memAddress(pixels)); + } + + /** + * Draws a pixel rectangle to the active draw buffers. + * + * @param width the pixel rectangle width + * @param height the pixel rectangle height + * @param format the pixel data format. One of:
{@link #GL_RED RED}{@link #GL_GREEN GREEN}{@link #GL_BLUE BLUE}{@link #GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link #GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link #GL_STENCIL_INDEX STENCIL_INDEX}{@link #GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}{@link #GL_LUMINANCE LUMINANCE}{@link #GL_LUMINANCE_ALPHA LUMINANCE_ALPHA}
+ * @param type the pixel data type. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_SHORT SHORT}
{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
{@link #GL_BITMAP BITMAP}
+ * @param pixels the pixel data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") IntBuffer pixels) { + nglDrawPixels(width, height, format, type, memAddress(pixels)); + } + + /** + * Draws a pixel rectangle to the active draw buffers. + * + * @param width the pixel rectangle width + * @param height the pixel rectangle height + * @param format the pixel data format. One of:
{@link #GL_RED RED}{@link #GL_GREEN GREEN}{@link #GL_BLUE BLUE}{@link #GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link #GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link #GL_STENCIL_INDEX STENCIL_INDEX}{@link #GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}{@link #GL_LUMINANCE LUMINANCE}{@link #GL_LUMINANCE_ALPHA LUMINANCE_ALPHA}
+ * @param type the pixel data type. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_BYTE BYTE}{@link #GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link #GL_SHORT SHORT}
{@link #GL_UNSIGNED_INT UNSIGNED_INT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
{@link #GL_BITMAP BITMAP}
+ * @param pixels the pixel data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") FloatBuffer pixels) { + nglDrawPixels(width, height, format, type, memAddress(pixels)); + } + + // --- [ glEdgeFlag ] --- + + /** + * Each edge of each polygon primitive generated is flagged as either boundary or non-boundary. These classifications are used during polygon + * rasterization; some modes affect the interpretation of polygon boundary edges. By default, all edges are boundary edges, but the flagging of polygons, + * separate triangles, or separate quadrilaterals may be altered by calling this function. + * + *

When a primitive of type {@link #GL_POLYGON POLYGON}, {@link #GL_TRIANGLES TRIANGLES}, or {@link #GL_QUADS QUADS} is drawn, each vertex transferred begins an edge. If the edge + * flag bit is TRUE, then each specified vertex begins an edge that is flagged as boundary. If the bit is FALSE, then induced edges are flagged as + * non-boundary.

+ * + * @param flag the edge flag bit + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEdgeFlag(@NativeType("GLboolean") boolean flag); + + // --- [ glEdgeFlagv ] --- + + /** Unsafe version of: {@link #glEdgeFlagv EdgeFlagv} */ + public static native void nglEdgeFlagv(long flag); + + /** + * Pointer version of {@link #glEdgeFlag EdgeFlag}. + * + * @param flag the edge flag buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEdgeFlagv(@NativeType("GLboolean const *") ByteBuffer flag) { + if (CHECKS) { + check(flag, 1); + } + nglEdgeFlagv(memAddress(flag)); + } + + // --- [ glEdgeFlagPointer ] --- + + /** Unsafe version of: {@link #glEdgeFlagPointer EdgeFlagPointer} */ + public static native void nglEdgeFlagPointer(int stride, long pointer); + + /** + * Specifies the location and organization of an edge flag array. + * + * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the edge flag array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEdgeFlagPointer(@NativeType("GLsizei") int stride, @NativeType("GLboolean const *") ByteBuffer pointer) { + nglEdgeFlagPointer(stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of an edge flag array. + * + * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the edge flag array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEdgeFlagPointer(@NativeType("GLsizei") int stride, @NativeType("GLboolean const *") long pointer) { + nglEdgeFlagPointer(stride, pointer); + } + + // --- [ glEnableClientState ] --- + + /** + * Enables a client-side capability. + * + *

If the {@link NVVertexBufferUnifiedMemory} extension is supported, this function is available even in a core profile context.

+ * + * @param cap the capability to enable. One of:
{@link #GL_COLOR_ARRAY COLOR_ARRAY}{@link #GL_EDGE_FLAG_ARRAY EDGE_FLAG_ARRAY}{@link GL15#GL_FOG_COORD_ARRAY FOG_COORD_ARRAY}{@link #GL_INDEX_ARRAY INDEX_ARRAY}
{@link #GL_NORMAL_ARRAY NORMAL_ARRAY}{@link GL14#GL_SECONDARY_COLOR_ARRAY SECONDARY_COLOR_ARRAY}{@link #GL_TEXTURE_COORD_ARRAY TEXTURE_COORD_ARRAY}{@link #GL_VERTEX_ARRAY VERTEX_ARRAY}
{@link NVVertexBufferUnifiedMemory#GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV VERTEX_ATTRIB_ARRAY_UNIFIED_NV}{@link NVVertexBufferUnifiedMemory#GL_ELEMENT_ARRAY_UNIFIED_NV ELEMENT_ARRAY_UNIFIED_NV}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEnableClientState(@NativeType("GLenum") int cap); + + // --- [ glEnd ] --- + + /** + * Ends the definition of vertex attributes of a sequence of primitives to be transferred to the GL. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEnd(); + + // --- [ glEvalCoord1f ] --- + + /** + * Causes evaluation of the enabled one-dimensional evaluator maps. + * + * @param u the domain coordinate u + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalCoord1f(@NativeType("GLfloat") float u); + + // --- [ glEvalCoord1fv ] --- + + /** Unsafe version of: {@link #glEvalCoord1fv EvalCoord1fv} */ + public static native void nglEvalCoord1fv(long u); + + /** + * Pointer version of {@link #glEvalCoord1f EvalCoord1f}. + * + * @param u the domain coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord1fv(@NativeType("GLfloat const *") FloatBuffer u) { + if (CHECKS) { + check(u, 1); + } + nglEvalCoord1fv(memAddress(u)); + } + + // --- [ glEvalCoord1d ] --- + + /** + * Double version of {@link #glEvalCoord1f EvalCoord1f}. + * + * @param u the domain coordinate u + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalCoord1d(@NativeType("GLdouble") double u); + + // --- [ glEvalCoord1dv ] --- + + /** Unsafe version of: {@link #glEvalCoord1dv EvalCoord1dv} */ + public static native void nglEvalCoord1dv(long u); + + /** + * Pointer version of {@link #glEvalCoord1d EvalCoord1d}. + * + * @param u the domain coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord1dv(@NativeType("GLdouble const *") DoubleBuffer u) { + if (CHECKS) { + check(u, 1); + } + nglEvalCoord1dv(memAddress(u)); + } + + // --- [ glEvalCoord2f ] --- + + /** + * Causes evaluation of the enabled two-dimensional evaluator maps. + * + * @param u the domain coordinate u + * @param v the domain coordinate v + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalCoord2f(@NativeType("GLfloat") float u, @NativeType("GLfloat") float v); + + // --- [ glEvalCoord2fv ] --- + + /** Unsafe version of: {@link #glEvalCoord2fv EvalCoord2fv} */ + public static native void nglEvalCoord2fv(long u); + + /** + * Pointer version of {@link #glEvalCoord2f EvalCoord2f}. + * + * @param u the domain coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord2fv(@NativeType("GLfloat const *") FloatBuffer u) { + if (CHECKS) { + check(u, 2); + } + nglEvalCoord2fv(memAddress(u)); + } + + // --- [ glEvalCoord2d ] --- + + /** + * Double version of {@link #glEvalCoord2f EvalCoord2f}. + * + * @param u the domain coordinate u + * @param v the domain coordinate v + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalCoord2d(@NativeType("GLdouble") double u, @NativeType("GLdouble") double v); + + // --- [ glEvalCoord2dv ] --- + + /** Unsafe version of: {@link #glEvalCoord2dv EvalCoord2dv} */ + public static native void nglEvalCoord2dv(long u); + + /** + * Pointer version of {@link #glEvalCoord2d EvalCoord2d}. + * + * @param u the domain coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord2dv(@NativeType("GLdouble const *") DoubleBuffer u) { + if (CHECKS) { + check(u, 2); + } + nglEvalCoord2dv(memAddress(u)); + } + + // --- [ glEvalMesh1 ] --- + + /** + * Carries out an evaluation on a subset of the one-dimensional map grid. + * + * @param mode the mesh type. One of:
{@link #GL_POINT POINT}{@link #GL_LINE LINE}
+ * @param i1 the start index + * @param i2 the end index + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalMesh1(@NativeType("GLenum") int mode, @NativeType("GLint") int i1, @NativeType("GLint") int i2); + + // --- [ glEvalMesh2 ] --- + + /** + * Carries out an evaluation on a rectangular subset of the two-dimensional map grid. + * + * @param mode the mesh type. One of:
{@link #GL_FILL FILL}{@link #GL_LINE LINE}{@link #GL_POINT POINT}
+ * @param i1 the u-dimension start index + * @param i2 the u-dimension end index + * @param j1 the v-dimension start index + * @param j2 the v-dimension end index + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalMesh2(@NativeType("GLenum") int mode, @NativeType("GLint") int i1, @NativeType("GLint") int i2, @NativeType("GLint") int j1, @NativeType("GLint") int j2); + + // --- [ glEvalPoint1 ] --- + + /** + * Carries out an evalutation of a single point on the one-dimensional map grid. + * + * @param i the grid index + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalPoint1(@NativeType("GLint") int i); + + // --- [ glEvalPoint2 ] --- + + /** + * Carries out an evalutation of a single point on the two-dimensional map grid. + * + * @param i the u-dimension grid index + * @param j the v-dimension grid index + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEvalPoint2(@NativeType("GLint") int i, @NativeType("GLint") int j); + + // --- [ glFeedbackBuffer ] --- + + /** + * Unsafe version of: {@link #glFeedbackBuffer FeedbackBuffer} + * + * @param size the maximum number of values that can be written to {@code buffer} + */ + public static native void nglFeedbackBuffer(int size, int type, long buffer); + + /** + * Returns information about primitives when the GL is in feedback mode. + * + * @param type the type of information to feed back for each vertex. One of:
{@link #GL_2D 2D}{@link #GL_3D 3D}{@link #GL_3D_COLOR 3D_COLOR}{@link #GL_3D_COLOR_TEXTURE 3D_COLOR_TEXTURE}{@link #GL_4D_COLOR_TEXTURE 4D_COLOR_TEXTURE}
+ * @param buffer an array of floating-point values into which feedback information will be placed + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glFeedbackBuffer(@NativeType("GLenum") int type, @NativeType("GLfloat *") FloatBuffer buffer) { + nglFeedbackBuffer(buffer.remaining(), type, memAddress(buffer)); + } + + // --- [ glFinish ] --- + + /** + * Forces all previously issued GL commands to complete. {@code Finish} does not return until all effects from such commands on GL client and server + * state and the framebuffer are fully realized. + * + * @see Reference Page + */ + public static void glFinish() { + GL11C.glFinish(); + } + + // --- [ glFlush ] --- + + /** + * Causes all previously issued GL commands to complete in finite time (although such commands may still be executing when {@code Flush} returns). + * + * @see Reference Page + */ + public static void glFlush() { + GL11C.glFlush(); + } + + // --- [ glFogi ] --- + + /** + * Sets the integer value of a fog parameter. + * + * @param pname the fog parameter. One of:
{@link #GL_FOG_MODE FOG_MODE}{@link GL15#GL_FOG_COORD_SRC FOG_COORD_SRC}
+ * @param param the fog parameter value. One of:
{@link #GL_EXP EXP}{@link #GL_EXP2 EXP2}{@link #GL_LINEAR LINEAR}{@link GL14#GL_FRAGMENT_DEPTH FRAGMENT_DEPTH}{@link GL15#GL_FOG_COORD FOG_COORD}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glFogi(@NativeType("GLenum") int pname, @NativeType("GLint") int param); + + // --- [ glFogiv ] --- + + /** Unsafe version of: {@link #glFogiv Fogiv} */ + public static native void nglFogiv(int pname, long params); + + /** + * Pointer version of {@link #glFogi Fogi}. + * + * @param pname the fog parameter. One of:
{@link #GL_FOG_MODE FOG_MODE}{@link GL15#GL_FOG_COORD_SRC FOG_COORD_SRC}
+ * @param params the fog parameter buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glFogiv(@NativeType("GLenum") int pname, @NativeType("GLint const *") IntBuffer params) { + if (CHECKS) { + check(params, 1); + } + nglFogiv(pname, memAddress(params)); + } + + // --- [ glFogf ] --- + + /** + * Sets the float value of a fog parameter. + * + * @param pname the fog parameter. One of:
{@link #GL_FOG_DENSITY FOG_DENSITY}{@link #GL_FOG_START FOG_START}{@link #GL_FOG_END FOG_END}
+ * @param param the fog parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glFogf(@NativeType("GLenum") int pname, @NativeType("GLfloat") float param); + + // --- [ glFogfv ] --- + + /** Unsafe version of: {@link #glFogfv Fogfv} */ + public static native void nglFogfv(int pname, long params); + + /** + * Pointer version of {@link #glFogf Fogf}. + * + * @param pname the fog parameter. One of:
{@link #GL_FOG_DENSITY FOG_DENSITY}{@link #GL_FOG_START FOG_START}{@link #GL_FOG_END FOG_END}
+ * @param params the fog parameter buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glFogfv(@NativeType("GLenum") int pname, @NativeType("GLfloat const *") FloatBuffer params) { + if (CHECKS) { + check(params, 1); + } + nglFogfv(pname, memAddress(params)); + } + + // --- [ glFrontFace ] --- + + /** + * The first step of polygon rasterization is to determine if the polygon is back-facing or front-facing. This determination is made based on the sign of + * the (clipped or unclipped) polygon's area computed in window coordinates. The interpretation of the sign of this value is controlled with this function. + * In the initial state, the front face direction is set to {@link GL11C#GL_CCW CCW}. + * + * @param dir the front face direction. One of:
{@link GL11C#GL_CCW CCW}{@link GL11C#GL_CW CW}
+ * + * @see Reference Page + */ + public static void glFrontFace(@NativeType("GLenum") int dir) { + GL11C.glFrontFace(dir); + } + + // --- [ glGenLists ] --- + + /** + * Returns an integer n such that the indices {@code n,..., n + s - 1} are previously unused (i.e. there are {@code s} previously unused display list + * indices starting at n). {@code GenLists} also has the effect of creating an empty display list for each of the indices {@code n,..., n + s - 1}, so + * that these indices all become used. {@code GenLists} returns zero if there is no group of {@code s} contiguous previously unused display list indices, + * or if {@code s = 0}. + * + * @param s the number of display lists to create + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("GLuint") + public static native int glGenLists(@NativeType("GLsizei") int s); + + // --- [ glGenTextures ] --- + + /** + * Unsafe version of: {@link #glGenTextures GenTextures} + * + * @param n the number of textures to create + */ + public static void nglGenTextures(int n, long textures) { + GL11C.nglGenTextures(n, textures); + } + + /** + * Returns n previously unused texture names in textures. These names are marked as used, for the purposes of GenTextures only, but they acquire texture + * state and a dimensionality only when they are first bound, just as if they were unused. + * + * @param textures a scalar or buffer in which to place the returned texture names + * + * @see Reference Page + */ + public static void glGenTextures(@NativeType("GLuint *") IntBuffer textures) { + GL11C.glGenTextures(textures); + } + + /** + * Returns n previously unused texture names in textures. These names are marked as used, for the purposes of GenTextures only, but they acquire texture + * state and a dimensionality only when they are first bound, just as if they were unused. + * + * @see Reference Page + */ + @NativeType("void") + public static int glGenTextures() { + return GL11C.glGenTextures(); + } + + // --- [ glDeleteTextures ] --- + + /** + * Unsafe version of: {@link #glDeleteTextures DeleteTextures} + * + * @param n the number of texture names in the {@code textures} parameter + */ + public static void nglDeleteTextures(int n, long textures) { + GL11C.nglDeleteTextures(n, textures); + } + + /** + * Deletes texture objects. After a texture object is deleted, it has no contents or dimensionality, and its name is again unused. If a texture that is + * currently bound to any of the target bindings of {@link #glBindTexture BindTexture} is deleted, it is as though {@link #glBindTexture BindTexture} had been executed with the + * same target and texture zero. Additionally, special care must be taken when deleting a texture if any of the images of the texture are attached to a + * framebuffer object. + * + *

Unused names in textures that have been marked as used for the purposes of {@link #glGenTextures GenTextures} are marked as unused again. Unused names in textures are + * silently ignored, as is the name zero.

+ * + * @param textures contains {@code n} names of texture objects to be deleted + * + * @see Reference Page + */ + public static void glDeleteTextures(@NativeType("GLuint const *") IntBuffer textures) { + GL11C.glDeleteTextures(textures); + } + + /** + * Deletes texture objects. After a texture object is deleted, it has no contents or dimensionality, and its name is again unused. If a texture that is + * currently bound to any of the target bindings of {@link #glBindTexture BindTexture} is deleted, it is as though {@link #glBindTexture BindTexture} had been executed with the + * same target and texture zero. Additionally, special care must be taken when deleting a texture if any of the images of the texture are attached to a + * framebuffer object. + * + *

Unused names in textures that have been marked as used for the purposes of {@link #glGenTextures GenTextures} are marked as unused again. Unused names in textures are + * silently ignored, as is the name zero.

+ * + * @see Reference Page + */ + public static void glDeleteTextures(@NativeType("GLuint const *") int texture) { + GL11C.glDeleteTextures(texture); + } + + // --- [ glGetClipPlane ] --- + + /** Unsafe version of: {@link #glGetClipPlane GetClipPlane} */ + public static native void nglGetClipPlane(int plane, long equation); + + /** + * Returns four double-precision values in {@code equation}; these are the coefficients of the plane equation of plane in eye coordinates (these + * coordinates are those that were computed when the plane was specified). + * + * @param plane the clip plane + * @param equation a buffer in which to place the returned values + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetClipPlane(@NativeType("GLenum") int plane, @NativeType("GLdouble *") DoubleBuffer equation) { + if (CHECKS) { + check(equation, 4); + } + nglGetClipPlane(plane, memAddress(equation)); + } + + // --- [ glGetBooleanv ] --- + + /** Unsafe version of: {@link #glGetBooleanv GetBooleanv} */ + public static void nglGetBooleanv(int pname, long params) { + GL11C.nglGetBooleanv(pname, params); + } + + /** + * Returns the current boolean value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetBooleanv(@NativeType("GLenum") int pname, @NativeType("GLboolean *") ByteBuffer params) { + GL11C.glGetBooleanv(pname, params); + } + + /** + * Returns the current boolean value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * + * @see Reference Page + */ + @NativeType("void") + public static boolean glGetBoolean(@NativeType("GLenum") int pname) { + return GL11C.glGetBoolean(pname); + } + + // --- [ glGetFloatv ] --- + + /** Unsafe version of: {@link #glGetFloatv GetFloatv} */ + public static void nglGetFloatv(int pname, long params) { + GL11C.nglGetFloatv(pname, params); + } + + /** + * Returns the current float value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetFloatv(@NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer params) { + GL11C.glGetFloatv(pname, params); + } + + /** + * Returns the current float value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * + * @see Reference Page + */ + @NativeType("void") + public static float glGetFloat(@NativeType("GLenum") int pname) { + return GL11C.glGetFloat(pname); + } + + // --- [ glGetIntegerv ] --- + + /** Unsafe version of: {@link #glGetIntegerv GetIntegerv} */ + public static void nglGetIntegerv(int pname, long params) { + GL11C.nglGetIntegerv(pname, params); + } + + /** + * Returns the current integer value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetIntegerv(@NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL11C.glGetIntegerv(pname, params); + } + + /** + * Returns the current integer value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * + * @see Reference Page + */ + @NativeType("void") + public static int glGetInteger(@NativeType("GLenum") int pname) { + return GL11C.glGetInteger(pname); + } + + // --- [ glGetDoublev ] --- + + /** Unsafe version of: {@link #glGetDoublev GetDoublev} */ + public static void nglGetDoublev(int pname, long params) { + GL11C.nglGetDoublev(pname, params); + } + + /** + * Returns the current double value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetDoublev(@NativeType("GLenum") int pname, @NativeType("GLdouble *") DoubleBuffer params) { + GL11C.glGetDoublev(pname, params); + } + + /** + * Returns the current double value of the specified state variable. + * + *

LWJGL note: The state that corresponds to the state variable may be a single value or an array of values. In the case of an array of values, + * LWJGL will not validate if {@code params} has enough space to store that array. Doing so would introduce significant overhead, as the + * OpenGL state variables are too many. It is the user's responsibility to avoid JVM crashes by ensuring enough space for the returned values.

+ * + * @param pname the state variable + * + * @see Reference Page + */ + @NativeType("void") + public static double glGetDouble(@NativeType("GLenum") int pname) { + return GL11C.glGetDouble(pname); + } + + // --- [ glGetError ] --- + + /** + * Returns error information. + * + *

Each detectable error is assigned a numeric code. When an error is detected, a flag is set and the code is recorded. Further errors, if they occur, do + * not affect this recorded code. When {@code GetError} is called, the code is returned and the flag is cleared, so that a further error will again record + * its code. If a call to {@code GetError} returns {@link GL11C#GL_NO_ERROR NO_ERROR}, then there has been no detectable error since the last call to {@code GetError} (or since + * the GL was initialized).

+ * + * @see Reference Page + */ + @NativeType("GLenum") + public static int glGetError() { + return GL11C.glGetError(); + } + + // --- [ glGetLightiv ] --- + + /** Unsafe version of: {@link #glGetLightiv GetLightiv} */ + public static native void nglGetLightiv(int light, int pname, long data); + + /** + * Returns integer information about light parameter {@code pname} for {@code light} in {@code data}. + * + * @param light the light for which to return information. One of:
{@link #GL_LIGHT0 LIGHT0}GL_LIGHT[1-7]
+ * @param pname the light parameter to query. One of:
{@link #GL_AMBIENT AMBIENT}{@link #GL_DIFFUSE DIFFUSE}{@link #GL_SPECULAR SPECULAR}{@link #GL_POSITION POSITION}{@link #GL_CONSTANT_ATTENUATION CONSTANT_ATTENUATION}{@link #GL_LINEAR_ATTENUATION LINEAR_ATTENUATION}
{@link #GL_QUADRATIC_ATTENUATION QUADRATIC_ATTENUATION}{@link #GL_SPOT_DIRECTION SPOT_DIRECTION}{@link #GL_SPOT_EXPONENT SPOT_EXPONENT}{@link #GL_SPOT_CUTOFF SPOT_CUTOFF}
+ * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetLightiv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer data) { + if (CHECKS) { + check(data, 4); + } + nglGetLightiv(light, pname, memAddress(data)); + } + + /** + * Returns integer information about light parameter {@code pname} for {@code light} in {@code data}. + * + * @param light the light for which to return information. One of:
{@link #GL_LIGHT0 LIGHT0}GL_LIGHT[1-7]
+ * @param pname the light parameter to query. One of:
{@link #GL_AMBIENT AMBIENT}{@link #GL_DIFFUSE DIFFUSE}{@link #GL_SPECULAR SPECULAR}{@link #GL_POSITION POSITION}{@link #GL_CONSTANT_ATTENUATION CONSTANT_ATTENUATION}{@link #GL_LINEAR_ATTENUATION LINEAR_ATTENUATION}
{@link #GL_QUADRATIC_ATTENUATION QUADRATIC_ATTENUATION}{@link #GL_SPOT_DIRECTION SPOT_DIRECTION}{@link #GL_SPOT_EXPONENT SPOT_EXPONENT}{@link #GL_SPOT_CUTOFF SPOT_CUTOFF}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static int glGetLighti(@NativeType("GLenum") int light, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer data = stack.callocInt(1); + nglGetLightiv(light, pname, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetLightfv ] --- + + /** Unsafe version of: {@link #glGetLightfv GetLightfv} */ + public static native void nglGetLightfv(int light, int pname, long data); + + /** + * Float version of {@link #glGetLightiv GetLightiv}. + * + * @param light the light for which to return information + * @param pname the light parameter to query + * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetLightfv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer data) { + if (CHECKS) { + check(data, 4); + } + nglGetLightfv(light, pname, memAddress(data)); + } + + /** + * Float version of {@link #glGetLightiv GetLightiv}. + * + * @param light the light for which to return information + * @param pname the light parameter to query + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static float glGetLightf(@NativeType("GLenum") int light, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer data = stack.callocFloat(1); + nglGetLightfv(light, pname, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetMapiv ] --- + + /** Unsafe version of: {@link #glGetMapiv GetMapiv} */ + public static native void nglGetMapiv(int target, int query, long data); + + /** + * Returns integer information about {@code query} for evaluator map {@code target} in {@code data}. + * + * @param target the evaluator target. One of:
{@link #GL_MAP1_VERTEX_3 MAP1_VERTEX_3}{@link #GL_MAP1_VERTEX_4 MAP1_VERTEX_4}{@link #GL_MAP1_COLOR_4 MAP1_COLOR_4}{@link #GL_MAP1_NORMAL MAP1_NORMAL}{@link #GL_MAP1_TEXTURE_COORD_1 MAP1_TEXTURE_COORD_1}
{@link #GL_MAP1_TEXTURE_COORD_2 MAP1_TEXTURE_COORD_2}{@link #GL_MAP1_TEXTURE_COORD_3 MAP1_TEXTURE_COORD_3}{@link #GL_MAP1_TEXTURE_COORD_4 MAP1_TEXTURE_COORD_4}{@link #GL_MAP2_VERTEX_3 MAP2_VERTEX_3}{@link #GL_MAP2_VERTEX_4 MAP2_VERTEX_4}
{@link #GL_MAP2_COLOR_4 MAP2_COLOR_4}{@link #GL_MAP2_NORMAL MAP2_NORMAL}{@link #GL_MAP2_TEXTURE_COORD_1 MAP2_TEXTURE_COORD_1}{@link #GL_MAP2_TEXTURE_COORD_2 MAP2_TEXTURE_COORD_2}{@link #GL_MAP2_TEXTURE_COORD_3 MAP2_TEXTURE_COORD_3}
{@link #GL_MAP2_TEXTURE_COORD_4 MAP2_TEXTURE_COORD_4}
+ * @param query the information to query. One of:
{@link #GL_ORDER ORDER}{@link #GL_COEFF COEFF}{@link #GL_DOMAIN DOMAIN}
+ * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMapiv(@NativeType("GLenum") int target, @NativeType("GLenum") int query, @NativeType("GLint *") IntBuffer data) { + if (CHECKS) { + check(data, 4); + } + nglGetMapiv(target, query, memAddress(data)); + } + + /** + * Returns integer information about {@code query} for evaluator map {@code target} in {@code data}. + * + * @param target the evaluator target. One of:
{@link #GL_MAP1_VERTEX_3 MAP1_VERTEX_3}{@link #GL_MAP1_VERTEX_4 MAP1_VERTEX_4}{@link #GL_MAP1_COLOR_4 MAP1_COLOR_4}{@link #GL_MAP1_NORMAL MAP1_NORMAL}{@link #GL_MAP1_TEXTURE_COORD_1 MAP1_TEXTURE_COORD_1}
{@link #GL_MAP1_TEXTURE_COORD_2 MAP1_TEXTURE_COORD_2}{@link #GL_MAP1_TEXTURE_COORD_3 MAP1_TEXTURE_COORD_3}{@link #GL_MAP1_TEXTURE_COORD_4 MAP1_TEXTURE_COORD_4}{@link #GL_MAP2_VERTEX_3 MAP2_VERTEX_3}{@link #GL_MAP2_VERTEX_4 MAP2_VERTEX_4}
{@link #GL_MAP2_COLOR_4 MAP2_COLOR_4}{@link #GL_MAP2_NORMAL MAP2_NORMAL}{@link #GL_MAP2_TEXTURE_COORD_1 MAP2_TEXTURE_COORD_1}{@link #GL_MAP2_TEXTURE_COORD_2 MAP2_TEXTURE_COORD_2}{@link #GL_MAP2_TEXTURE_COORD_3 MAP2_TEXTURE_COORD_3}
{@link #GL_MAP2_TEXTURE_COORD_4 MAP2_TEXTURE_COORD_4}
+ * @param query the information to query. One of:
{@link #GL_ORDER ORDER}{@link #GL_COEFF COEFF}{@link #GL_DOMAIN DOMAIN}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static int glGetMapi(@NativeType("GLenum") int target, @NativeType("GLenum") int query) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer data = stack.callocInt(1); + nglGetMapiv(target, query, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetMapfv ] --- + + /** Unsafe version of: {@link #glGetMapfv GetMapfv} */ + public static native void nglGetMapfv(int target, int query, long data); + + /** + * Float version of {@link #glGetMapiv GetMapiv}. + * + * @param target the evaluator map + * @param query the information to query + * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMapfv(@NativeType("GLenum") int target, @NativeType("GLenum") int query, @NativeType("GLfloat *") FloatBuffer data) { + if (CHECKS) { + check(data, 4); + } + nglGetMapfv(target, query, memAddress(data)); + } + + /** + * Float version of {@link #glGetMapiv GetMapiv}. + * + * @param target the evaluator map + * @param query the information to query + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static float glGetMapf(@NativeType("GLenum") int target, @NativeType("GLenum") int query) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer data = stack.callocFloat(1); + nglGetMapfv(target, query, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetMapdv ] --- + + /** Unsafe version of: {@link #glGetMapdv GetMapdv} */ + public static native void nglGetMapdv(int target, int query, long data); + + /** + * Double version of {@link #glGetMapiv GetMapiv}. + * + * @param target the evaluator map + * @param query the information to query + * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMapdv(@NativeType("GLenum") int target, @NativeType("GLenum") int query, @NativeType("GLdouble *") DoubleBuffer data) { + if (CHECKS) { + check(data, 4); + } + nglGetMapdv(target, query, memAddress(data)); + } + + /** + * Double version of {@link #glGetMapiv GetMapiv}. + * + * @param target the evaluator map + * @param query the information to query + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static double glGetMapd(@NativeType("GLenum") int target, @NativeType("GLenum") int query) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + DoubleBuffer data = stack.callocDouble(1); + nglGetMapdv(target, query, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetMaterialiv ] --- + + /** Unsafe version of: {@link #glGetMaterialiv GetMaterialiv} */ + public static native void nglGetMaterialiv(int face, int pname, long data); + + /** + * Returns integer information about material property {@code pname} for {@code face} in {@code data}. + * + * @param face the material face for which to return information. One of:
{@link #GL_FRONT FRONT}{@link #GL_BACK BACK}
+ * @param pname the information to query. One of:
{@link #GL_AMBIENT AMBIENT}{@link #GL_DIFFUSE DIFFUSE}{@link #GL_SPECULAR SPECULAR}{@link #GL_EMISSION EMISSION}{@link #GL_SHININESS SHININESS}
+ * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMaterialiv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer data) { + if (CHECKS) { + check(data, 1); + } + nglGetMaterialiv(face, pname, memAddress(data)); + } + + // --- [ glGetMaterialfv ] --- + + /** Unsafe version of: {@link #glGetMaterialfv GetMaterialfv} */ + public static native void nglGetMaterialfv(int face, int pname, long data); + + /** + * Float version of {@link #glGetMaterialiv GetMaterialiv}. + * + * @param face the material face for which to return information + * @param pname the information to query + * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMaterialfv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer data) { + if (CHECKS) { + check(data, 1); + } + nglGetMaterialfv(face, pname, memAddress(data)); + } + + // --- [ glGetPixelMapfv ] --- + + /** Unsafe version of: {@link #glGetPixelMapfv GetPixelMapfv} */ + public static native void nglGetPixelMapfv(int map, long data); + + /** + * Returns all float values in the pixel map {@code map} in {@code data}. + * + * @param map the pixel map parameter to query. One of:
{@link #GL_PIXEL_MAP_I_TO_I PIXEL_MAP_I_TO_I}{@link #GL_PIXEL_MAP_S_TO_S PIXEL_MAP_S_TO_S}{@link #GL_PIXEL_MAP_I_TO_R PIXEL_MAP_I_TO_R}{@link #GL_PIXEL_MAP_I_TO_G PIXEL_MAP_I_TO_G}{@link #GL_PIXEL_MAP_I_TO_B PIXEL_MAP_I_TO_B}
{@link #GL_PIXEL_MAP_I_TO_A PIXEL_MAP_I_TO_A}{@link #GL_PIXEL_MAP_R_TO_R PIXEL_MAP_R_TO_R}{@link #GL_PIXEL_MAP_G_TO_G PIXEL_MAP_G_TO_G}{@link #GL_PIXEL_MAP_B_TO_B PIXEL_MAP_B_TO_B}{@link #GL_PIXEL_MAP_A_TO_A PIXEL_MAP_A_TO_A}
+ * @param data a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapfv(@NativeType("GLenum") int map, @NativeType("GLfloat *") FloatBuffer data) { + if (CHECKS) { + check(data, 32); + } + nglGetPixelMapfv(map, memAddress(data)); + } + + /** + * Returns all float values in the pixel map {@code map} in {@code data}. + * + * @param map the pixel map parameter to query. One of:
{@link #GL_PIXEL_MAP_I_TO_I PIXEL_MAP_I_TO_I}{@link #GL_PIXEL_MAP_S_TO_S PIXEL_MAP_S_TO_S}{@link #GL_PIXEL_MAP_I_TO_R PIXEL_MAP_I_TO_R}{@link #GL_PIXEL_MAP_I_TO_G PIXEL_MAP_I_TO_G}{@link #GL_PIXEL_MAP_I_TO_B PIXEL_MAP_I_TO_B}
{@link #GL_PIXEL_MAP_I_TO_A PIXEL_MAP_I_TO_A}{@link #GL_PIXEL_MAP_R_TO_R PIXEL_MAP_R_TO_R}{@link #GL_PIXEL_MAP_G_TO_G PIXEL_MAP_G_TO_G}{@link #GL_PIXEL_MAP_B_TO_B PIXEL_MAP_B_TO_B}{@link #GL_PIXEL_MAP_A_TO_A PIXEL_MAP_A_TO_A}
+ * @param data a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapfv(@NativeType("GLenum") int map, @NativeType("GLfloat *") long data) { + nglGetPixelMapfv(map, data); + } + + // --- [ glGetPixelMapusv ] --- + + /** Unsafe version of: {@link #glGetPixelMapusv GetPixelMapusv} */ + public static native void nglGetPixelMapusv(int map, long data); + + /** + * Unsigned short version of {@link #glGetPixelMapfv GetPixelMapfv}. + * + * @param map the pixel map parameter to query + * @param data a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapusv(@NativeType("GLenum") int map, @NativeType("GLushort *") ShortBuffer data) { + if (CHECKS) { + check(data, 32); + } + nglGetPixelMapusv(map, memAddress(data)); + } + + /** + * Unsigned short version of {@link #glGetPixelMapfv GetPixelMapfv}. + * + * @param map the pixel map parameter to query + * @param data a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapusv(@NativeType("GLenum") int map, @NativeType("GLushort *") long data) { + nglGetPixelMapusv(map, data); + } + + // --- [ glGetPixelMapuiv ] --- + + /** Unsafe version of: {@link #glGetPixelMapuiv GetPixelMapuiv} */ + public static native void nglGetPixelMapuiv(int map, long data); + + /** + * Unsigned integer version of {@link #glGetPixelMapfv GetPixelMapfv}. + * + * @param map the pixel map parameter to query + * @param data a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapuiv(@NativeType("GLenum") int map, @NativeType("GLuint *") IntBuffer data) { + if (CHECKS) { + check(data, 32); + } + nglGetPixelMapuiv(map, memAddress(data)); + } + + /** + * Unsigned integer version of {@link #glGetPixelMapfv GetPixelMapfv}. + * + * @param map the pixel map parameter to query + * @param data a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapuiv(@NativeType("GLenum") int map, @NativeType("GLuint *") long data) { + nglGetPixelMapuiv(map, data); + } + + // --- [ glGetPointerv ] --- + + /** Unsafe version of: {@link #glGetPointerv GetPointerv} */ + public static void nglGetPointerv(int pname, long params) { + GL11C.nglGetPointerv(pname, params); + } + + /** + * Returns a pointer in the current GL context. + * + * @param pname the pointer to return. One of:
{@link GL43#GL_DEBUG_CALLBACK_FUNCTION DEBUG_CALLBACK_FUNCTION}{@link GL43#GL_DEBUG_CALLBACK_USER_PARAM DEBUG_CALLBACK_USER_PARAM}
+ * @param params a buffer in which to place the returned pointer + * + * @see Reference Page + */ + public static void glGetPointerv(@NativeType("GLenum") int pname, @NativeType("void **") PointerBuffer params) { + GL11C.glGetPointerv(pname, params); + } + + /** + * Returns a pointer in the current GL context. + * + * @param pname the pointer to return. One of:
{@link GL43#GL_DEBUG_CALLBACK_FUNCTION DEBUG_CALLBACK_FUNCTION}{@link GL43#GL_DEBUG_CALLBACK_USER_PARAM DEBUG_CALLBACK_USER_PARAM}
+ * + * @see Reference Page + */ + @NativeType("void") + public static long glGetPointer(@NativeType("GLenum") int pname) { + return GL11C.glGetPointer(pname); + } + + // --- [ glGetPolygonStipple ] --- + + /** Unsafe version of: {@link #glGetPolygonStipple GetPolygonStipple} */ + public static native void nglGetPolygonStipple(long pattern); + + /** + * Obtains the polygon stipple. + * + * @param pattern a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPolygonStipple(@NativeType("void *") ByteBuffer pattern) { + if (CHECKS) { + check(pattern, 128); + } + nglGetPolygonStipple(memAddress(pattern)); + } + + /** + * Obtains the polygon stipple. + * + * @param pattern a buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPolygonStipple(@NativeType("void *") long pattern) { + nglGetPolygonStipple(pattern); + } + + // --- [ glGetString ] --- + + /** Unsafe version of: {@link #glGetString GetString} */ + public static long nglGetString(int name) { + return GL11C.nglGetString(name); + } + + /** + * Return strings describing properties of the current GL context. + * + * @param name the property to query. One of:
{@link GL11C#GL_RENDERER RENDERER}{@link GL11C#GL_VENDOR VENDOR}{@link GL11C#GL_EXTENSIONS EXTENSIONS}{@link GL11C#GL_VERSION VERSION}{@link GL20#GL_SHADING_LANGUAGE_VERSION SHADING_LANGUAGE_VERSION}
+ * + * @see Reference Page + */ + @Nullable + @NativeType("GLubyte const *") + public static String glGetString(@NativeType("GLenum") int name) { + return GL11C.glGetString(name); + } + + // --- [ glGetTexEnviv ] --- + + /** Unsafe version of: {@link #glGetTexEnviv GetTexEnviv} */ + public static native void nglGetTexEnviv(int env, int pname, long data); + + /** + * Returns integer information about {@code pname} for {@code env} in {@code data}. + * + * @param env the texture environment to query. One of:
{@link GL20#GL_POINT_SPRITE POINT_SPRITE}{@link #GL_TEXTURE_ENV TEXTURE_ENV}{@link GL14#GL_TEXTURE_FILTER_CONTROL TEXTURE_FILTER_CONTROL}
+ * @param pname the parameter to query. One of:
{@link GL20#GL_COORD_REPLACE COORD_REPLACE}{@link #GL_TEXTURE_ENV_MODE TEXTURE_ENV_MODE}{@link #GL_TEXTURE_ENV_COLOR TEXTURE_ENV_COLOR}{@link GL14#GL_TEXTURE_LOD_BIAS TEXTURE_LOD_BIAS}{@link GL13#GL_COMBINE_RGB COMBINE_RGB}{@link GL13#GL_COMBINE_ALPHA COMBINE_ALPHA}
{@link GL15#GL_SRC0_RGB SRC0_RGB}{@link GL15#GL_SRC1_RGB SRC1_RGB}{@link GL15#GL_SRC2_RGB SRC2_RGB}{@link GL15#GL_SRC0_ALPHA SRC0_ALPHA}{@link GL15#GL_SRC1_ALPHA SRC1_ALPHA}{@link GL15#GL_SRC2_ALPHA SRC2_ALPHA}
{@link GL13#GL_OPERAND0_RGB OPERAND0_RGB}{@link GL13#GL_OPERAND1_RGB OPERAND1_RGB}{@link GL13#GL_OPERAND2_RGB OPERAND2_RGB}{@link GL13#GL_OPERAND0_ALPHA OPERAND0_ALPHA}{@link GL13#GL_OPERAND1_ALPHA OPERAND1_ALPHA}{@link GL13#GL_OPERAND2_ALPHA OPERAND2_ALPHA}
{@link GL13#GL_RGB_SCALE RGB_SCALE}{@link #GL_ALPHA_SCALE ALPHA_SCALE}
+ * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexEnviv(@NativeType("GLenum") int env, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer data) { + if (CHECKS) { + check(data, 1); + } + nglGetTexEnviv(env, pname, memAddress(data)); + } + + /** + * Returns integer information about {@code pname} for {@code env} in {@code data}. + * + * @param env the texture environment to query. One of:
{@link GL20#GL_POINT_SPRITE POINT_SPRITE}{@link #GL_TEXTURE_ENV TEXTURE_ENV}{@link GL14#GL_TEXTURE_FILTER_CONTROL TEXTURE_FILTER_CONTROL}
+ * @param pname the parameter to query. One of:
{@link GL20#GL_COORD_REPLACE COORD_REPLACE}{@link #GL_TEXTURE_ENV_MODE TEXTURE_ENV_MODE}{@link #GL_TEXTURE_ENV_COLOR TEXTURE_ENV_COLOR}{@link GL14#GL_TEXTURE_LOD_BIAS TEXTURE_LOD_BIAS}{@link GL13#GL_COMBINE_RGB COMBINE_RGB}{@link GL13#GL_COMBINE_ALPHA COMBINE_ALPHA}
{@link GL15#GL_SRC0_RGB SRC0_RGB}{@link GL15#GL_SRC1_RGB SRC1_RGB}{@link GL15#GL_SRC2_RGB SRC2_RGB}{@link GL15#GL_SRC0_ALPHA SRC0_ALPHA}{@link GL15#GL_SRC1_ALPHA SRC1_ALPHA}{@link GL15#GL_SRC2_ALPHA SRC2_ALPHA}
{@link GL13#GL_OPERAND0_RGB OPERAND0_RGB}{@link GL13#GL_OPERAND1_RGB OPERAND1_RGB}{@link GL13#GL_OPERAND2_RGB OPERAND2_RGB}{@link GL13#GL_OPERAND0_ALPHA OPERAND0_ALPHA}{@link GL13#GL_OPERAND1_ALPHA OPERAND1_ALPHA}{@link GL13#GL_OPERAND2_ALPHA OPERAND2_ALPHA}
{@link GL13#GL_RGB_SCALE RGB_SCALE}{@link #GL_ALPHA_SCALE ALPHA_SCALE}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static int glGetTexEnvi(@NativeType("GLenum") int env, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer data = stack.callocInt(1); + nglGetTexEnviv(env, pname, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetTexEnvfv ] --- + + /** Unsafe version of: {@link #glGetTexEnvfv GetTexEnvfv} */ + public static native void nglGetTexEnvfv(int env, int pname, long data); + + /** + * Float version of {@link #glGetTexEnviv GetTexEnviv}. + * + * @param env the texture environment to query + * @param pname the parameter to query + * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexEnvfv(@NativeType("GLenum") int env, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer data) { + if (CHECKS) { + check(data, 1); + } + nglGetTexEnvfv(env, pname, memAddress(data)); + } + + /** + * Float version of {@link #glGetTexEnviv GetTexEnviv}. + * + * @param env the texture environment to query + * @param pname the parameter to query + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static float glGetTexEnvf(@NativeType("GLenum") int env, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer data = stack.callocFloat(1); + nglGetTexEnvfv(env, pname, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetTexGeniv ] --- + + /** Unsafe version of: {@link #glGetTexGeniv GetTexGeniv} */ + public static native void nglGetTexGeniv(int coord, int pname, long data); + + /** + * Returns integer information about {@code pname} for {@code coord} in {@code data}. + * + * @param coord the coord to query. One of:
{@link #GL_S S}{@link #GL_T T}{@link #GL_R R}{@link #GL_Q Q}
+ * @param pname the parameter to query. One of:
{@link #GL_EYE_PLANE EYE_PLANE}{@link #GL_OBJECT_PLANE OBJECT_PLANE}{@link #GL_TEXTURE_GEN_MODE TEXTURE_GEN_MODE}
+ * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexGeniv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer data) { + if (CHECKS) { + check(data, 1); + } + nglGetTexGeniv(coord, pname, memAddress(data)); + } + + /** + * Returns integer information about {@code pname} for {@code coord} in {@code data}. + * + * @param coord the coord to query. One of:
{@link #GL_S S}{@link #GL_T T}{@link #GL_R R}{@link #GL_Q Q}
+ * @param pname the parameter to query. One of:
{@link #GL_EYE_PLANE EYE_PLANE}{@link #GL_OBJECT_PLANE OBJECT_PLANE}{@link #GL_TEXTURE_GEN_MODE TEXTURE_GEN_MODE}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static int glGetTexGeni(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + IntBuffer data = stack.callocInt(1); + nglGetTexGeniv(coord, pname, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetTexGenfv ] --- + + /** Unsafe version of: {@link #glGetTexGenfv GetTexGenfv} */ + public static native void nglGetTexGenfv(int coord, int pname, long data); + + /** + * Float version of {@link #glGetTexGeniv GetTexGeniv}. + * + * @param coord the coord to query + * @param pname the parameter to query + * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexGenfv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer data) { + if (CHECKS) { + check(data, 4); + } + nglGetTexGenfv(coord, pname, memAddress(data)); + } + + /** + * Float version of {@link #glGetTexGeniv GetTexGeniv}. + * + * @param coord the coord to query + * @param pname the parameter to query + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static float glGetTexGenf(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + FloatBuffer data = stack.callocFloat(1); + nglGetTexGenfv(coord, pname, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetTexGendv ] --- + + /** Unsafe version of: {@link #glGetTexGendv GetTexGendv} */ + public static native void nglGetTexGendv(int coord, int pname, long data); + + /** + * Double version of {@link #glGetTexGeniv GetTexGeniv}. + * + * @param coord the coord to query + * @param pname the parameter to query + * @param data a scalar or buffer in which to place the returned data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexGendv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLdouble *") DoubleBuffer data) { + if (CHECKS) { + check(data, 4); + } + nglGetTexGendv(coord, pname, memAddress(data)); + } + + /** + * Double version of {@link #glGetTexGeniv GetTexGeniv}. + * + * @param coord the coord to query + * @param pname the parameter to query + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("void") + public static double glGetTexGend(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname) { + MemoryStack stack = stackGet(); int stackPointer = stack.getPointer(); + try { + DoubleBuffer data = stack.callocDouble(1); + nglGetTexGendv(coord, pname, memAddress(data)); + return data.get(0); + } finally { + stack.setPointer(stackPointer); + } + } + + // --- [ glGetTexImage ] --- + + /** Unsafe version of: {@link #glGetTexImage GetTexImage} */ + public static void nglGetTexImage(int tex, int level, int format, int type, long pixels) { + GL11C.nglGetTexImage(tex, level, format, type, pixels); + } + + /** + * Obtains texture images. + * + * @param tex the texture (or texture face) to be obtained. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_X TEXTURE_CUBE_MAP_POSITIVE_X}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_X TEXTURE_CUBE_MAP_NEGATIVE_X}
{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Y TEXTURE_CUBE_MAP_POSITIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Y TEXTURE_CUBE_MAP_NEGATIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Z TEXTURE_CUBE_MAP_POSITIVE_Z}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Z TEXTURE_CUBE_MAP_NEGATIVE_Z}
+ * @param level the level-of-detail number + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") ByteBuffer pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Obtains texture images. + * + * @param tex the texture (or texture face) to be obtained. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_X TEXTURE_CUBE_MAP_POSITIVE_X}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_X TEXTURE_CUBE_MAP_NEGATIVE_X}
{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Y TEXTURE_CUBE_MAP_POSITIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Y TEXTURE_CUBE_MAP_NEGATIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Z TEXTURE_CUBE_MAP_POSITIVE_Z}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Z TEXTURE_CUBE_MAP_NEGATIVE_Z}
+ * @param level the level-of-detail number + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") long pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Obtains texture images. + * + * @param tex the texture (or texture face) to be obtained. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_X TEXTURE_CUBE_MAP_POSITIVE_X}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_X TEXTURE_CUBE_MAP_NEGATIVE_X}
{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Y TEXTURE_CUBE_MAP_POSITIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Y TEXTURE_CUBE_MAP_NEGATIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Z TEXTURE_CUBE_MAP_POSITIVE_Z}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Z TEXTURE_CUBE_MAP_NEGATIVE_Z}
+ * @param level the level-of-detail number + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") ShortBuffer pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Obtains texture images. + * + * @param tex the texture (or texture face) to be obtained. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_X TEXTURE_CUBE_MAP_POSITIVE_X}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_X TEXTURE_CUBE_MAP_NEGATIVE_X}
{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Y TEXTURE_CUBE_MAP_POSITIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Y TEXTURE_CUBE_MAP_NEGATIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Z TEXTURE_CUBE_MAP_POSITIVE_Z}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Z TEXTURE_CUBE_MAP_NEGATIVE_Z}
+ * @param level the level-of-detail number + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") IntBuffer pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Obtains texture images. + * + * @param tex the texture (or texture face) to be obtained. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_X TEXTURE_CUBE_MAP_POSITIVE_X}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_X TEXTURE_CUBE_MAP_NEGATIVE_X}
{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Y TEXTURE_CUBE_MAP_POSITIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Y TEXTURE_CUBE_MAP_NEGATIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Z TEXTURE_CUBE_MAP_POSITIVE_Z}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Z TEXTURE_CUBE_MAP_NEGATIVE_Z}
+ * @param level the level-of-detail number + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") FloatBuffer pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Obtains texture images. + * + * @param tex the texture (or texture face) to be obtained. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_X TEXTURE_CUBE_MAP_POSITIVE_X}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_X TEXTURE_CUBE_MAP_NEGATIVE_X}
{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Y TEXTURE_CUBE_MAP_POSITIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Y TEXTURE_CUBE_MAP_NEGATIVE_Y}{@link GL13#GL_TEXTURE_CUBE_MAP_POSITIVE_Z TEXTURE_CUBE_MAP_POSITIVE_Z}{@link GL13#GL_TEXTURE_CUBE_MAP_NEGATIVE_Z TEXTURE_CUBE_MAP_NEGATIVE_Z}
+ * @param level the level-of-detail number + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") DoubleBuffer pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + // --- [ glGetTexLevelParameteriv ] --- + + /** Unsafe version of: {@link #glGetTexLevelParameteriv GetTexLevelParameteriv} */ + public static void nglGetTexLevelParameteriv(int target, int level, int pname, long params) { + GL11C.nglGetTexLevelParameteriv(target, level, pname, params); + } + + /** + * Places integer information about texture image parameter {@code pname} for level-of-detail {@code level} of the specified {@code target} into {@code params}. + * + * @param target the texture image target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL40#GL_TEXTURE_CUBE_MAP_ARRAY TEXTURE_CUBE_MAP_ARRAY}
{@link GL32#GL_TEXTURE_2D_MULTISAMPLE TEXTURE_2D_MULTISAMPLE}{@link GL32#GL_TEXTURE_2D_MULTISAMPLE_ARRAY TEXTURE_2D_MULTISAMPLE_ARRAY}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}{@link GL12#GL_PROXY_TEXTURE_3D PROXY_TEXTURE_3D}
{@link GL30#GL_PROXY_TEXTURE_2D_ARRAY PROXY_TEXTURE_2D_ARRAY}{@link GL40#GL_PROXY_TEXTURE_CUBE_MAP_ARRAY PROXY_TEXTURE_CUBE_MAP_ARRAY}{@link GL32#GL_PROXY_TEXTURE_2D_MULTISAMPLE PROXY_TEXTURE_2D_MULTISAMPLE}{@link GL32#GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY}
+ * @param level the level-of-detail number + * @param pname the parameter to query. One of:
{@link GL11C#GL_TEXTURE_WIDTH TEXTURE_WIDTH}{@link GL11C#GL_TEXTURE_HEIGHT TEXTURE_HEIGHT}{@link GL12#GL_TEXTURE_DEPTH TEXTURE_DEPTH}{@link GL32#GL_TEXTURE_SAMPLES TEXTURE_SAMPLES}
{@link GL32#GL_TEXTURE_FIXED_SAMPLE_LOCATIONS TEXTURE_FIXED_SAMPLE_LOCATIONS}{@link GL11C#GL_TEXTURE_INTERNAL_FORMAT TEXTURE_INTERNAL_FORMAT}{@link GL11C#GL_TEXTURE_RED_SIZE TEXTURE_RED_SIZE}{@link GL11C#GL_TEXTURE_GREEN_SIZE TEXTURE_GREEN_SIZE}
{@link GL11C#GL_TEXTURE_BLUE_SIZE TEXTURE_BLUE_SIZE}{@link GL11C#GL_TEXTURE_ALPHA_SIZE TEXTURE_ALPHA_SIZE}{@link GL14#GL_TEXTURE_DEPTH_SIZE TEXTURE_DEPTH_SIZE}{@link GL30#GL_TEXTURE_STENCIL_SIZE TEXTURE_STENCIL_SIZE}
{@link GL30#GL_TEXTURE_SHARED_SIZE TEXTURE_SHARED_SIZE}{@link GL30#GL_TEXTURE_ALPHA_TYPE TEXTURE_ALPHA_TYPE}{@link GL30#GL_TEXTURE_DEPTH_TYPE TEXTURE_DEPTH_TYPE}{@link GL13#GL_TEXTURE_COMPRESSED TEXTURE_COMPRESSED}
{@link GL13#GL_TEXTURE_COMPRESSED_IMAGE_SIZE TEXTURE_COMPRESSED_IMAGE_SIZE}{@link GL31#GL_TEXTURE_BUFFER_DATA_STORE_BINDING TEXTURE_BUFFER_DATA_STORE_BINDING}{@link GL43#GL_TEXTURE_BUFFER_OFFSET TEXTURE_BUFFER_OFFSET}{@link GL43#GL_TEXTURE_BUFFER_SIZE TEXTURE_BUFFER_SIZE}
+ * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexLevelParameteriv(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL11C.glGetTexLevelParameteriv(target, level, pname, params); + } + + /** + * Places integer information about texture image parameter {@code pname} for level-of-detail {@code level} of the specified {@code target} into {@code params}. + * + * @param target the texture image target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL40#GL_TEXTURE_CUBE_MAP_ARRAY TEXTURE_CUBE_MAP_ARRAY}
{@link GL32#GL_TEXTURE_2D_MULTISAMPLE TEXTURE_2D_MULTISAMPLE}{@link GL32#GL_TEXTURE_2D_MULTISAMPLE_ARRAY TEXTURE_2D_MULTISAMPLE_ARRAY}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}{@link GL12#GL_PROXY_TEXTURE_3D PROXY_TEXTURE_3D}
{@link GL30#GL_PROXY_TEXTURE_2D_ARRAY PROXY_TEXTURE_2D_ARRAY}{@link GL40#GL_PROXY_TEXTURE_CUBE_MAP_ARRAY PROXY_TEXTURE_CUBE_MAP_ARRAY}{@link GL32#GL_PROXY_TEXTURE_2D_MULTISAMPLE PROXY_TEXTURE_2D_MULTISAMPLE}{@link GL32#GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY}
+ * @param level the level-of-detail number + * @param pname the parameter to query. One of:
{@link GL11C#GL_TEXTURE_WIDTH TEXTURE_WIDTH}{@link GL11C#GL_TEXTURE_HEIGHT TEXTURE_HEIGHT}{@link GL12#GL_TEXTURE_DEPTH TEXTURE_DEPTH}{@link GL32#GL_TEXTURE_SAMPLES TEXTURE_SAMPLES}
{@link GL32#GL_TEXTURE_FIXED_SAMPLE_LOCATIONS TEXTURE_FIXED_SAMPLE_LOCATIONS}{@link GL11C#GL_TEXTURE_INTERNAL_FORMAT TEXTURE_INTERNAL_FORMAT}{@link GL11C#GL_TEXTURE_RED_SIZE TEXTURE_RED_SIZE}{@link GL11C#GL_TEXTURE_GREEN_SIZE TEXTURE_GREEN_SIZE}
{@link GL11C#GL_TEXTURE_BLUE_SIZE TEXTURE_BLUE_SIZE}{@link GL11C#GL_TEXTURE_ALPHA_SIZE TEXTURE_ALPHA_SIZE}{@link GL14#GL_TEXTURE_DEPTH_SIZE TEXTURE_DEPTH_SIZE}{@link GL30#GL_TEXTURE_STENCIL_SIZE TEXTURE_STENCIL_SIZE}
{@link GL30#GL_TEXTURE_SHARED_SIZE TEXTURE_SHARED_SIZE}{@link GL30#GL_TEXTURE_ALPHA_TYPE TEXTURE_ALPHA_TYPE}{@link GL30#GL_TEXTURE_DEPTH_TYPE TEXTURE_DEPTH_TYPE}{@link GL13#GL_TEXTURE_COMPRESSED TEXTURE_COMPRESSED}
{@link GL13#GL_TEXTURE_COMPRESSED_IMAGE_SIZE TEXTURE_COMPRESSED_IMAGE_SIZE}{@link GL31#GL_TEXTURE_BUFFER_DATA_STORE_BINDING TEXTURE_BUFFER_DATA_STORE_BINDING}{@link GL43#GL_TEXTURE_BUFFER_OFFSET TEXTURE_BUFFER_OFFSET}{@link GL43#GL_TEXTURE_BUFFER_SIZE TEXTURE_BUFFER_SIZE}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetTexLevelParameteri(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int pname) { + return GL11C.glGetTexLevelParameteri(target, level, pname); + } + + // --- [ glGetTexLevelParameterfv ] --- + + /** Unsafe version of: {@link #glGetTexLevelParameterfv GetTexLevelParameterfv} */ + public static void nglGetTexLevelParameterfv(int target, int level, int pname, long params) { + GL11C.nglGetTexLevelParameterfv(target, level, pname, params); + } + + /** + * Float version of {@link #glGetTexLevelParameteriv GetTexLevelParameteriv}. + * + * @param target the texture image target + * @param level the level-of-detail number + * @param pname the parameter to query + * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexLevelParameterfv(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer params) { + GL11C.glGetTexLevelParameterfv(target, level, pname, params); + } + + /** + * Float version of {@link #glGetTexLevelParameteriv GetTexLevelParameteriv}. + * + * @param target the texture image target + * @param level the level-of-detail number + * @param pname the parameter to query + * + * @see Reference Page + */ + @NativeType("void") + public static float glGetTexLevelParameterf(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int pname) { + return GL11C.glGetTexLevelParameterf(target, level, pname); + } + + // --- [ glGetTexParameteriv ] --- + + /** Unsafe version of: {@link #glGetTexParameteriv GetTexParameteriv} */ + public static void nglGetTexParameteriv(int target, int pname, long params) { + GL11C.nglGetTexParameteriv(target, pname, params); + } + + /** + * Place integer information about texture parameter {@code pname} for the specified {@code target} into {@code params}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}{@link GL40#GL_TEXTURE_CUBE_MAP_ARRAY TEXTURE_CUBE_MAP_ARRAY}
{@link GL32#GL_TEXTURE_2D_MULTISAMPLE TEXTURE_2D_MULTISAMPLE}{@link GL32#GL_TEXTURE_2D_MULTISAMPLE_ARRAY TEXTURE_2D_MULTISAMPLE_ARRAY}
+ * @param pname the parameter to query. One of:
{@link GL12#GL_TEXTURE_BASE_LEVEL TEXTURE_BASE_LEVEL}{@link GL11C#GL_TEXTURE_BORDER_COLOR TEXTURE_BORDER_COLOR}{@link GL14#GL_TEXTURE_COMPARE_MODE TEXTURE_COMPARE_MODE}{@link GL14#GL_TEXTURE_COMPARE_FUNC TEXTURE_COMPARE_FUNC}
{@link GL14#GL_TEXTURE_LOD_BIAS TEXTURE_LOD_BIAS}{@link GL11C#GL_TEXTURE_MAG_FILTER TEXTURE_MAG_FILTER}{@link GL12#GL_TEXTURE_MAX_LEVEL TEXTURE_MAX_LEVEL}{@link GL12#GL_TEXTURE_MAX_LOD TEXTURE_MAX_LOD}
{@link GL11C#GL_TEXTURE_MIN_FILTER TEXTURE_MIN_FILTER}{@link GL12#GL_TEXTURE_MIN_LOD TEXTURE_MIN_LOD}{@link GL33#GL_TEXTURE_SWIZZLE_R TEXTURE_SWIZZLE_R}{@link GL33#GL_TEXTURE_SWIZZLE_G TEXTURE_SWIZZLE_G}
{@link GL33#GL_TEXTURE_SWIZZLE_B TEXTURE_SWIZZLE_B}{@link GL33#GL_TEXTURE_SWIZZLE_A TEXTURE_SWIZZLE_A}{@link GL33#GL_TEXTURE_SWIZZLE_RGBA TEXTURE_SWIZZLE_RGBA}{@link GL11C#GL_TEXTURE_WRAP_S TEXTURE_WRAP_S}
{@link GL11C#GL_TEXTURE_WRAP_T TEXTURE_WRAP_T}{@link GL12#GL_TEXTURE_WRAP_R TEXTURE_WRAP_R}{@link GL14#GL_DEPTH_TEXTURE_MODE DEPTH_TEXTURE_MODE}{@link GL14#GL_GENERATE_MIPMAP GENERATE_MIPMAP}
{@link GL42#GL_IMAGE_FORMAT_COMPATIBILITY_TYPE IMAGE_FORMAT_COMPATIBILITY_TYPE}{@link GL42#GL_TEXTURE_IMMUTABLE_FORMAT TEXTURE_IMMUTABLE_FORMAT}{@link GL43#GL_TEXTURE_IMMUTABLE_LEVELS TEXTURE_IMMUTABLE_LEVELS}{@link GL43#GL_TEXTURE_VIEW_MIN_LEVEL TEXTURE_VIEW_MIN_LEVEL}
{@link GL43#GL_TEXTURE_VIEW_NUM_LEVELS TEXTURE_VIEW_NUM_LEVELS}{@link GL43#GL_TEXTURE_VIEW_MIN_LAYER TEXTURE_VIEW_MIN_LAYER}{@link GL43#GL_TEXTURE_VIEW_NUM_LAYERS TEXTURE_VIEW_NUM_LAYERS}
+ * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexParameteriv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL11C.glGetTexParameteriv(target, pname, params); + } + + /** + * Place integer information about texture parameter {@code pname} for the specified {@code target} into {@code params}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}{@link GL40#GL_TEXTURE_CUBE_MAP_ARRAY TEXTURE_CUBE_MAP_ARRAY}
{@link GL32#GL_TEXTURE_2D_MULTISAMPLE TEXTURE_2D_MULTISAMPLE}{@link GL32#GL_TEXTURE_2D_MULTISAMPLE_ARRAY TEXTURE_2D_MULTISAMPLE_ARRAY}
+ * @param pname the parameter to query. One of:
{@link GL12#GL_TEXTURE_BASE_LEVEL TEXTURE_BASE_LEVEL}{@link GL11C#GL_TEXTURE_BORDER_COLOR TEXTURE_BORDER_COLOR}{@link GL14#GL_TEXTURE_COMPARE_MODE TEXTURE_COMPARE_MODE}{@link GL14#GL_TEXTURE_COMPARE_FUNC TEXTURE_COMPARE_FUNC}
{@link GL14#GL_TEXTURE_LOD_BIAS TEXTURE_LOD_BIAS}{@link GL11C#GL_TEXTURE_MAG_FILTER TEXTURE_MAG_FILTER}{@link GL12#GL_TEXTURE_MAX_LEVEL TEXTURE_MAX_LEVEL}{@link GL12#GL_TEXTURE_MAX_LOD TEXTURE_MAX_LOD}
{@link GL11C#GL_TEXTURE_MIN_FILTER TEXTURE_MIN_FILTER}{@link GL12#GL_TEXTURE_MIN_LOD TEXTURE_MIN_LOD}{@link GL33#GL_TEXTURE_SWIZZLE_R TEXTURE_SWIZZLE_R}{@link GL33#GL_TEXTURE_SWIZZLE_G TEXTURE_SWIZZLE_G}
{@link GL33#GL_TEXTURE_SWIZZLE_B TEXTURE_SWIZZLE_B}{@link GL33#GL_TEXTURE_SWIZZLE_A TEXTURE_SWIZZLE_A}{@link GL33#GL_TEXTURE_SWIZZLE_RGBA TEXTURE_SWIZZLE_RGBA}{@link GL11C#GL_TEXTURE_WRAP_S TEXTURE_WRAP_S}
{@link GL11C#GL_TEXTURE_WRAP_T TEXTURE_WRAP_T}{@link GL12#GL_TEXTURE_WRAP_R TEXTURE_WRAP_R}{@link GL14#GL_DEPTH_TEXTURE_MODE DEPTH_TEXTURE_MODE}{@link GL14#GL_GENERATE_MIPMAP GENERATE_MIPMAP}
{@link GL42#GL_IMAGE_FORMAT_COMPATIBILITY_TYPE IMAGE_FORMAT_COMPATIBILITY_TYPE}{@link GL42#GL_TEXTURE_IMMUTABLE_FORMAT TEXTURE_IMMUTABLE_FORMAT}{@link GL43#GL_TEXTURE_IMMUTABLE_LEVELS TEXTURE_IMMUTABLE_LEVELS}{@link GL43#GL_TEXTURE_VIEW_MIN_LEVEL TEXTURE_VIEW_MIN_LEVEL}
{@link GL43#GL_TEXTURE_VIEW_NUM_LEVELS TEXTURE_VIEW_NUM_LEVELS}{@link GL43#GL_TEXTURE_VIEW_MIN_LAYER TEXTURE_VIEW_MIN_LAYER}{@link GL43#GL_TEXTURE_VIEW_NUM_LAYERS TEXTURE_VIEW_NUM_LAYERS}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetTexParameteri(@NativeType("GLenum") int target, @NativeType("GLenum") int pname) { + return GL11C.glGetTexParameteri(target, pname); + } + + // --- [ glGetTexParameterfv ] --- + + /** Unsafe version of: {@link #glGetTexParameterfv GetTexParameterfv} */ + public static void nglGetTexParameterfv(int target, int pname, long params) { + GL11C.nglGetTexParameterfv(target, pname, params); + } + + /** + * Float version of {@link #glGetTexParameteriv GetTexParameteriv}. + * + * @param target the texture target + * @param pname the parameter to query + * @param params a scalar or buffer in which to place the returned data + * + * @see Reference Page + */ + public static void glGetTexParameterfv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer params) { + GL11C.glGetTexParameterfv(target, pname, params); + } + + /** + * Float version of {@link #glGetTexParameteriv GetTexParameteriv}. + * + * @param target the texture target + * @param pname the parameter to query + * + * @see Reference Page + */ + @NativeType("void") + public static float glGetTexParameterf(@NativeType("GLenum") int target, @NativeType("GLenum") int pname) { + return GL11C.glGetTexParameterf(target, pname); + } + + // --- [ glHint ] --- + + /** + * Certain aspects of GL behavior, when there is room for variation, may be controlled with this function. The initial value for all hints is + * {@link GL11C#GL_DONT_CARE DONT_CARE}. + * + * @param target the behavior to control. One of:
{@link GL11C#GL_LINE_SMOOTH_HINT LINE_SMOOTH_HINT}{@link GL11C#GL_POLYGON_SMOOTH_HINT POLYGON_SMOOTH_HINT}{@link GL13#GL_TEXTURE_COMPRESSION_HINT TEXTURE_COMPRESSION_HINT}
{@link GL20#GL_FRAGMENT_SHADER_DERIVATIVE_HINT FRAGMENT_SHADER_DERIVATIVE_HINT}
+ * @param hint the behavior hint. One of:
{@link GL11C#GL_FASTEST FASTEST}{@link GL11C#GL_NICEST NICEST}{@link GL11C#GL_DONT_CARE DONT_CARE}
+ * + * @see Reference Page + */ + public static void glHint(@NativeType("GLenum") int target, @NativeType("GLenum") int hint) { + GL11C.glHint(target, hint); + } + + // --- [ glIndexi ] --- + + /** + * Updates the current (single-valued) color index. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glIndexi(@NativeType("GLint") int index); + + // --- [ glIndexub ] --- + + /** + * Unsigned byte version of {@link #glIndexi Indexi}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glIndexub(@NativeType("GLubyte") byte index); + + // --- [ glIndexs ] --- + + /** + * Short version of {@link #glIndexi Indexi}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glIndexs(@NativeType("GLshort") short index); + + // --- [ glIndexf ] --- + + /** + * Float version of {@link #glIndexi Indexi}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glIndexf(@NativeType("GLfloat") float index); + + // --- [ glIndexd ] --- + + /** + * Double version of {@link #glIndexi Indexi}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glIndexd(@NativeType("GLdouble") double index); + + // --- [ glIndexiv ] --- + + /** Unsafe version of: {@link #glIndexiv Indexiv} */ + public static native void nglIndexiv(long index); + + /** + * Pointer version of {@link #glIndexi Indexi} + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexiv(@NativeType("GLint const *") IntBuffer index) { + if (CHECKS) { + check(index, 1); + } + nglIndexiv(memAddress(index)); + } + + // --- [ glIndexubv ] --- + + /** Unsafe version of: {@link #glIndexubv Indexubv} */ + public static native void nglIndexubv(long index); + + /** + * Pointer version of {@link #glIndexub Indexub}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexubv(@NativeType("GLubyte const *") ByteBuffer index) { + if (CHECKS) { + check(index, 1); + } + nglIndexubv(memAddress(index)); + } + + // --- [ glIndexsv ] --- + + /** Unsafe version of: {@link #glIndexsv Indexsv} */ + public static native void nglIndexsv(long index); + + /** + * Pointer version of {@link #glIndexs Indexs}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexsv(@NativeType("GLshort const *") ShortBuffer index) { + if (CHECKS) { + check(index, 1); + } + nglIndexsv(memAddress(index)); + } + + // --- [ glIndexfv ] --- + + /** Unsafe version of: {@link #glIndexfv Indexfv} */ + public static native void nglIndexfv(long index); + + /** + * Pointer version of {@link #glIndexf Indexf}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexfv(@NativeType("GLfloat const *") FloatBuffer index) { + if (CHECKS) { + check(index, 1); + } + nglIndexfv(memAddress(index)); + } + + // --- [ glIndexdv ] --- + + /** Unsafe version of: {@link #glIndexdv Indexdv} */ + public static native void nglIndexdv(long index); + + /** + * Pointer version of {@link #glIndexd Indexd}. + * + * @param index the value to which the current color index should be set + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexdv(@NativeType("GLdouble const *") DoubleBuffer index) { + if (CHECKS) { + check(index, 1); + } + nglIndexdv(memAddress(index)); + } + + // --- [ glIndexMask ] --- + + /** + * The least significant n bits of mask, where n is the number of bits in a color index buffer, specify a mask. Where a 1 appears in this mask, the + * corresponding bit in the color index buffer (or buffers) is written; where a 0 appears, the bit is not written. This mask applies only in color index + * mode. + * + * @param mask the color index mask value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glIndexMask(@NativeType("GLuint") int mask); + + // --- [ glIndexPointer ] --- + + /** + * Unsafe version of: {@link #glIndexPointer IndexPointer} + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}
+ */ + public static native void nglIndexPointer(int type, int stride, long pointer); + + /** + * Specifies the location and organization of a color index array. + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color index array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexPointer(@NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + nglIndexPointer(type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a color index array. + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color index array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexPointer(@NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") long pointer) { + nglIndexPointer(type, stride, pointer); + } + + /** + * Specifies the location and organization of a color index array. + * + * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color index array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexPointer(@NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + nglIndexPointer(GL11.GL_UNSIGNED_BYTE, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a color index array. + * + * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color index array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexPointer(@NativeType("GLsizei") int stride, @NativeType("void const *") ShortBuffer pointer) { + nglIndexPointer(GL11.GL_SHORT, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a color index array. + * + * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the color index array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexPointer(@NativeType("GLsizei") int stride, @NativeType("void const *") IntBuffer pointer) { + nglIndexPointer(GL11.GL_INT, stride, memAddress(pointer)); + } + + // --- [ glInitNames ] --- + + /** + * Clears the selection name stack. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glInitNames(); + + // --- [ glInterleavedArrays ] --- + + /** Unsafe version of: {@link #glInterleavedArrays InterleavedArrays} */ + public static native void nglInterleavedArrays(int format, int stride, long pointer); + + /** + * Efficiently initializes the six vertex arrays and their enables to one of 14 configurations. + * + * @param format the interleaved array format. One of:
{@link #GL_V2F V2F}{@link #GL_V3F V3F}{@link #GL_C4UB_V2F C4UB_V2F}{@link #GL_C4UB_V3F C4UB_V3F}{@link #GL_C3F_V3F C3F_V3F}{@link #GL_N3F_V3F N3F_V3F}{@link #GL_C4F_N3F_V3F C4F_N3F_V3F}{@link #GL_T2F_V3F T2F_V3F}
{@link #GL_T4F_V4F T4F_V4F}{@link #GL_T2F_C4UB_V3F T2F_C4UB_V3F}{@link #GL_T2F_C3F_V3F T2F_C3F_V3F}{@link #GL_T2F_N3F_V3F T2F_N3F_V3F}{@link #GL_T2F_C4F_N3F_V3F T2F_C4F_N3F_V3F}{@link #GL_T4F_C4F_N3F_V4F T4F_C4F_N3F_V4F}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + nglInterleavedArrays(format, stride, memAddress(pointer)); + } + + /** + * Efficiently initializes the six vertex arrays and their enables to one of 14 configurations. + * + * @param format the interleaved array format. One of:
{@link #GL_V2F V2F}{@link #GL_V3F V3F}{@link #GL_C4UB_V2F C4UB_V2F}{@link #GL_C4UB_V3F C4UB_V3F}{@link #GL_C3F_V3F C3F_V3F}{@link #GL_N3F_V3F N3F_V3F}{@link #GL_C4F_N3F_V3F C4F_N3F_V3F}{@link #GL_T2F_V3F T2F_V3F}
{@link #GL_T4F_V4F T4F_V4F}{@link #GL_T2F_C4UB_V3F T2F_C4UB_V3F}{@link #GL_T2F_C3F_V3F T2F_C3F_V3F}{@link #GL_T2F_N3F_V3F T2F_N3F_V3F}{@link #GL_T2F_C4F_N3F_V3F T2F_C4F_N3F_V3F}{@link #GL_T4F_C4F_N3F_V4F T4F_C4F_N3F_V4F}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") long pointer) { + nglInterleavedArrays(format, stride, pointer); + } + + /** + * Efficiently initializes the six vertex arrays and their enables to one of 14 configurations. + * + * @param format the interleaved array format. One of:
{@link #GL_V2F V2F}{@link #GL_V3F V3F}{@link #GL_C4UB_V2F C4UB_V2F}{@link #GL_C4UB_V3F C4UB_V3F}{@link #GL_C3F_V3F C3F_V3F}{@link #GL_N3F_V3F N3F_V3F}{@link #GL_C4F_N3F_V3F C4F_N3F_V3F}{@link #GL_T2F_V3F T2F_V3F}
{@link #GL_T4F_V4F T4F_V4F}{@link #GL_T2F_C4UB_V3F T2F_C4UB_V3F}{@link #GL_T2F_C3F_V3F T2F_C3F_V3F}{@link #GL_T2F_N3F_V3F T2F_N3F_V3F}{@link #GL_T2F_C4F_N3F_V3F T2F_C4F_N3F_V3F}{@link #GL_T4F_C4F_N3F_V4F T4F_C4F_N3F_V4F}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") ShortBuffer pointer) { + nglInterleavedArrays(format, stride, memAddress(pointer)); + } + + /** + * Efficiently initializes the six vertex arrays and their enables to one of 14 configurations. + * + * @param format the interleaved array format. One of:
{@link #GL_V2F V2F}{@link #GL_V3F V3F}{@link #GL_C4UB_V2F C4UB_V2F}{@link #GL_C4UB_V3F C4UB_V3F}{@link #GL_C3F_V3F C3F_V3F}{@link #GL_N3F_V3F N3F_V3F}{@link #GL_C4F_N3F_V3F C4F_N3F_V3F}{@link #GL_T2F_V3F T2F_V3F}
{@link #GL_T4F_V4F T4F_V4F}{@link #GL_T2F_C4UB_V3F T2F_C4UB_V3F}{@link #GL_T2F_C3F_V3F T2F_C3F_V3F}{@link #GL_T2F_N3F_V3F T2F_N3F_V3F}{@link #GL_T2F_C4F_N3F_V3F T2F_C4F_N3F_V3F}{@link #GL_T4F_C4F_N3F_V4F T4F_C4F_N3F_V4F}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") IntBuffer pointer) { + nglInterleavedArrays(format, stride, memAddress(pointer)); + } + + /** + * Efficiently initializes the six vertex arrays and their enables to one of 14 configurations. + * + * @param format the interleaved array format. One of:
{@link #GL_V2F V2F}{@link #GL_V3F V3F}{@link #GL_C4UB_V2F C4UB_V2F}{@link #GL_C4UB_V3F C4UB_V3F}{@link #GL_C3F_V3F C3F_V3F}{@link #GL_N3F_V3F N3F_V3F}{@link #GL_C4F_N3F_V3F C4F_N3F_V3F}{@link #GL_T2F_V3F T2F_V3F}
{@link #GL_T4F_V4F T4F_V4F}{@link #GL_T2F_C4UB_V3F T2F_C4UB_V3F}{@link #GL_T2F_C3F_V3F T2F_C3F_V3F}{@link #GL_T2F_N3F_V3F T2F_N3F_V3F}{@link #GL_T2F_C4F_N3F_V3F T2F_C4F_N3F_V3F}{@link #GL_T4F_C4F_N3F_V4F T4F_C4F_N3F_V4F}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") FloatBuffer pointer) { + nglInterleavedArrays(format, stride, memAddress(pointer)); + } + + /** + * Efficiently initializes the six vertex arrays and their enables to one of 14 configurations. + * + * @param format the interleaved array format. One of:
{@link #GL_V2F V2F}{@link #GL_V3F V3F}{@link #GL_C4UB_V2F C4UB_V2F}{@link #GL_C4UB_V3F C4UB_V3F}{@link #GL_C3F_V3F C3F_V3F}{@link #GL_N3F_V3F N3F_V3F}{@link #GL_C4F_N3F_V3F C4F_N3F_V3F}{@link #GL_T2F_V3F T2F_V3F}
{@link #GL_T4F_V4F T4F_V4F}{@link #GL_T2F_C4UB_V3F T2F_C4UB_V3F}{@link #GL_T2F_C3F_V3F T2F_C3F_V3F}{@link #GL_T2F_N3F_V3F T2F_N3F_V3F}{@link #GL_T2F_C4F_N3F_V3F T2F_C4F_N3F_V3F}{@link #GL_T4F_C4F_N3F_V4F T4F_C4F_N3F_V4F}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") DoubleBuffer pointer) { + nglInterleavedArrays(format, stride, memAddress(pointer)); + } + + // --- [ glIsEnabled ] --- + + /** + * Determines if {@code cap} is currently enabled (as with {@link #glEnable Enable}) or disabled. + * + * @param cap the enable state to query + * + * @see Reference Page + */ + @NativeType("GLboolean") + public static boolean glIsEnabled(@NativeType("GLenum") int cap) { + return GL11C.glIsEnabled(cap); + } + + // --- [ glIsList ] --- + + /** + * Returns true if the {@code list} is the index of some display list. + * + * @param list the list index to query + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("GLboolean") + public static native boolean glIsList(@NativeType("GLuint") int list); + + // --- [ glIsTexture ] --- + + /** + * Returns true if {@code texture} is the name of a texture object. + * + * @param texture the texture name to query + * + * @see Reference Page + */ + @NativeType("GLboolean") + public static boolean glIsTexture(@NativeType("GLuint") int texture) { + return GL11C.glIsTexture(texture); + } + + // --- [ glLightModeli ] --- + + /** + * Set the integer value of a lighting model parameter. + * + * @param pname the lighting model parameter to set. One of:
{@link #GL_LIGHT_MODEL_AMBIENT LIGHT_MODEL_AMBIENT}{@link #GL_LIGHT_MODEL_LOCAL_VIEWER LIGHT_MODEL_LOCAL_VIEWER}{@link #GL_LIGHT_MODEL_TWO_SIDE LIGHT_MODEL_TWO_SIDE}
{@link GL12#GL_LIGHT_MODEL_COLOR_CONTROL LIGHT_MODEL_COLOR_CONTROL}
+ * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glLightModeli(@NativeType("GLenum") int pname, @NativeType("GLint") int param); + + // --- [ glLightModelf ] --- + + /** + * Float version of {@link #glLightModeli LightModeli}. + * + * @param pname the lighting model parameter to set + * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glLightModelf(@NativeType("GLenum") int pname, @NativeType("GLfloat") float param); + + // --- [ glLightModeliv ] --- + + /** Unsafe version of: {@link #glLightModeliv LightModeliv} */ + public static native void nglLightModeliv(int pname, long params); + + /** + * Pointer version of {@link #glLightModeli LightModeli}. + * + * @param pname the lighting model parameter to set + * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightModeliv(@NativeType("GLenum") int pname, @NativeType("GLint const *") IntBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglLightModeliv(pname, memAddress(params)); + } + + // --- [ glLightModelfv ] --- + + /** Unsafe version of: {@link #glLightModelfv LightModelfv} */ + public static native void nglLightModelfv(int pname, long params); + + /** + * Pointer version of {@link #glLightModelf LightModelf}. + * + * @param pname the lighting model parameter to set + * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightModelfv(@NativeType("GLenum") int pname, @NativeType("GLfloat const *") FloatBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglLightModelfv(pname, memAddress(params)); + } + + // --- [ glLighti ] --- + + /** + * Sets the integer value of a light parameter. + * + * @param light the light for which to set the parameter. One of:
{@link #GL_LIGHT0 LIGHT0}GL_LIGHT[1-7]
+ * @param pname the parameter to set. One of:
{@link #GL_AMBIENT AMBIENT}{@link #GL_DIFFUSE DIFFUSE}{@link #GL_SPECULAR SPECULAR}{@link #GL_POSITION POSITION}{@link #GL_CONSTANT_ATTENUATION CONSTANT_ATTENUATION}{@link #GL_LINEAR_ATTENUATION LINEAR_ATTENUATION}
{@link #GL_QUADRATIC_ATTENUATION QUADRATIC_ATTENUATION}{@link #GL_SPOT_DIRECTION SPOT_DIRECTION}{@link #GL_SPOT_EXPONENT SPOT_EXPONENT}{@link #GL_SPOT_CUTOFF SPOT_CUTOFF}
+ * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glLighti(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLint") int param); + + // --- [ glLightf ] --- + + /** + * Float version of {@link #glLighti Lighti}. + * + * @param light the light for which to set the parameter + * @param pname the parameter to set + * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glLightf(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLfloat") float param); + + // --- [ glLightiv ] --- + + /** Unsafe version of: {@link #glLightiv Lightiv} */ + public static native void nglLightiv(int light, int pname, long params); + + /** + * Pointer version of {@link #glLighti Lighti}. + * + * @param light the light for which to set the parameter + * @param pname the parameter to set + * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightiv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLint const *") IntBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglLightiv(light, pname, memAddress(params)); + } + + // --- [ glLightfv ] --- + + /** Unsafe version of: {@link #glLightfv Lightfv} */ + public static native void nglLightfv(int light, int pname, long params); + + /** + * Pointer version of {@link #glLightf Lightf}. + * + * @param light the light for which to set the parameter + * @param pname the parameter to set + * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightfv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") FloatBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglLightfv(light, pname, memAddress(params)); + } + + // --- [ glLineStipple ] --- + + /** + * Defines a line stipple. It determines those fragments that are to be drawn when the line is rasterized. Line stippling may be enabled or disabled using + * {@link #glEnable Enable} or {@link #glDisable Disable} with the constant {@link #GL_LINE_STIPPLE LINE_STIPPLE}. When disabled, it is as if the line stipple has its default value. + * + * @param factor a count that is used to modify the effective line stipple by causing each bit in pattern to be used {@code factor} times. {@code factor} is clamped + * to the range [1, 256]. + * @param pattern an unsigned short integer whose 16 bits define the stipple pattern + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glLineStipple(@NativeType("GLint") int factor, @NativeType("GLushort") short pattern); + + // --- [ glLineWidth ] --- + + /** + * Sets the width of rasterized line segments. The default width is 1.0. + * + * @param width the line width + * + * @see Reference Page + */ + public static void glLineWidth(@NativeType("GLfloat") float width) { + GL11C.glLineWidth(width); + } + + // --- [ glListBase ] --- + + /** + * Sets the display list base. + * + * @param base the display list base offset + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glListBase(@NativeType("GLuint") int base); + + // --- [ glLoadMatrixf ] --- + + /** Unsafe version of: {@link #glLoadMatrixf LoadMatrixf} */ + public static native void nglLoadMatrixf(long m); + + /** + * Sets the current matrix to a 4 × 4 matrix in column-major order. + * + *

The matrix is stored as 16 consecutive values, i.e. as:

+ * + * + * + * + * + * + *
a1a5a9a13
a2a6a10a14
a3a7a11a15
a4a8a12a16
+ * + *

This differs from the standard row-major ordering for matrix elements. If the standard ordering is used, all of the subsequent transformation equations + * are transposed, and the columns representing vectors become rows.

+ * + * @param m the matrix data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLoadMatrixf(@NativeType("GLfloat const *") FloatBuffer m) { + if (CHECKS) { + check(m, 16); + } + nglLoadMatrixf(memAddress(m)); + } + + // --- [ glLoadMatrixd ] --- + + /** Unsafe version of: {@link #glLoadMatrixd LoadMatrixd} */ + public static native void nglLoadMatrixd(long m); + + /** + * Double version of {@link #glLoadMatrixf LoadMatrixf}. + * + * @param m the matrix data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLoadMatrixd(@NativeType("GLdouble const *") DoubleBuffer m) { + if (CHECKS) { + check(m, 16); + } + nglLoadMatrixd(memAddress(m)); + } + + // --- [ glLoadIdentity ] --- + + /** + * Sets the current matrix to the identity matrix. + * + *

Calling this function is equivalent to calling {@link #glLoadMatrixf LoadMatrixf} with the following matrix:

+ * + * + * + * + * + * + *
1000
0100
0010
0001
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glLoadIdentity(); + + // --- [ glLoadName ] --- + + /** + * Replaces the value on the top of the selection stack with {@code name}. + * + * @param name the name to load + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glLoadName(@NativeType("GLuint") int name); + + // --- [ glLogicOp ] --- + + /** + * Sets the logical framebuffer operation. + * + * @param op the operation to set. One of:
{@link GL11C#GL_CLEAR CLEAR}{@link GL11C#GL_AND AND}{@link GL11C#GL_AND_REVERSE AND_REVERSE}{@link GL11C#GL_COPY COPY}{@link GL11C#GL_AND_INVERTED AND_INVERTED}{@link GL11C#GL_NOOP NOOP}{@link GL11C#GL_XOR XOR}{@link GL11C#GL_OR OR}{@link GL11C#GL_NOR NOR}{@link GL11C#GL_EQUIV EQUIV}{@link GL11C#GL_INVERT INVERT}{@link GL11C#GL_OR_REVERSE OR_REVERSE}{@link GL11C#GL_COPY_INVERTED COPY_INVERTED}
{@link GL11C#GL_OR_INVERTED OR_INVERTED}{@link GL11C#GL_NAND NAND}{@link GL11C#GL_SET SET}
+ * + * @see Reference Page + */ + public static void glLogicOp(@NativeType("GLenum") int op) { + GL11C.glLogicOp(op); + } + + // --- [ glMap1f ] --- + + /** Unsafe version of: {@link #glMap1f Map1f} */ + public static native void nglMap1f(int target, float u1, float u2, int stride, int order, long points); + + /** + * Defines a polynomial or rational polynomial mapping to produce vertex, normal, texture coordinates and colors. The values so produced are sent on to + * further stages of the GL as if they had been provided directly by the client. + * + * @param target the evaluator target. One of:
{@link #GL_MAP1_VERTEX_3 MAP1_VERTEX_3}{@link #GL_MAP1_VERTEX_4 MAP1_VERTEX_4}{@link #GL_MAP1_COLOR_4 MAP1_COLOR_4}{@link #GL_MAP1_NORMAL MAP1_NORMAL}{@link #GL_MAP1_TEXTURE_COORD_1 MAP1_TEXTURE_COORD_1}
{@link #GL_MAP1_TEXTURE_COORD_2 MAP1_TEXTURE_COORD_2}{@link #GL_MAP1_TEXTURE_COORD_3 MAP1_TEXTURE_COORD_3}{@link #GL_MAP1_TEXTURE_COORD_4 MAP1_TEXTURE_COORD_4}
+ * @param u1 the first endpoint of the pre-image of the map + * @param u2 the second endpoint of the pre-image of the map + * @param stride the number of values in each block of storage + * @param order the polynomial order + * @param points a set of {@code order} blocks of storage containing control points + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap1f(@NativeType("GLenum") int target, @NativeType("GLfloat") float u1, @NativeType("GLfloat") float u2, @NativeType("GLint") int stride, @NativeType("GLint") int order, @NativeType("GLfloat const *") FloatBuffer points) { + if (CHECKS) { + check(points, order * stride); + } + nglMap1f(target, u1, u2, stride, order, memAddress(points)); + } + + // --- [ glMap1d ] --- + + /** Unsafe version of: {@link #glMap1d Map1d} */ + public static native void nglMap1d(int target, double u1, double u2, int stride, int order, long points); + + /** + * Double version of {@link #glMap1f Map1f}. + * + * @param target the evaluator target + * @param u1 the first endpoint of the pre-image of the map + * @param u2 the second endpoint of the pre-image of the map + * @param stride the number of values in each block of storage + * @param order the polynomial order + * @param points a set of {@code order} blocks of storage containing control points + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap1d(@NativeType("GLenum") int target, @NativeType("GLdouble") double u1, @NativeType("GLdouble") double u2, @NativeType("GLint") int stride, @NativeType("GLint") int order, @NativeType("GLdouble const *") DoubleBuffer points) { + if (CHECKS) { + check(points, stride * order); + } + nglMap1d(target, u1, u2, stride, order, memAddress(points)); + } + + // --- [ glMap2f ] --- + + /** Unsafe version of: {@link #glMap2f Map2f} */ + public static native void nglMap2f(int target, float u1, float u2, int ustride, int uorder, float v1, float v2, int vstride, int vorder, long points); + + /** + * Bivariate version of {@link #glMap1f Map1f}. + * + * @param target the evaluator target + * @param u1 the first u-dimension endpoint of the pre-image rectangle of the map + * @param u2 the second u-dimension endpoint of the pre-image rectangle of the map + * @param ustride the number of values in the u-dimension in each block of storage + * @param uorder the polynomial order in the u-dimension + * @param v1 the first v-dimension endpoint of the pre-image rectangle of the map + * @param v2 the second v-dimension endpoint of the pre-image rectangle of the map + * @param vstride the number of values in the v-dimension in each block of storage + * @param vorder the polynomial order in the v-dimension + * @param points a set of uorder × vorder blocks of storage containing control points + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap2f(@NativeType("GLenum") int target, @NativeType("GLfloat") float u1, @NativeType("GLfloat") float u2, @NativeType("GLint") int ustride, @NativeType("GLint") int uorder, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2, @NativeType("GLint") int vstride, @NativeType("GLint") int vorder, @NativeType("GLfloat const *") FloatBuffer points) { + if (CHECKS) { + check(points, ustride * uorder * vstride * vorder); + } + nglMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, memAddress(points)); + } + + // --- [ glMap2d ] --- + + /** Unsafe version of: {@link #glMap2d Map2d} */ + public static native void nglMap2d(int target, double u1, double u2, int ustride, int uorder, double v1, double v2, int vstride, int vorder, long points); + + /** + * Double version of {@link #glMap2f Map2f}. + * + * @param target the evaluator target + * @param u1 the first u-dimension endpoint of the pre-image rectangle of the map + * @param u2 the second u-dimension endpoint of the pre-image rectangle of the map + * @param ustride the number of values in the u-dimension in each block of storage + * @param uorder the polynomial order in the u-dimension + * @param v1 the first v-dimension endpoint of the pre-image rectangle of the map + * @param v2 the second v-dimension endpoint of the pre-image rectangle of the map + * @param vstride the number of values in the v-dimension in each block of storage + * @param vorder the polynomial order in the v-dimension + * @param points a set of uorder × vorder blocks of storage containing control points + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap2d(@NativeType("GLenum") int target, @NativeType("GLdouble") double u1, @NativeType("GLdouble") double u2, @NativeType("GLint") int ustride, @NativeType("GLint") int uorder, @NativeType("GLdouble") double v1, @NativeType("GLdouble") double v2, @NativeType("GLint") int vstride, @NativeType("GLint") int vorder, @NativeType("GLdouble const *") DoubleBuffer points) { + if (CHECKS) { + check(points, ustride * uorder * vstride * vorder); + } + nglMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, memAddress(points)); + } + + // --- [ glMapGrid1f ] --- + + /** + * Defines a one-dimensional grid in the map evaluator domain. + * + * @param n the number of partitions of the interval + * @param u1 the first interval endpoint + * @param u2 the second interval endpoint + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glMapGrid1f(@NativeType("GLint") int n, @NativeType("GLfloat") float u1, @NativeType("GLfloat") float u2); + + // --- [ glMapGrid1d ] --- + + /** + * Double version of {@link #glMapGrid1f MapGrid1f}. + * + * @param n the number of partitions of the interval + * @param u1 the first interval endpoint + * @param u2 the second interval endpoint + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glMapGrid1d(@NativeType("GLint") int n, @NativeType("GLdouble") double u1, @NativeType("GLdouble") double u2); + + // --- [ glMapGrid2f ] --- + + /** + * Defines a two-dimensional grid in the map evaluator domain. + * + * @param un the number of partitions of the interval in the u-dimension + * @param u1 the first u-dimension interval endpoint + * @param u2 the second u-dimension interval endpoint + * @param vn the number of partitions of the interval in the v-dimension + * @param v1 the first v-dimension interval endpoint + * @param v2 the second v-dimension interval endpoint + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glMapGrid2f(@NativeType("GLint") int un, @NativeType("GLfloat") float u1, @NativeType("GLfloat") float u2, @NativeType("GLint") int vn, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2); + + // --- [ glMapGrid2d ] --- + + /** + * Double version of {@link #glMapGrid2f MapGrid2f}. + * + * @param un the number of partitions of the interval in the u-dimension + * @param u1 the first u-dimension interval endpoint + * @param u2 the second u-dimension interval endpoint + * @param vn the number of partitions of the interval in the v-dimension + * @param v1 the first v-dimension interval endpoint + * @param v2 the second v-dimension interval endpoint + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glMapGrid2d(@NativeType("GLint") int un, @NativeType("GLdouble") double u1, @NativeType("GLdouble") double u2, @NativeType("GLint") int vn, @NativeType("GLdouble") double v1, @NativeType("GLdouble") double v2); + + // --- [ glMateriali ] --- + + /** + * Sets the integer value of a material parameter. + * + * @param face the material face for which to set the parameter. One of:
{@link #GL_FRONT FRONT}{@link #GL_BACK BACK}{@link #GL_FRONT_AND_BACK FRONT_AND_BACK}
+ * @param pname the parameter to set. Must be:
{@link #GL_SHININESS SHININESS}
+ * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glMateriali(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLint") int param); + + // --- [ glMaterialf ] --- + + /** + * Float version of {@link #glMateriali Materiali}. + * + * @param face the material face for which to set the parameter + * @param pname the parameter to set + * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glMaterialf(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLfloat") float param); + + // --- [ glMaterialiv ] --- + + /** Unsafe version of: {@link #glMaterialiv Materialiv} */ + public static native void nglMaterialiv(int face, int pname, long params); + + /** + * Pointer version of {@link #glMateriali Materiali}. + * + * @param face the material face for which to set the parameter + * @param pname the parameter to set. One of:
{@link #GL_AMBIENT AMBIENT}{@link #GL_DIFFUSE DIFFUSE}{@link #GL_AMBIENT_AND_DIFFUSE AMBIENT_AND_DIFFUSE}{@link #GL_SPECULAR SPECULAR}{@link #GL_EMISSION EMISSION}
+ * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMaterialiv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLint const *") IntBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglMaterialiv(face, pname, memAddress(params)); + } + + // --- [ glMaterialfv ] --- + + /** Unsafe version of: {@link #glMaterialfv Materialfv} */ + public static native void nglMaterialfv(int face, int pname, long params); + + /** + * Pointer version of {@link #glMaterialf Materialf}. + * + * @param face the material face for which to set the parameter + * @param pname the parameter to set + * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMaterialfv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") FloatBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglMaterialfv(face, pname, memAddress(params)); + } + + // --- [ glMatrixMode ] --- + + /** + * Set the current matrix mode. + * + * @param mode the matrix mode. One of:
{@link #GL_MODELVIEW MODELVIEW}{@link #GL_PROJECTION PROJECTION}{@link #GL_TEXTURE TEXTURE}{@link #GL_COLOR COLOR}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glMatrixMode(@NativeType("GLenum") int mode); + + // --- [ glMultMatrixf ] --- + + /** Unsafe version of: {@link #glMultMatrixf MultMatrixf} */ + public static native void nglMultMatrixf(long m); + + /** + * Multiplies the current matrix with a 4 × 4 matrix in column-major order. See {@link #glLoadMatrixf LoadMatrixf} for details. + * + * @param m the matrix data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMultMatrixf(@NativeType("GLfloat const *") FloatBuffer m) { + if (CHECKS) { + check(m, 16); + } + nglMultMatrixf(memAddress(m)); + } + + // --- [ glMultMatrixd ] --- + + /** Unsafe version of: {@link #glMultMatrixd MultMatrixd} */ + public static native void nglMultMatrixd(long m); + + /** + * Double version of {@link #glMultMatrixf MultMatrixf}. + * + * @param m the matrix data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMultMatrixd(@NativeType("GLdouble const *") DoubleBuffer m) { + if (CHECKS) { + check(m, 16); + } + nglMultMatrixd(memAddress(m)); + } + + // --- [ glFrustum ] --- + + /** + * Manipulates the current matrix with a matrix that produces perspective projection, in such a way that the coordinates (lb – n)T + * and (rt – n)T specify the points on the near clipping plane that are mapped to the lower left and upper right corners of the + * window, respectively (assuming that the eye is located at (0 0 0)T). {@code f} gives the distance from the eye to the far clipping + * plane. + * + *

Calling this function is equivalent to calling {@link #glMultMatrixf MultMatrixf} with the following matrix:

+ * + * + * + * + * + * + *
2n / (r - l)0(r + l) / (r - l)0
02n / (t - b)(t + b) / (t - b)0
00- (f + n) / (f - n)- (2fn) / (f - n)
00-10
+ * + * @param l the left frustum plane + * @param r the right frustum plane + * @param b the bottom frustum plane + * @param t the top frustum plane + * @param n the near frustum plane + * @param f the far frustum plane + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glFrustum(@NativeType("GLdouble") double l, @NativeType("GLdouble") double r, @NativeType("GLdouble") double b, @NativeType("GLdouble") double t, @NativeType("GLdouble") double n, @NativeType("GLdouble") double f); + + // --- [ glNewList ] --- + + /** + * Begins the definition of a display list. + * + * @param n a positive integer to which the display list that follows is assigned + * @param mode a symbolic constant that controls the behavior of the GL during display list creation. One of:
{@link #GL_COMPILE COMPILE}{@link #GL_COMPILE_AND_EXECUTE COMPILE_AND_EXECUTE}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glNewList(@NativeType("GLuint") int n, @NativeType("GLenum") int mode); + + // --- [ glEndList ] --- + + /** + * Ends the definition of GL commands to be placed in a display list. It is only when {@code EndList} occurs that the specified display list is actually + * associated with the index indicated with {@link #glNewList NewList}. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glEndList(); + + // --- [ glNormal3f ] --- + + /** + * Sets the current normal. + * + * @param nx the x coordinate of the current normal + * @param ny the y coordinate of the current normal + * @param nz the z coordinate of the current normal + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glNormal3f(@NativeType("GLfloat") float nx, @NativeType("GLfloat") float ny, @NativeType("GLfloat") float nz); + + // --- [ glNormal3b ] --- + + /** + * Byte version of {@link #glNormal3f Normal3f}. + * + * @param nx the x coordinate of the current normal + * @param ny the y coordinate of the current normal + * @param nz the z coordinate of the current normal + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glNormal3b(@NativeType("GLbyte") byte nx, @NativeType("GLbyte") byte ny, @NativeType("GLbyte") byte nz); + + // --- [ glNormal3s ] --- + + /** + * Short version of {@link #glNormal3f Normal3f}. + * + * @param nx the x coordinate of the current normal + * @param ny the y coordinate of the current normal + * @param nz the z coordinate of the current normal + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glNormal3s(@NativeType("GLshort") short nx, @NativeType("GLshort") short ny, @NativeType("GLshort") short nz); + + // --- [ glNormal3i ] --- + + /** + * Integer version of {@link #glNormal3f Normal3f}. + * + * @param nx the x coordinate of the current normal + * @param ny the y coordinate of the current normal + * @param nz the z coordinate of the current normal + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glNormal3i(@NativeType("GLint") int nx, @NativeType("GLint") int ny, @NativeType("GLint") int nz); + + // --- [ glNormal3d ] --- + + /** + * Double version of {@link #glNormal3f Normal3f}. + * + * @param nx the x coordinate of the current normal + * @param ny the y coordinate of the current normal + * @param nz the z coordinate of the current normal + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glNormal3d(@NativeType("GLdouble") double nx, @NativeType("GLdouble") double ny, @NativeType("GLdouble") double nz); + + // --- [ glNormal3fv ] --- + + /** Unsafe version of: {@link #glNormal3fv Normal3fv} */ + public static native void nglNormal3fv(long v); + + /** + * Pointer version of {@link #glNormal3f Normal3f}. + * + * @param v the normal buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3fv(@NativeType("GLfloat const *") FloatBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglNormal3fv(memAddress(v)); + } + + // --- [ glNormal3bv ] --- + + /** Unsafe version of: {@link #glNormal3bv Normal3bv} */ + public static native void nglNormal3bv(long v); + + /** + * Pointer version of {@link #glNormal3b Normal3b}. + * + * @param v the normal buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3bv(@NativeType("GLbyte const *") ByteBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglNormal3bv(memAddress(v)); + } + + // --- [ glNormal3sv ] --- + + /** Unsafe version of: {@link #glNormal3sv Normal3sv} */ + public static native void nglNormal3sv(long v); + + /** + * Pointer version of {@link #glNormal3s Normal3s}. + * + * @param v the normal buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3sv(@NativeType("GLshort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglNormal3sv(memAddress(v)); + } + + // --- [ glNormal3iv ] --- + + /** Unsafe version of: {@link #glNormal3iv Normal3iv} */ + public static native void nglNormal3iv(long v); + + /** + * Pointer version of {@link #glNormal3i Normal3i}. + * + * @param v the normal buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3iv(@NativeType("GLint const *") IntBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglNormal3iv(memAddress(v)); + } + + // --- [ glNormal3dv ] --- + + /** Unsafe version of: {@link #glNormal3dv Normal3dv} */ + public static native void nglNormal3dv(long v); + + /** + * Pointer version of {@link #glNormal3d Normal3d}. + * + * @param v the normal buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3dv(@NativeType("GLdouble const *") DoubleBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglNormal3dv(memAddress(v)); + } + + // --- [ glNormalPointer ] --- + + /** Unsafe version of: {@link #glNormalPointer NormalPointer} */ + public static native void nglNormalPointer(int type, int stride, long pointer); + + /** + * Specifies the location and organization of a normal array. + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the normal array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormalPointer(@NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + nglNormalPointer(type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a normal array. + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the normal array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormalPointer(@NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") long pointer) { + nglNormalPointer(type, stride, pointer); + } + + /** + * Specifies the location and organization of a normal array. + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the normal array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormalPointer(@NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ShortBuffer pointer) { + nglNormalPointer(type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a normal array. + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the normal array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormalPointer(@NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") IntBuffer pointer) { + nglNormalPointer(type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a normal array. + * + * @param type the data type of the values stored in the array. One of:
{@link #GL_BYTE BYTE}{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the normal array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormalPointer(@NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") FloatBuffer pointer) { + nglNormalPointer(type, stride, memAddress(pointer)); + } + + // --- [ glOrtho ] --- + + /** + * Manipulates the current matrix with a matrix that produces parallel projection, in such a way that the coordinates (lb – n)T + * and (rt – n)T specify the points on the near clipping plane that are mapped to the lower left and upper right corners of the + * window, respectively (assuming that the eye is located at (0 0 0)T). {@code f} gives the distance from the eye to the far clipping + * plane. + * + *

Calling this function is equivalent to calling {@link #glMultMatrixf MultMatrixf} with the following matrix:

+ * + * + * + * + * + * + *
2 / (r - l)00- (r + l) / (r - l)
02 / (t - b)0- (t + b) / (t - b)
00- 2 / (f - n)- (f + n) / (f - n)
0001
+ * + * @param l the left frustum plane + * @param r the right frustum plane + * @param b the bottom frustum plane + * @param t the top frustum plane + * @param n the near frustum plane + * @param f the far frustum plane + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glOrtho(@NativeType("GLdouble") double l, @NativeType("GLdouble") double r, @NativeType("GLdouble") double b, @NativeType("GLdouble") double t, @NativeType("GLdouble") double n, @NativeType("GLdouble") double f); + + // --- [ glPassThrough ] --- + + /** + * Inserts a marker when the GL is in feeback mode. {@code token} is returned as if it were a primitive; it is indicated with its own unique identifying + * value. The ordering of any {@code PassThrough} commands with respect to primitive specification is maintained by feedback. {@code PassThrough} may + * not occur between {@link #glBegin Begin} and {@link #glEnd End}. + * + * @param token the marker value to insert + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPassThrough(@NativeType("GLfloat") float token); + + // --- [ glPixelMapfv ] --- + + /** + * Unsafe version of: {@link #glPixelMapfv PixelMapfv} + * + * @param size the map size + */ + public static native void nglPixelMapfv(int map, int size, long values); + + /** + * Sets a pixel map lookup table. + * + * @param map the map to set. One of:
{@link #GL_PIXEL_MAP_I_TO_I PIXEL_MAP_I_TO_I}{@link #GL_PIXEL_MAP_S_TO_S PIXEL_MAP_S_TO_S}{@link #GL_PIXEL_MAP_I_TO_R PIXEL_MAP_I_TO_R}{@link #GL_PIXEL_MAP_I_TO_G PIXEL_MAP_I_TO_G}{@link #GL_PIXEL_MAP_I_TO_B PIXEL_MAP_I_TO_B}
{@link #GL_PIXEL_MAP_I_TO_A PIXEL_MAP_I_TO_A}{@link #GL_PIXEL_MAP_R_TO_R PIXEL_MAP_R_TO_R}{@link #GL_PIXEL_MAP_G_TO_G PIXEL_MAP_G_TO_G}{@link #GL_PIXEL_MAP_B_TO_B PIXEL_MAP_B_TO_B}{@link #GL_PIXEL_MAP_A_TO_A PIXEL_MAP_A_TO_A}
+ * @param size the map size + * @param values the map values + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapfv(@NativeType("GLenum") int map, @NativeType("GLsizei") int size, @NativeType("GLfloat const *") long values) { + nglPixelMapfv(map, size, values); + } + + /** + * Sets a pixel map lookup table. + * + * @param map the map to set. One of:
{@link #GL_PIXEL_MAP_I_TO_I PIXEL_MAP_I_TO_I}{@link #GL_PIXEL_MAP_S_TO_S PIXEL_MAP_S_TO_S}{@link #GL_PIXEL_MAP_I_TO_R PIXEL_MAP_I_TO_R}{@link #GL_PIXEL_MAP_I_TO_G PIXEL_MAP_I_TO_G}{@link #GL_PIXEL_MAP_I_TO_B PIXEL_MAP_I_TO_B}
{@link #GL_PIXEL_MAP_I_TO_A PIXEL_MAP_I_TO_A}{@link #GL_PIXEL_MAP_R_TO_R PIXEL_MAP_R_TO_R}{@link #GL_PIXEL_MAP_G_TO_G PIXEL_MAP_G_TO_G}{@link #GL_PIXEL_MAP_B_TO_B PIXEL_MAP_B_TO_B}{@link #GL_PIXEL_MAP_A_TO_A PIXEL_MAP_A_TO_A}
+ * @param values the map values + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapfv(@NativeType("GLenum") int map, @NativeType("GLfloat const *") FloatBuffer values) { + nglPixelMapfv(map, values.remaining(), memAddress(values)); + } + + // --- [ glPixelMapusv ] --- + + /** + * Unsafe version of: {@link #glPixelMapusv PixelMapusv} + * + * @param size the map size + */ + public static native void nglPixelMapusv(int map, int size, long values); + + /** + * Unsigned short version of {@link #glPixelMapfv PixelMapfv}. + * + * @param map the map to set + * @param size the map size + * @param values the map values + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapusv(@NativeType("GLenum") int map, @NativeType("GLsizei") int size, @NativeType("GLushort const *") long values) { + nglPixelMapusv(map, size, values); + } + + /** + * Unsigned short version of {@link #glPixelMapfv PixelMapfv}. + * + * @param map the map to set + * @param values the map values + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapusv(@NativeType("GLenum") int map, @NativeType("GLushort const *") ShortBuffer values) { + nglPixelMapusv(map, values.remaining(), memAddress(values)); + } + + // --- [ glPixelMapuiv ] --- + + /** + * Unsafe version of: {@link #glPixelMapuiv PixelMapuiv} + * + * @param size the map size + */ + public static native void nglPixelMapuiv(int map, int size, long values); + + /** + * Unsigned integer version of {@link #glPixelMapfv PixelMapfv}. + * + * @param map the map to set + * @param size the map size + * @param values the map values + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapuiv(@NativeType("GLenum") int map, @NativeType("GLsizei") int size, @NativeType("GLuint const *") long values) { + nglPixelMapuiv(map, size, values); + } + + /** + * Unsigned integer version of {@link #glPixelMapfv PixelMapfv}. + * + * @param map the map to set + * @param values the map values + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapuiv(@NativeType("GLenum") int map, @NativeType("GLuint const *") IntBuffer values) { + nglPixelMapuiv(map, values.remaining(), memAddress(values)); + } + + // --- [ glPixelStorei ] --- + + /** + * Sets the integer value of a pixel store parameter. + * + * @param pname the pixel store parameter to set. One of:
{@link GL11C#GL_UNPACK_SWAP_BYTES UNPACK_SWAP_BYTES}{@link GL11C#GL_UNPACK_LSB_FIRST UNPACK_LSB_FIRST}{@link GL11C#GL_UNPACK_ROW_LENGTH UNPACK_ROW_LENGTH}
{@link GL11C#GL_UNPACK_SKIP_ROWS UNPACK_SKIP_ROWS}{@link GL11C#GL_UNPACK_SKIP_PIXELS UNPACK_SKIP_PIXELS}{@link GL11C#GL_UNPACK_ALIGNMENT UNPACK_ALIGNMENT}
{@link GL12#GL_UNPACK_IMAGE_HEIGHT UNPACK_IMAGE_HEIGHT}{@link GL12#GL_UNPACK_SKIP_IMAGES UNPACK_SKIP_IMAGES}{@link GL42#GL_UNPACK_COMPRESSED_BLOCK_WIDTH UNPACK_COMPRESSED_BLOCK_WIDTH}
{@link GL42#GL_UNPACK_COMPRESSED_BLOCK_HEIGHT UNPACK_COMPRESSED_BLOCK_HEIGHT}{@link GL42#GL_UNPACK_COMPRESSED_BLOCK_DEPTH UNPACK_COMPRESSED_BLOCK_DEPTH}{@link GL42#GL_UNPACK_COMPRESSED_BLOCK_SIZE UNPACK_COMPRESSED_BLOCK_SIZE}
+ * @param param the parameter value + * + * @see Reference Page + */ + public static void glPixelStorei(@NativeType("GLenum") int pname, @NativeType("GLint") int param) { + GL11C.glPixelStorei(pname, param); + } + + // --- [ glPixelStoref ] --- + + /** + * Float version of {@link #glPixelStorei PixelStorei}. + * + * @param pname the pixel store parameter to set + * @param param the parameter value + * + * @see Reference Page + */ + public static void glPixelStoref(@NativeType("GLenum") int pname, @NativeType("GLfloat") float param) { + GL11C.glPixelStoref(pname, param); + } + + // --- [ glPixelTransferi ] --- + + /** + * Sets the integer value of a pixel transfer parameter. + * + * @param pname the pixel transfer parameter to set. One of:
{@link #GL_MAP_COLOR MAP_COLOR}{@link #GL_MAP_STENCIL MAP_STENCIL}{@link #GL_INDEX_SHIFT INDEX_SHIFT}{@link #GL_INDEX_OFFSET INDEX_OFFSET}
{@link #GL_RED_SCALE RED_SCALE}{@link #GL_GREEN_SCALE GREEN_SCALE}{@link #GL_BLUE_SCALE BLUE_SCALE}{@link #GL_ALPHA_SCALE ALPHA_SCALE}
{@link #GL_DEPTH_SCALE DEPTH_SCALE}{@link #GL_RED_BIAS RED_BIAS}{@link #GL_GREEN_BIAS GREEN_BIAS}{@link #GL_BLUE_BIAS BLUE_BIAS}
{@link #GL_ALPHA_BIAS ALPHA_BIAS}{@link #GL_DEPTH_BIAS DEPTH_BIAS}{@link ARBImaging#GL_POST_CONVOLUTION_RED_SCALE POST_CONVOLUTION_RED_SCALE}{@link ARBImaging#GL_POST_CONVOLUTION_RED_BIAS POST_CONVOLUTION_RED_BIAS}
{@link ARBImaging#GL_POST_COLOR_MATRIX_RED_SCALE POST_COLOR_MATRIX_RED_SCALE}{@link ARBImaging#GL_POST_COLOR_MATRIX_RED_BIAS POST_COLOR_MATRIX_RED_BIAS}{@link ARBImaging#GL_POST_CONVOLUTION_GREEN_SCALE POST_CONVOLUTION_GREEN_SCALE}{@link ARBImaging#GL_POST_CONVOLUTION_GREEN_BIAS POST_CONVOLUTION_GREEN_BIAS}
{@link ARBImaging#GL_POST_COLOR_MATRIX_GREEN_SCALE POST_COLOR_MATRIX_GREEN_SCALE}{@link ARBImaging#GL_POST_COLOR_MATRIX_GREEN_BIAS POST_COLOR_MATRIX_GREEN_BIAS}{@link ARBImaging#GL_POST_CONVOLUTION_BLUE_SCALE POST_CONVOLUTION_BLUE_SCALE}{@link ARBImaging#GL_POST_CONVOLUTION_BLUE_BIAS POST_CONVOLUTION_BLUE_BIAS}
{@link ARBImaging#GL_POST_COLOR_MATRIX_BLUE_SCALE POST_COLOR_MATRIX_BLUE_SCALE}{@link ARBImaging#GL_POST_COLOR_MATRIX_BLUE_BIAS POST_COLOR_MATRIX_BLUE_BIAS}{@link ARBImaging#GL_POST_CONVOLUTION_ALPHA_SCALE POST_CONVOLUTION_ALPHA_SCALE}{@link ARBImaging#GL_POST_CONVOLUTION_ALPHA_BIAS POST_CONVOLUTION_ALPHA_BIAS}
{@link ARBImaging#GL_POST_COLOR_MATRIX_ALPHA_SCALE POST_COLOR_MATRIX_ALPHA_SCALE}{@link ARBImaging#GL_POST_COLOR_MATRIX_ALPHA_BIAS POST_COLOR_MATRIX_ALPHA_BIAS}
+ * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPixelTransferi(@NativeType("GLenum") int pname, @NativeType("GLint") int param); + + // --- [ glPixelTransferf ] --- + + /** + * Float version of {@link #glPixelTransferi PixelTransferi}. + * + * @param pname the pixel transfer parameter to set + * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPixelTransferf(@NativeType("GLenum") int pname, @NativeType("GLfloat") float param); + + // --- [ glPixelZoom ] --- + + /** + * Controls the conversion of a group of fragments. + * + *

Let (xrp, yrp) be the current raster position. If a particular group is the nth in a row and belongs to the + * mth row, consider the region in window coordinates bounded by the rectangle with corners

+ * + *

(xrp + zxn, yrp + zym) and (xrp + zx(n + 1), yrp + zy(m + 1))

+ * + *

(either zx or zy may be negative). A fragment representing group {@code (n, m)} is produced for each framebuffer pixel inside, or + * on the bottom or left boundary, of this rectangle.

+ * + * @param xfactor the zx factor + * @param yfactor the zy factor + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPixelZoom(@NativeType("GLfloat") float xfactor, @NativeType("GLfloat") float yfactor); + + // --- [ glPointSize ] --- + + /** + * Controls the rasterization of points if no vertex, tessellation control, tessellation evaluation, or geometry shader is active. The default point size is 1.0. + * + * @param size the request size of a point + * + * @see Reference Page + */ + public static void glPointSize(@NativeType("GLfloat") float size) { + GL11C.glPointSize(size); + } + + // --- [ glPolygonMode ] --- + + /** + * Controls the interpretation of polygons for rasterization. + * + *

{@link GL11C#GL_FILL FILL} is the default mode of polygon rasterization. Note that these modes affect only the final rasterization of polygons: in particular, a + * polygon's vertices are lit, and the polygon is clipped and possibly culled before these modes are applied. Polygon antialiasing applies only to the + * {@link GL11C#GL_FILL FILL} state of PolygonMode. For {@link GL11C#GL_POINT POINT} or {@link GL11C#GL_LINE LINE}, point antialiasing or line segment antialiasing, respectively, apply.

+ * + * @param face the face for which to set the rasterizing method. One of:
{@link GL11C#GL_FRONT FRONT}{@link GL11C#GL_BACK BACK}{@link GL11C#GL_FRONT_AND_BACK FRONT_AND_BACK}
+ * @param mode the rasterization mode. One of:
{@link GL11C#GL_POINT POINT}{@link GL11C#GL_LINE LINE}{@link GL11C#GL_FILL FILL}
+ * + * @see Reference Page + */ + public static void glPolygonMode(@NativeType("GLenum") int face, @NativeType("GLenum") int mode) { + GL11C.glPolygonMode(face, mode); + } + + // --- [ glPolygonOffset ] --- + + /** + * The depth values of all fragments generated by the rasterization of a polygon may be offset by a single value that is computed for that polygon. This + * function determines that value. + * + *

{@code factor} scales the maximum depth slope of the polygon, and {@code units} scales an implementation-dependent constant that relates to the usable + * resolution of the depth buffer. The resulting values are summed to produce the polygon offset value.

+ * + * @param factor the maximum depth slope factor + * @param units the constant scale + * + * @see Reference Page + */ + public static void glPolygonOffset(@NativeType("GLfloat") float factor, @NativeType("GLfloat") float units) { + GL11C.glPolygonOffset(factor, units); + } + + // --- [ glPolygonStipple ] --- + + /** Unsafe version of: {@link #glPolygonStipple PolygonStipple} */ + public static native void nglPolygonStipple(long pattern); + + /** + * Defines a polygon stipple. It works much the same way as {@link #glLineStipple LineStipple}, masking out certain fragments produced by rasterization so that they + * are not sent to the next stage of the GL. This is the case regardless of the state of polygon antialiasing. + * + *

If xw and yw are the window coordinates of a rasterized polygon fragment, then that fragment is sent to the next stage of the GL + * if and only if the bit of the pattern (xw mod 32, yw mod 32) is 1.

+ * + *

Polygon stippling may be enabled or disabled with {@link #glEnable Enable} or {@link #glDisable Disable} using the constant {@link #GL_POLYGON_STIPPLE POLYGON_STIPPLE}. When disabled, + * it is as if the stipple pattern were all ones.

+ * + * @param pattern a pointer to memory into which a 32 × 32 pattern is packed + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPolygonStipple(@NativeType("GLubyte const *") ByteBuffer pattern) { + if (CHECKS) { + check(pattern, 128); + } + nglPolygonStipple(memAddress(pattern)); + } + + /** + * Defines a polygon stipple. It works much the same way as {@link #glLineStipple LineStipple}, masking out certain fragments produced by rasterization so that they + * are not sent to the next stage of the GL. This is the case regardless of the state of polygon antialiasing. + * + *

If xw and yw are the window coordinates of a rasterized polygon fragment, then that fragment is sent to the next stage of the GL + * if and only if the bit of the pattern (xw mod 32, yw mod 32) is 1.

+ * + *

Polygon stippling may be enabled or disabled with {@link #glEnable Enable} or {@link #glDisable Disable} using the constant {@link #GL_POLYGON_STIPPLE POLYGON_STIPPLE}. When disabled, + * it is as if the stipple pattern were all ones.

+ * + * @param pattern a pointer to memory into which a 32 × 32 pattern is packed + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPolygonStipple(@NativeType("GLubyte const *") long pattern) { + nglPolygonStipple(pattern); + } + + // --- [ glPushAttrib ] --- + + /** + * Takes a bitwise OR of symbolic constants indicating which groups of state variables to push onto the server attribute stack. Each constant refers to a + * group of state variables. + * + *

Bits set in mask that do not correspond to an attribute group are ignored. The special mask value {@link #GL_ALL_ATTRIB_BITS ALL_ATTRIB_BITS} may be used to push all + * stackable server state.

+ * + *

A {@link #GL_STACK_OVERFLOW STACK_OVERFLOW} error is generated if {@code PushAttrib} is called and the attribute stack depth is equal to the value of + * {@link #GL_MAX_ATTRIB_STACK_DEPTH MAX_ATTRIB_STACK_DEPTH}.

+ * + * @param mask the state variables to push. One or more of:
{@link #GL_ACCUM_BUFFER_BIT ACCUM_BUFFER_BIT}{@link #GL_COLOR_BUFFER_BIT COLOR_BUFFER_BIT}{@link #GL_CURRENT_BIT CURRENT_BIT}{@link #GL_DEPTH_BUFFER_BIT DEPTH_BUFFER_BIT}{@link #GL_ENABLE_BIT ENABLE_BIT}{@link #GL_EVAL_BIT EVAL_BIT}
{@link #GL_FOG_BIT FOG_BIT}{@link #GL_HINT_BIT HINT_BIT}{@link #GL_LIGHTING_BIT LIGHTING_BIT}{@link #GL_LINE_BIT LINE_BIT}{@link #GL_LIST_BIT LIST_BIT}{@link GL13#GL_MULTISAMPLE_BIT MULTISAMPLE_BIT}
{@link #GL_PIXEL_MODE_BIT PIXEL_MODE_BIT}{@link #GL_POINT_BIT POINT_BIT}{@link #GL_POLYGON_BIT POLYGON_BIT}{@link #GL_POLYGON_STIPPLE_BIT POLYGON_STIPPLE_BIT}{@link #GL_SCISSOR_BIT SCISSOR_BIT}{@link #GL_STENCIL_BUFFER_BIT STENCIL_BUFFER_BIT}
{@link #GL_TEXTURE_BIT TEXTURE_BIT}{@link #GL_TRANSFORM_BIT TRANSFORM_BIT}{@link #GL_VIEWPORT_BIT VIEWPORT_BIT}{@link #GL_ALL_ATTRIB_BITS ALL_ATTRIB_BITS}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPushAttrib(@NativeType("GLbitfield") int mask); + + // --- [ glPushClientAttrib ] --- + + /** + * Takes a bitwise OR of symbolic constants indicating which groups of state variables to push onto the client attribute stack. Each constant refers to a + * group of state variables. + * + *

Bits set in mask that do not correspond to an attribute group are ignored. The special mask value {@link #GL_CLIENT_ALL_ATTRIB_BITS CLIENT_ALL_ATTRIB_BITS} may be used to push + * all stackable client state.

+ * + *

A {@link #GL_STACK_OVERFLOW STACK_OVERFLOW} error is generated if {@code PushAttrib} is called and the client attribute stack depth is equal to the value of + * {@link #GL_MAX_CLIENT_ATTRIB_STACK_DEPTH MAX_CLIENT_ATTRIB_STACK_DEPTH}.

+ * + * @param mask the state variables to push. One or more of:
{@link #GL_CLIENT_VERTEX_ARRAY_BIT CLIENT_VERTEX_ARRAY_BIT}{@link #GL_CLIENT_PIXEL_STORE_BIT CLIENT_PIXEL_STORE_BIT}{@link #GL_CLIENT_ALL_ATTRIB_BITS CLIENT_ALL_ATTRIB_BITS}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPushClientAttrib(@NativeType("GLbitfield") int mask); + + // --- [ glPopAttrib ] --- + + /** + * Resets the values of those state variables that were saved with the last {@link #glPushAttrib PushAttrib}. Those not saved remain unchanged. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPopAttrib(); + + // --- [ glPopClientAttrib ] --- + + /** + * Resets the values of those state variables that were saved with the last {@link #glPushClientAttrib PushClientAttrib}. Those not saved remain unchanged. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPopClientAttrib(); + + // --- [ glPopMatrix ] --- + + /** + * Pops the top entry off the current matrix stack, replacing the current matrix with the matrix that was the second entry in the stack. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPopMatrix(); + + // --- [ glPopName ] --- + + /** + * Pops one name off the top of the selection name stack. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPopName(); + + // --- [ glPrioritizeTextures ] --- + + /** + * Unsafe version of: {@link #glPrioritizeTextures PrioritizeTextures} + * + * @param n the number of texture object priorities to set + */ + public static native void nglPrioritizeTextures(int n, long textures, long priorities); + + /** + * Sets the priority of texture objects. Each priority value is clamped to the range [0, 1] before it is assigned. Zero indicates the lowest priority, with + * the least likelihood of being resident. One indicates the highest priority, with the greatest likelihood of being resident. + * + * @param textures an array of texture object names + * @param priorities an array of texture object priorities + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPrioritizeTextures(@NativeType("GLuint const *") IntBuffer textures, @NativeType("GLfloat const *") FloatBuffer priorities) { + if (CHECKS) { + check(priorities, textures.remaining()); + } + nglPrioritizeTextures(textures.remaining(), memAddress(textures), memAddress(priorities)); + } + + // --- [ glPushMatrix ] --- + + /** + * Pushes the current matrix stack down by one, duplicating the current matrix in both the top of the stack and the entry below it. + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPushMatrix(); + + // --- [ glPushName ] --- + + /** + * Causes {@code name} to be pushed onto the selection name stack. + * + * @param name the name to push + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glPushName(@NativeType("GLuint") int name); + + // --- [ glRasterPos2i ] --- + + /** + * Sets the two-dimensional current raster position. {@code z} is implicitly set to 0 and {@code w} implicitly set to 1. + * + *

The coordinates are treated as if they were specified in a Vertex command. If a vertex shader is active, this vertex shader is executed using the x, y, + * z, and w coordinates as the object coordinates of the vertex. Otherwise, the x, y, z, and w coordinates are transformed by the current model-view and + * projection matrices. These coordinates, along with current values, are used to generate primary and secondary colors and texture coordinates just as is + * done for a vertex. The colors and texture coordinates so produced replace the colors and texture coordinates stored in the current raster position's + * associated data.

+ * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos2i(@NativeType("GLint") int x, @NativeType("GLint") int y); + + // --- [ glRasterPos2s ] --- + + /** + * Short version of {@link #glRasterPos2i RasterPos2i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos2s(@NativeType("GLshort") short x, @NativeType("GLshort") short y); + + // --- [ glRasterPos2f ] --- + + /** + * Float version of {@link #glRasterPos2i RasterPos2i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos2f(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y); + + // --- [ glRasterPos2d ] --- + + /** + * Double version of {@link #glRasterPos2i RasterPos2i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos2d(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y); + + // --- [ glRasterPos2iv ] --- + + /** Unsafe version of: {@link #glRasterPos2iv RasterPos2iv} */ + public static native void nglRasterPos2iv(long coords); + + /** + * Pointer version of {@link #glRasterPos2i RasterPos2i}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2iv(@NativeType("GLint const *") IntBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglRasterPos2iv(memAddress(coords)); + } + + // --- [ glRasterPos2sv ] --- + + /** Unsafe version of: {@link #glRasterPos2sv RasterPos2sv} */ + public static native void nglRasterPos2sv(long coords); + + /** + * Pointer version of {@link #glRasterPos2s RasterPos2s}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2sv(@NativeType("GLshort const *") ShortBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglRasterPos2sv(memAddress(coords)); + } + + // --- [ glRasterPos2fv ] --- + + /** Unsafe version of: {@link #glRasterPos2fv RasterPos2fv} */ + public static native void nglRasterPos2fv(long coords); + + /** + * Pointer version of {@link #glRasterPos2f RasterPos2f}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2fv(@NativeType("GLfloat const *") FloatBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglRasterPos2fv(memAddress(coords)); + } + + // --- [ glRasterPos2dv ] --- + + /** Unsafe version of: {@link #glRasterPos2dv RasterPos2dv} */ + public static native void nglRasterPos2dv(long coords); + + /** + * Pointer version of {@link #glRasterPos2d RasterPos2d}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2dv(@NativeType("GLdouble const *") DoubleBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglRasterPos2dv(memAddress(coords)); + } + + // --- [ glRasterPos3i ] --- + + /** + * Sets the three-dimensional current raster position. {@code w} is implicitly set to 1. See {@link #glRasterPos2i RasterPos2i} for more details. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos3i(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLint") int z); + + // --- [ glRasterPos3s ] --- + + /** + * Short version of {@link #glRasterPos3i RasterPos3i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos3s(@NativeType("GLshort") short x, @NativeType("GLshort") short y, @NativeType("GLshort") short z); + + // --- [ glRasterPos3f ] --- + + /** + * Float version of {@link #glRasterPos3i RasterPos3i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos3f(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y, @NativeType("GLfloat") float z); + + // --- [ glRasterPos3d ] --- + + /** + * Double version of {@link #glRasterPos3i RasterPos3i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos3d(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y, @NativeType("GLdouble") double z); + + // --- [ glRasterPos3iv ] --- + + /** Unsafe version of: {@link #glRasterPos3iv RasterPos3iv} */ + public static native void nglRasterPos3iv(long coords); + + /** + * Pointer version of {@link #glRasterPos3i RasterPos3i}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3iv(@NativeType("GLint const *") IntBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglRasterPos3iv(memAddress(coords)); + } + + // --- [ glRasterPos3sv ] --- + + /** Unsafe version of: {@link #glRasterPos3sv RasterPos3sv} */ + public static native void nglRasterPos3sv(long coords); + + /** + * Pointer version of {@link #glRasterPos3s RasterPos3s}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3sv(@NativeType("GLshort const *") ShortBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglRasterPos3sv(memAddress(coords)); + } + + // --- [ glRasterPos3fv ] --- + + /** Unsafe version of: {@link #glRasterPos3fv RasterPos3fv} */ + public static native void nglRasterPos3fv(long coords); + + /** + * Pointer version of {@link #glRasterPos3f RasterPos3f}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3fv(@NativeType("GLfloat const *") FloatBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglRasterPos3fv(memAddress(coords)); + } + + // --- [ glRasterPos3dv ] --- + + /** Unsafe version of: {@link #glRasterPos3dv RasterPos3dv} */ + public static native void nglRasterPos3dv(long coords); + + /** + * Pointer version of {@link #glRasterPos3d RasterPos3d}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3dv(@NativeType("GLdouble const *") DoubleBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglRasterPos3dv(memAddress(coords)); + } + + // --- [ glRasterPos4i ] --- + + /** + * Sets the four-dimensional current raster position. See {@link #glRasterPos2i RasterPos2i} for more details. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * @param w the {@code w} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos4i(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLint") int z, @NativeType("GLint") int w); + + // --- [ glRasterPos4s ] --- + + /** + * Short version of {@link #glRasterPos4i RasterPos4i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * @param w the {@code w} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos4s(@NativeType("GLshort") short x, @NativeType("GLshort") short y, @NativeType("GLshort") short z, @NativeType("GLshort") short w); + + // --- [ glRasterPos4f ] --- + + /** + * Float version of RasterPos4i. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * @param w the {@code w} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos4f(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y, @NativeType("GLfloat") float z, @NativeType("GLfloat") float w); + + // --- [ glRasterPos4d ] --- + + /** + * Double version of {@link #glRasterPos4i RasterPos4i}. + * + * @param x the {@code x} raster coordinate + * @param y the {@code y} raster coordinate + * @param z the {@code z} raster coordinate + * @param w the {@code w} raster coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRasterPos4d(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y, @NativeType("GLdouble") double z, @NativeType("GLdouble") double w); + + // --- [ glRasterPos4iv ] --- + + /** Unsafe version of: {@link #glRasterPos4iv RasterPos4iv} */ + public static native void nglRasterPos4iv(long coords); + + /** + * Pointer version of {@link #glRasterPos4i RasterPos4i}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4iv(@NativeType("GLint const *") IntBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglRasterPos4iv(memAddress(coords)); + } + + // --- [ glRasterPos4sv ] --- + + /** Unsafe version of: {@link #glRasterPos4sv RasterPos4sv} */ + public static native void nglRasterPos4sv(long coords); + + /** + * Pointer version of {@link #glRasterPos4s RasterPos4s}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4sv(@NativeType("GLshort const *") ShortBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglRasterPos4sv(memAddress(coords)); + } + + // --- [ glRasterPos4fv ] --- + + /** Unsafe version of: {@link #glRasterPos4fv RasterPos4fv} */ + public static native void nglRasterPos4fv(long coords); + + /** + * Pointer version of {@link #glRasterPos4f RasterPos4f}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4fv(@NativeType("GLfloat const *") FloatBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglRasterPos4fv(memAddress(coords)); + } + + // --- [ glRasterPos4dv ] --- + + /** Unsafe version of: {@link #glRasterPos4dv RasterPos4dv} */ + public static native void nglRasterPos4dv(long coords); + + /** + * Pointer version of {@link #glRasterPos4d RasterPos4d}. + * + * @param coords the raster position buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4dv(@NativeType("GLdouble const *") DoubleBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglRasterPos4dv(memAddress(coords)); + } + + // --- [ glReadBuffer ] --- + + /** + * Defines the color buffer from which values are obtained. + * + *

Acceptable values for {@code src} depend on whether the GL is using the default framebuffer (i.e., {@link GL30#GL_DRAW_FRAMEBUFFER_BINDING DRAW_FRAMEBUFFER_BINDING} is zero), or + * a framebuffer object (i.e., {@link GL30#GL_DRAW_FRAMEBUFFER_BINDING DRAW_FRAMEBUFFER_BINDING} is non-zero). In the initial state, the GL is bound to the default framebuffer.

+ * + * @param src the color buffer to read from. One of:
{@link GL11C#GL_NONE NONE}{@link GL11C#GL_FRONT_LEFT FRONT_LEFT}{@link GL11C#GL_FRONT_RIGHT FRONT_RIGHT}{@link GL11C#GL_BACK_LEFT BACK_LEFT}{@link GL11C#GL_BACK_RIGHT BACK_RIGHT}{@link GL11C#GL_FRONT FRONT}{@link GL11C#GL_BACK BACK}{@link GL11C#GL_LEFT LEFT}
{@link GL11C#GL_RIGHT RIGHT}{@link GL11C#GL_FRONT_AND_BACK FRONT_AND_BACK}{@link GL30#GL_COLOR_ATTACHMENT0 COLOR_ATTACHMENT0}GL30.GL_COLOR_ATTACHMENT[1-15]
+ * + * @see Reference Page + */ + public static void glReadBuffer(@NativeType("GLenum") int src) { + GL11C.glReadBuffer(src); + } + + // --- [ glReadPixels ] --- + + /** Unsafe version of: {@link #glReadPixels ReadPixels} */ + public static void nglReadPixels(int x, int y, int width, int height, int format, int type, long pixels) { + GL11C.nglReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * ReadPixels obtains values from the selected read buffer from each pixel with lower left hand corner at {@code (x + i, y + j)} for {@code 0 <= i < width} + * and {@code 0 <= j < height}; this pixel is said to be the ith pixel in the jth row. If any of these pixels lies outside of the + * window allocated to the current GL context, or outside of the image attached to the currently bound read framebuffer object, then the values obtained + * for those pixels are undefined. When {@link GL30#GL_READ_FRAMEBUFFER_BINDING READ_FRAMEBUFFER_BINDING} is zero, values are also undefined for individual pixels that are not owned by + * the current context. Otherwise, {@code ReadPixels} obtains values from the selected buffer, regardless of how those values were placed there. + * + * @param x the left pixel coordinate + * @param y the lower pixel coordinate + * @param width the number of pixels to read in the x-dimension + * @param height the number of pixels to read in the y-dimension + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels a buffer in which to place the returned pixel data + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") ByteBuffer pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * ReadPixels obtains values from the selected read buffer from each pixel with lower left hand corner at {@code (x + i, y + j)} for {@code 0 <= i < width} + * and {@code 0 <= j < height}; this pixel is said to be the ith pixel in the jth row. If any of these pixels lies outside of the + * window allocated to the current GL context, or outside of the image attached to the currently bound read framebuffer object, then the values obtained + * for those pixels are undefined. When {@link GL30#GL_READ_FRAMEBUFFER_BINDING READ_FRAMEBUFFER_BINDING} is zero, values are also undefined for individual pixels that are not owned by + * the current context. Otherwise, {@code ReadPixels} obtains values from the selected buffer, regardless of how those values were placed there. + * + * @param x the left pixel coordinate + * @param y the lower pixel coordinate + * @param width the number of pixels to read in the x-dimension + * @param height the number of pixels to read in the y-dimension + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels a buffer in which to place the returned pixel data + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") long pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * ReadPixels obtains values from the selected read buffer from each pixel with lower left hand corner at {@code (x + i, y + j)} for {@code 0 <= i < width} + * and {@code 0 <= j < height}; this pixel is said to be the ith pixel in the jth row. If any of these pixels lies outside of the + * window allocated to the current GL context, or outside of the image attached to the currently bound read framebuffer object, then the values obtained + * for those pixels are undefined. When {@link GL30#GL_READ_FRAMEBUFFER_BINDING READ_FRAMEBUFFER_BINDING} is zero, values are also undefined for individual pixels that are not owned by + * the current context. Otherwise, {@code ReadPixels} obtains values from the selected buffer, regardless of how those values were placed there. + * + * @param x the left pixel coordinate + * @param y the lower pixel coordinate + * @param width the number of pixels to read in the x-dimension + * @param height the number of pixels to read in the y-dimension + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels a buffer in which to place the returned pixel data + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") ShortBuffer pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * ReadPixels obtains values from the selected read buffer from each pixel with lower left hand corner at {@code (x + i, y + j)} for {@code 0 <= i < width} + * and {@code 0 <= j < height}; this pixel is said to be the ith pixel in the jth row. If any of these pixels lies outside of the + * window allocated to the current GL context, or outside of the image attached to the currently bound read framebuffer object, then the values obtained + * for those pixels are undefined. When {@link GL30#GL_READ_FRAMEBUFFER_BINDING READ_FRAMEBUFFER_BINDING} is zero, values are also undefined for individual pixels that are not owned by + * the current context. Otherwise, {@code ReadPixels} obtains values from the selected buffer, regardless of how those values were placed there. + * + * @param x the left pixel coordinate + * @param y the lower pixel coordinate + * @param width the number of pixels to read in the x-dimension + * @param height the number of pixels to read in the y-dimension + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels a buffer in which to place the returned pixel data + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") IntBuffer pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * ReadPixels obtains values from the selected read buffer from each pixel with lower left hand corner at {@code (x + i, y + j)} for {@code 0 <= i < width} + * and {@code 0 <= j < height}; this pixel is said to be the ith pixel in the jth row. If any of these pixels lies outside of the + * window allocated to the current GL context, or outside of the image attached to the currently bound read framebuffer object, then the values obtained + * for those pixels are undefined. When {@link GL30#GL_READ_FRAMEBUFFER_BINDING READ_FRAMEBUFFER_BINDING} is zero, values are also undefined for individual pixels that are not owned by + * the current context. Otherwise, {@code ReadPixels} obtains values from the selected buffer, regardless of how those values were placed there. + * + * @param x the left pixel coordinate + * @param y the lower pixel coordinate + * @param width the number of pixels to read in the x-dimension + * @param height the number of pixels to read in the y-dimension + * @param format the pixel format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels a buffer in which to place the returned pixel data + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") FloatBuffer pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + // --- [ glRecti ] --- + + /** + * Specifies a rectangle as two corner vertices. The effect of the Rect command + * + *

{@code Rect(x1, y1, x2, y2);}

+ * + *

is exactly the same as the following sequence of commands: + * {@code + * Begin(POLYGON); + * Vertex2(x1, y1); + * Vertex2(x2, y1); + * Vertex2(x2, y2); + * Vertex2(x1, y2); + * End();}

+ * + *

The appropriate Vertex2 command would be invoked depending on which of the Rect commands is issued.

+ * + * @param x1 the x coordinate of the first corner vertex + * @param y1 the y coordinate of the first corner vertex + * @param x2 the x coordinate of the second corner vertex + * @param y2 the y coordinate of the second corner vertex + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRecti(@NativeType("GLint") int x1, @NativeType("GLint") int y1, @NativeType("GLint") int x2, @NativeType("GLint") int y2); + + // --- [ glRects ] --- + + /** + * Short version of {@link #glRecti Recti}. + * + * @param x1 the x coordinate of the first corner vertex + * @param y1 the y coordinate of the first corner vertex + * @param x2 the x coordinate of the second corner vertex + * @param y2 the y coordinate of the second corner vertex + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRects(@NativeType("GLshort") short x1, @NativeType("GLshort") short y1, @NativeType("GLshort") short x2, @NativeType("GLshort") short y2); + + // --- [ glRectf ] --- + + /** + * Float version of {@link #glRecti Recti}. + * + * @param x1 the x coordinate of the first corner vertex + * @param y1 the y coordinate of the first corner vertex + * @param x2 the x coordinate of the second corner vertex + * @param y2 the y coordinate of the second corner vertex + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRectf(@NativeType("GLfloat") float x1, @NativeType("GLfloat") float y1, @NativeType("GLfloat") float x2, @NativeType("GLfloat") float y2); + + // --- [ glRectd ] --- + + /** + * Double version of {@link #glRecti Recti}. + * + * @param x1 the x coordinate of the first corner vertex + * @param y1 the y coordinate of the first corner vertex + * @param x2 the x coordinate of the second corner vertex + * @param y2 the y coordinate of the second corner vertex + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRectd(@NativeType("GLdouble") double x1, @NativeType("GLdouble") double y1, @NativeType("GLdouble") double x2, @NativeType("GLdouble") double y2); + + // --- [ glRectiv ] --- + + /** Unsafe version of: {@link #glRectiv Rectiv} */ + public static native void nglRectiv(long v1, long v2); + + /** + * Pointer version of {@link #glRecti Recti}. + * + * @param v1 the first vertex buffer + * @param v2 the second vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectiv(@NativeType("GLint const *") IntBuffer v1, @NativeType("GLint const *") IntBuffer v2) { + if (CHECKS) { + check(v1, 2); + check(v2, 2); + } + nglRectiv(memAddress(v1), memAddress(v2)); + } + + // --- [ glRectsv ] --- + + /** Unsafe version of: {@link #glRectsv Rectsv} */ + public static native void nglRectsv(long v1, long v2); + + /** + * Pointer version of {@link #glRects Rects}. + * + * @param v1 the first vertex buffer + * @param v2 the second vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectsv(@NativeType("GLshort const *") ShortBuffer v1, @NativeType("GLshort const *") ShortBuffer v2) { + if (CHECKS) { + check(v1, 2); + check(v2, 2); + } + nglRectsv(memAddress(v1), memAddress(v2)); + } + + // --- [ glRectfv ] --- + + /** Unsafe version of: {@link #glRectfv Rectfv} */ + public static native void nglRectfv(long v1, long v2); + + /** + * Pointer version of {@link #glRectf Rectf}. + * + * @param v1 the first vertex buffer + * @param v2 the second vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectfv(@NativeType("GLfloat const *") FloatBuffer v1, @NativeType("GLfloat const *") FloatBuffer v2) { + if (CHECKS) { + check(v1, 2); + check(v2, 2); + } + nglRectfv(memAddress(v1), memAddress(v2)); + } + + // --- [ glRectdv ] --- + + /** Unsafe version of: {@link #glRectdv Rectdv} */ + public static native void nglRectdv(long v1, long v2); + + /** + * Pointer version of {@link #glRectd Rectd}. + * + * @param v1 the first vertex buffer + * @param v2 the second vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectdv(@NativeType("GLdouble const *") DoubleBuffer v1, @NativeType("GLdouble const *") DoubleBuffer v2) { + if (CHECKS) { + check(v1, 2); + check(v2, 2); + } + nglRectdv(memAddress(v1), memAddress(v2)); + } + + // --- [ glRenderMode ] --- + + /** + * Sets the current render mode. The default is {@link #GL_RENDER RENDER}. + * + * @param mode the render mode. One of:
{@link #GL_RENDER RENDER}{@link #GL_SELECT SELECT}{@link #GL_FEEDBACK FEEDBACK}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("GLint") + public static native int glRenderMode(@NativeType("GLenum") int mode); + + // --- [ glRotatef ] --- + + /** + * Manipulates the current matrix with a rotation matrix. + * + *

{@code angle} gives an angle of rotation in degrees; the coordinates of a vector v are given by v = (x y z)T. The computed matrix + * is a counter-clockwise rotation about the line through the origin with the specified axis when that axis is pointing up (i.e. the right-hand rule + * determines the sense of the rotation angle). The matrix is thus

+ * + * + * + * + * + * + *
R0
0
0
0001
+ * + *

Let u = v / ||v|| = (x' y' z')T. If S =

+ * + * + * + * + * + *
0-z'y'
z'0-x'
-y'x'0
+ * + *

then R = uuT + cos(angle)(I - uuT) + sin(angle)S

+ * + * @param angle the angle of rotation in degrees + * @param x the x coordinate of the rotation vector + * @param y the y coordinate of the rotation vector + * @param z the z coordinate of the rotation vector + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRotatef(@NativeType("GLfloat") float angle, @NativeType("GLfloat") float x, @NativeType("GLfloat") float y, @NativeType("GLfloat") float z); + + // --- [ glRotated ] --- + + /** + * Double version of {@link #glRotatef Rotatef}. + * + * @param angle the angle of rotation in degrees + * @param x the x coordinate of the rotation vector + * @param y the y coordinate of the rotation vector + * @param z the z coordinate of the rotation vector + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glRotated(@NativeType("GLdouble") double angle, @NativeType("GLdouble") double x, @NativeType("GLdouble") double y, @NativeType("GLdouble") double z); + + // --- [ glScalef ] --- + + /** + * Manipulates the current matrix with a general scaling matrix along the x-, y- and z- axes. + * + *

Calling this function is equivalent to calling {@link #glMultMatrixf MultMatrixf} with the following matrix:

+ * + * + * + * + * + * + *
x000
0y00
00z0
0001
+ * + * @param x the x-axis scaling factor + * @param y the y-axis scaling factor + * @param z the z-axis scaling factor + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glScalef(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y, @NativeType("GLfloat") float z); + + // --- [ glScaled ] --- + + /** + * Double version of {@link #glScalef Scalef}. + * + * @param x the x-axis scaling factor + * @param y the y-axis scaling factor + * @param z the z-axis scaling factor + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glScaled(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y, @NativeType("GLdouble") double z); + + // --- [ glScissor ] --- + + /** + * Defines the scissor rectangle for all viewports. The scissor test is enabled or disabled for all viewports using {@link #glEnable Enable} or {@link #glDisable Disable} + * with the symbolic constant {@link GL11C#GL_SCISSOR_TEST SCISSOR_TEST}. When disabled, it is as if the scissor test always passes. When enabled, if + * left ≤ xw < left + width and bottom ≤ yw < bottom + height for the scissor rectangle, then the scissor + * test passes. Otherwise, the test fails and the fragment is discarded. + * + * @param x the left scissor rectangle coordinate + * @param y the bottom scissor rectangle coordinate + * @param width the scissor rectangle width + * @param height the scissor rectangle height + * + * @see Reference Page + */ + public static void glScissor(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height) { + GL11C.glScissor(x, y, width, height); + } + + // --- [ glSelectBuffer ] --- + + /** + * Unsafe version of: {@link #glSelectBuffer SelectBuffer} + * + * @param size the maximum number of values that can be stored in {@code buffer} + */ + public static native void nglSelectBuffer(int size, long buffer); + + /** + * Sets the selection array. + * + * @param buffer an array of unsigned integers to be potentially filled names + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glSelectBuffer(@NativeType("GLuint *") IntBuffer buffer) { + nglSelectBuffer(buffer.remaining(), memAddress(buffer)); + } + + // --- [ glShadeModel ] --- + + /** + * Sets the current shade mode. The initial value of the shade mode is {@link #GL_SMOOTH SMOOTH}. + * + *

If mode is {@link #GL_SMOOTH SMOOTH}, vertex colors are treated individually. If mode is {@link #GL_FLAT FLAT}, flatshading is enabled and colors are taken from the + * provoking vertex of the primitive. The colors selected are those derived from current values, generated by lighting, or generated by vertex shading, if + * lighting is disabled, enabled, or a vertex shader is in use, respectively.

+ * + * @param mode the shade mode. One of:
{@link #GL_SMOOTH SMOOTH}{@link #GL_FLAT FLAT}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glShadeModel(@NativeType("GLenum") int mode); + + // --- [ glStencilFunc ] --- + + /** + * Controls the stencil test. + * + *

{@code ref} is an integer reference value that is used in the unsigned stencil comparison. Stencil comparison operations and queries of {@code ref} + * clamp its value to the range [0, 2s – 1], where s is the number of bits in the stencil buffer attached to the draw framebuffer. The s + * least significant bits of {@code mask} are bitwise ANDed with both the reference and the stored stencil value, and the resulting masked values are those that + * participate in the comparison controlled by {@code func}.

+ * + * @param func the stencil comparison function. One of:
{@link GL11C#GL_NEVER NEVER}{@link GL11C#GL_ALWAYS ALWAYS}{@link GL11C#GL_LESS LESS}{@link GL11C#GL_LEQUAL LEQUAL}{@link GL11C#GL_EQUAL EQUAL}{@link GL11C#GL_GEQUAL GEQUAL}{@link GL11C#GL_GREATER GREATER}{@link GL11C#GL_NOTEQUAL NOTEQUAL}
+ * @param ref the reference value + * @param mask the stencil comparison mask + * + * @see Reference Page + */ + public static void glStencilFunc(@NativeType("GLenum") int func, @NativeType("GLint") int ref, @NativeType("GLuint") int mask) { + GL11C.glStencilFunc(func, ref, mask); + } + + // --- [ glStencilMask ] --- + + /** + * Masks the writing of particular bits into the stencil plans. + * + *

The least significant s bits of {@code mask}, where s is the number of bits in the stencil buffer, specify an integer mask. Where a 1 appears in this + * mask, the corresponding bit in the stencil buffer is written; where a 0 appears, the bit is not written.

+ * + * @param mask the stencil mask + * + * @see Reference Page + */ + public static void glStencilMask(@NativeType("GLuint") int mask) { + GL11C.glStencilMask(mask); + } + + // --- [ glStencilOp ] --- + + /** + * Indicates what happens to the stored stencil value if this or certain subsequent tests fail or pass. + * + *

The supported actions are {@link GL11C#GL_KEEP KEEP}, {@link GL11C#GL_ZERO ZERO}, {@link GL11C#GL_REPLACE REPLACE}, {@link GL11C#GL_INCR INCR}, {@link GL11C#GL_DECR DECR}, {@link GL11C#GL_INVERT INVERT}, + * {@link GL14#GL_INCR_WRAP INCR_WRAP} and {@link GL14#GL_DECR_WRAP DECR_WRAP}. These correspond to keeping the current value, setting to zero, replacing with the reference value, + * incrementing with saturation, decrementing with saturation, bitwise inverting it, incrementing without saturation, and decrementing without saturation.

+ * + *

For purposes of increment and decrement, the stencil bits are considered as an unsigned integer. Incrementing or decrementing with saturation clamps + * the stencil value at 0 and the maximum representable value. Incrementing or decrementing without saturation will wrap such that incrementing the maximum + * representable value results in 0, and decrementing 0 results in the maximum representable value.

+ * + * @param sfail the action to take if the stencil test fails + * @param dpfail the action to take if the depth buffer test fails + * @param dppass the action to take if the depth buffer test passes + * + * @see Reference Page + */ + public static void glStencilOp(@NativeType("GLenum") int sfail, @NativeType("GLenum") int dpfail, @NativeType("GLenum") int dppass) { + GL11C.glStencilOp(sfail, dpfail, dppass); + } + + // --- [ glTexCoord1f ] --- + + /** + * Sets the current one-dimensional texture coordinate. {@code t} and {@code r} are implicitly set to 0 and {@code q} to 1. + * + * @param s the s component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord1f(@NativeType("GLfloat") float s); + + // --- [ glTexCoord1s ] --- + + /** + * Short version of {@link #glTexCoord1f TexCoord1f}. + * + * @param s the s component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord1s(@NativeType("GLshort") short s); + + // --- [ glTexCoord1i ] --- + + /** + * Integer version of {@link #glTexCoord1f TexCoord1f}. + * + * @param s the s component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord1i(@NativeType("GLint") int s); + + // --- [ glTexCoord1d ] --- + + /** + * Double version of {@link #glTexCoord1f TexCoord1f}. + * + * @param s the s component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord1d(@NativeType("GLdouble") double s); + + // --- [ glTexCoord1fv ] --- + + /** Unsafe version of: {@link #glTexCoord1fv TexCoord1fv} */ + public static native void nglTexCoord1fv(long v); + + /** + * Pointer version of {@link #glTexCoord1f TexCoord1f}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1fv(@NativeType("GLfloat const *") FloatBuffer v) { + if (CHECKS) { + check(v, 1); + } + nglTexCoord1fv(memAddress(v)); + } + + // --- [ glTexCoord1sv ] --- + + /** Unsafe version of: {@link #glTexCoord1sv TexCoord1sv} */ + public static native void nglTexCoord1sv(long v); + + /** + * Pointer version of {@link #glTexCoord1s TexCoord1s}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1sv(@NativeType("GLshort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 1); + } + nglTexCoord1sv(memAddress(v)); + } + + // --- [ glTexCoord1iv ] --- + + /** Unsafe version of: {@link #glTexCoord1iv TexCoord1iv} */ + public static native void nglTexCoord1iv(long v); + + /** + * Pointer version of {@link #glTexCoord1i TexCoord1i}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1iv(@NativeType("GLint const *") IntBuffer v) { + if (CHECKS) { + check(v, 1); + } + nglTexCoord1iv(memAddress(v)); + } + + // --- [ glTexCoord1dv ] --- + + /** Unsafe version of: {@link #glTexCoord1dv TexCoord1dv} */ + public static native void nglTexCoord1dv(long v); + + /** + * Pointer version of {@link #glTexCoord1d TexCoord1d}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1dv(@NativeType("GLdouble const *") DoubleBuffer v) { + if (CHECKS) { + check(v, 1); + } + nglTexCoord1dv(memAddress(v)); + } + + // --- [ glTexCoord2f ] --- + + /** + * Sets the current two-dimensional texture coordinate. {@code r} is implicitly set to 0 and {@code q} to 1. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord2f(@NativeType("GLfloat") float s, @NativeType("GLfloat") float t); + + // --- [ glTexCoord2s ] --- + + /** + * Short version of {@link #glTexCoord2f TexCoord2f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord2s(@NativeType("GLshort") short s, @NativeType("GLshort") short t); + + // --- [ glTexCoord2i ] --- + + /** + * Integer version of {@link #glTexCoord2f TexCoord2f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord2i(@NativeType("GLint") int s, @NativeType("GLint") int t); + + // --- [ glTexCoord2d ] --- + + /** + * Double version of {@link #glTexCoord2f TexCoord2f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord2d(@NativeType("GLdouble") double s, @NativeType("GLdouble") double t); + + // --- [ glTexCoord2fv ] --- + + /** Unsafe version of: {@link #glTexCoord2fv TexCoord2fv} */ + public static native void nglTexCoord2fv(long v); + + /** + * Pointer version of {@link #glTexCoord2f TexCoord2f}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2fv(@NativeType("GLfloat const *") FloatBuffer v) { + if (CHECKS) { + check(v, 2); + } + nglTexCoord2fv(memAddress(v)); + } + + // --- [ glTexCoord2sv ] --- + + /** Unsafe version of: {@link #glTexCoord2sv TexCoord2sv} */ + public static native void nglTexCoord2sv(long v); + + /** + * Pointer version of {@link #glTexCoord2s TexCoord2s}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2sv(@NativeType("GLshort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 2); + } + nglTexCoord2sv(memAddress(v)); + } + + // --- [ glTexCoord2iv ] --- + + /** Unsafe version of: {@link #glTexCoord2iv TexCoord2iv} */ + public static native void nglTexCoord2iv(long v); + + /** + * Pointer version of {@link #glTexCoord2i TexCoord2i}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2iv(@NativeType("GLint const *") IntBuffer v) { + if (CHECKS) { + check(v, 2); + } + nglTexCoord2iv(memAddress(v)); + } + + // --- [ glTexCoord2dv ] --- + + /** Unsafe version of: {@link #glTexCoord2dv TexCoord2dv} */ + public static native void nglTexCoord2dv(long v); + + /** + * Pointer version of {@link #glTexCoord2d TexCoord2d}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2dv(@NativeType("GLdouble const *") DoubleBuffer v) { + if (CHECKS) { + check(v, 2); + } + nglTexCoord2dv(memAddress(v)); + } + + // --- [ glTexCoord3f ] --- + + /** + * Sets the current three-dimensional texture coordinate. {@code q} is implicitly set to 1. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord3f(@NativeType("GLfloat") float s, @NativeType("GLfloat") float t, @NativeType("GLfloat") float r); + + // --- [ glTexCoord3s ] --- + + /** + * Short version of {@link #glTexCoord3f TexCoord3f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord3s(@NativeType("GLshort") short s, @NativeType("GLshort") short t, @NativeType("GLshort") short r); + + // --- [ glTexCoord3i ] --- + + /** + * Integer version of {@link #glTexCoord3f TexCoord3f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord3i(@NativeType("GLint") int s, @NativeType("GLint") int t, @NativeType("GLint") int r); + + // --- [ glTexCoord3d ] --- + + /** + * Double version of {@link #glTexCoord3f TexCoord3f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord3d(@NativeType("GLdouble") double s, @NativeType("GLdouble") double t, @NativeType("GLdouble") double r); + + // --- [ glTexCoord3fv ] --- + + /** Unsafe version of: {@link #glTexCoord3fv TexCoord3fv} */ + public static native void nglTexCoord3fv(long v); + + /** + * Pointer version of {@link #glTexCoord3f TexCoord3f}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3fv(@NativeType("GLfloat const *") FloatBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglTexCoord3fv(memAddress(v)); + } + + // --- [ glTexCoord3sv ] --- + + /** Unsafe version of: {@link #glTexCoord3sv TexCoord3sv} */ + public static native void nglTexCoord3sv(long v); + + /** + * Pointer version of {@link #glTexCoord3s TexCoord3s}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3sv(@NativeType("GLshort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglTexCoord3sv(memAddress(v)); + } + + // --- [ glTexCoord3iv ] --- + + /** Unsafe version of: {@link #glTexCoord3iv TexCoord3iv} */ + public static native void nglTexCoord3iv(long v); + + /** + * Pointer version of {@link #glTexCoord3i TexCoord3i}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3iv(@NativeType("GLint const *") IntBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglTexCoord3iv(memAddress(v)); + } + + // --- [ glTexCoord3dv ] --- + + /** Unsafe version of: {@link #glTexCoord3dv TexCoord3dv} */ + public static native void nglTexCoord3dv(long v); + + /** + * Pointer version of {@link #glTexCoord3d TexCoord3d}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3dv(@NativeType("GLdouble const *") DoubleBuffer v) { + if (CHECKS) { + check(v, 3); + } + nglTexCoord3dv(memAddress(v)); + } + + // --- [ glTexCoord4f ] --- + + /** + * Sets the current four-dimensional texture coordinate. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * @param q the q component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord4f(@NativeType("GLfloat") float s, @NativeType("GLfloat") float t, @NativeType("GLfloat") float r, @NativeType("GLfloat") float q); + + // --- [ glTexCoord4s ] --- + + /** + * Short version of {@link #glTexCoord4f TexCoord4f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * @param q the q component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord4s(@NativeType("GLshort") short s, @NativeType("GLshort") short t, @NativeType("GLshort") short r, @NativeType("GLshort") short q); + + // --- [ glTexCoord4i ] --- + + /** + * Integer version of {@link #glTexCoord4f TexCoord4f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * @param q the q component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord4i(@NativeType("GLint") int s, @NativeType("GLint") int t, @NativeType("GLint") int r, @NativeType("GLint") int q); + + // --- [ glTexCoord4d ] --- + + /** + * Double version of {@link #glTexCoord4f TexCoord4f}. + * + * @param s the s component of the current texture coordinates + * @param t the t component of the current texture coordinates + * @param r the r component of the current texture coordinates + * @param q the q component of the current texture coordinates + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexCoord4d(@NativeType("GLdouble") double s, @NativeType("GLdouble") double t, @NativeType("GLdouble") double r, @NativeType("GLdouble") double q); + + // --- [ glTexCoord4fv ] --- + + /** Unsafe version of: {@link #glTexCoord4fv TexCoord4fv} */ + public static native void nglTexCoord4fv(long v); + + /** + * Pointer version of {@link #glTexCoord4f TexCoord4f}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4fv(@NativeType("GLfloat const *") FloatBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglTexCoord4fv(memAddress(v)); + } + + // --- [ glTexCoord4sv ] --- + + /** Unsafe version of: {@link #glTexCoord4sv TexCoord4sv} */ + public static native void nglTexCoord4sv(long v); + + /** + * Pointer version of {@link #glTexCoord4s TexCoord4s}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4sv(@NativeType("GLshort const *") ShortBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglTexCoord4sv(memAddress(v)); + } + + // --- [ glTexCoord4iv ] --- + + /** Unsafe version of: {@link #glTexCoord4iv TexCoord4iv} */ + public static native void nglTexCoord4iv(long v); + + /** + * Pointer version of {@link #glTexCoord4i TexCoord4i}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4iv(@NativeType("GLint const *") IntBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglTexCoord4iv(memAddress(v)); + } + + // --- [ glTexCoord4dv ] --- + + /** Unsafe version of: {@link #glTexCoord4dv TexCoord4dv} */ + public static native void nglTexCoord4dv(long v); + + /** + * Pointer version of {@link #glTexCoord4d TexCoord4d}. + * + * @param v the texture coordinate buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4dv(@NativeType("GLdouble const *") DoubleBuffer v) { + if (CHECKS) { + check(v, 4); + } + nglTexCoord4dv(memAddress(v)); + } + + // --- [ glTexCoordPointer ] --- + + /** Unsafe version of: {@link #glTexCoordPointer TexCoordPointer} */ + public static native void nglTexCoordPointer(int size, int type, int stride, long pointer); + + /** + * Specifies the location and organization of a texture coordinate array. + * + * @param size the number of values per vertex that are stored in the array. One of:
1234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the texture coordinate array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoordPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + nglTexCoordPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a texture coordinate array. + * + * @param size the number of values per vertex that are stored in the array. One of:
1234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the texture coordinate array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoordPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") long pointer) { + nglTexCoordPointer(size, type, stride, pointer); + } + + /** + * Specifies the location and organization of a texture coordinate array. + * + * @param size the number of values per vertex that are stored in the array. One of:
1234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the texture coordinate array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoordPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ShortBuffer pointer) { + nglTexCoordPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a texture coordinate array. + * + * @param size the number of values per vertex that are stored in the array. One of:
1234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the texture coordinate array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoordPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") IntBuffer pointer) { + nglTexCoordPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a texture coordinate array. + * + * @param size the number of values per vertex that are stored in the array. One of:
1234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the texture coordinate array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoordPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") FloatBuffer pointer) { + nglTexCoordPointer(size, type, stride, memAddress(pointer)); + } + + // --- [ glTexEnvi ] --- + + /** + * Sets parameters of the texture environment that specifies how texture values are interpreted when texturing a fragment, or sets per-texture-unit + * filtering parameters. + * + * @param target the texture environment target. One of:
{@link #GL_TEXTURE_ENV TEXTURE_ENV}{@link GL14#GL_TEXTURE_FILTER_CONTROL TEXTURE_FILTER_CONTROL}{@link GL20#GL_POINT_SPRITE POINT_SPRITE}
+ * @param pname the parameter to set. One of:
{@link GL20#GL_COORD_REPLACE COORD_REPLACE}{@link #GL_TEXTURE_ENV_MODE TEXTURE_ENV_MODE}{@link GL14#GL_TEXTURE_LOD_BIAS TEXTURE_LOD_BIAS}{@link GL13#GL_COMBINE_RGB COMBINE_RGB}{@link GL13#GL_COMBINE_ALPHA COMBINE_ALPHA}{@link GL15#GL_SRC0_RGB SRC0_RGB}
{@link GL15#GL_SRC1_RGB SRC1_RGB}{@link GL15#GL_SRC2_RGB SRC2_RGB}{@link GL15#GL_SRC0_ALPHA SRC0_ALPHA}{@link GL15#GL_SRC1_ALPHA SRC1_ALPHA}{@link GL15#GL_SRC2_ALPHA SRC2_ALPHA}{@link GL13#GL_OPERAND0_RGB OPERAND0_RGB}
{@link GL13#GL_OPERAND1_RGB OPERAND1_RGB}{@link GL13#GL_OPERAND2_RGB OPERAND2_RGB}{@link GL13#GL_OPERAND0_ALPHA OPERAND0_ALPHA}{@link GL13#GL_OPERAND1_ALPHA OPERAND1_ALPHA}{@link GL13#GL_OPERAND2_ALPHA OPERAND2_ALPHA}{@link GL13#GL_RGB_SCALE RGB_SCALE}
{@link #GL_ALPHA_SCALE ALPHA_SCALE}
+ * @param param the parameter value. Scalar value or one of:
{@link #GL_REPLACE REPLACE}{@link #GL_MODULATE MODULATE}{@link #GL_DECAL DECAL}{@link #GL_BLEND BLEND}{@link #GL_ADD ADD}{@link GL13#GL_COMBINE COMBINE}{@link GL13#GL_ADD_SIGNED ADD_SIGNED}{@link GL13#GL_INTERPOLATE INTERPOLATE}
{@link GL13#GL_SUBTRACT SUBTRACT}{@link GL13#GL_DOT3_RGB DOT3_RGB}{@link GL13#GL_DOT3_RGBA DOT3_RGBA}{@link #GL_TEXTURE TEXTURE}{@link GL13#GL_TEXTURE0 TEXTURE0}GL13.GL_TEXTURE[1-31]{@link GL13#GL_CONSTANT CONSTANT}{@link GL13#GL_PRIMARY_COLOR PRIMARY_COLOR}
{@link GL13#GL_PREVIOUS PREVIOUS}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexEnvi(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint") int param); + + // --- [ glTexEnviv ] --- + + /** Unsafe version of: {@link #glTexEnviv TexEnviv} */ + public static native void nglTexEnviv(int target, int pname, long params); + + /** + * Pointer version of {@link #glTexEnvi TexEnvi}. + * + * @param target the texture environment target. Must be:
{@link #GL_TEXTURE_ENV TEXTURE_ENV}
+ * @param pname the parameter to set. Must be:
{@link #GL_TEXTURE_ENV_COLOR TEXTURE_ENV_COLOR}
+ * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexEnviv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint const *") IntBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglTexEnviv(target, pname, memAddress(params)); + } + + // --- [ glTexEnvf ] --- + + /** + * Float version of {@link #glTexEnvi TexEnvi}. + * + * @param target the texture environment target + * @param pname the parameter to set + * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexEnvf(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat") float param); + + // --- [ glTexEnvfv ] --- + + /** Unsafe version of: {@link #glTexEnvfv TexEnvfv} */ + public static native void nglTexEnvfv(int target, int pname, long params); + + /** + * Pointer version of {@link #glTexEnvf TexEnvf}. + * + * @param target the texture environment target. Must be:
{@link #GL_TEXTURE_ENV TEXTURE_ENV}
+ * @param pname the parameter to set. Must be:
{@link #GL_TEXTURE_ENV_COLOR TEXTURE_ENV_COLOR}
+ * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexEnvfv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") FloatBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglTexEnvfv(target, pname, memAddress(params)); + } + + // --- [ glTexGeni ] --- + + /** + * Sets an integer texture coordinate generation parameter. + * + *

A texture coordinate generation function is enabled or disabled using {@link #glEnable Enable} and {@link #glDisable Disable} with an argument of + * {@link #GL_TEXTURE_GEN_S TEXTURE_GEN_S}, {@link #GL_TEXTURE_GEN_T TEXTURE_GEN_T}, {@link #GL_TEXTURE_GEN_R TEXTURE_GEN_R}, or {@link #GL_TEXTURE_GEN_Q TEXTURE_GEN_Q} (each indicates the corresponding texture + * coordinate). When enabled, the specified texture coordinate is computed according to the current {@link #GL_EYE_LINEAR EYE_LINEAR}, {@link #GL_OBJECT_LINEAR OBJECT_LINEAR} or + * {@link #GL_SPHERE_MAP SPHERE_MAP} specification, depending on the current setting of {@link #GL_TEXTURE_GEN_MODE TEXTURE_GEN_MODE} for that coordinate. When disabled, subsequent + * vertices will take the indicated texture coordinate from the current texture coordinates.

+ * + *

The initial state has the texture generation function disabled for all texture coordinates. Initially all texture generation modes are EYE_LINEAR.

+ * + * @param coord the coordinate for which to set the parameter. One of:
{@link #GL_S S}{@link #GL_T T}{@link #GL_R R}{@link #GL_Q Q}
+ * @param pname the parameter to set. Must be:
{@link #GL_TEXTURE_GEN_MODE TEXTURE_GEN_MODE}
+ * @param param the parameter value. One of:
{@link #GL_OBJECT_LINEAR OBJECT_LINEAR}{@link #GL_EYE_LINEAR EYE_LINEAR}{@link #GL_SPHERE_MAP SPHERE_MAP}{@link GL13#GL_REFLECTION_MAP REFLECTION_MAP}{@link GL13#GL_NORMAL_MAP NORMAL_MAP}
+ * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexGeni(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLint") int param); + + // --- [ glTexGeniv ] --- + + /** Unsafe version of: {@link #glTexGeniv TexGeniv} */ + public static native void nglTexGeniv(int coord, int pname, long params); + + /** + * Pointer version of {@link #glTexGeni TexGeni}. + * + * @param coord the coordinate for which to set the parameter + * @param pname the parameter to set. One of:
{@link #GL_OBJECT_PLANE OBJECT_PLANE}{@link #GL_EYE_PLANE EYE_PLANE}
+ * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexGeniv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLint const *") IntBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglTexGeniv(coord, pname, memAddress(params)); + } + + // --- [ glTexGenf ] --- + + /** + * Float version of {@link #glTexGeni TexGeni}. + * + * @param coord the coordinate for which to set the parameter + * @param pname the parameter to set + * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexGenf(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLfloat") float param); + + // --- [ glTexGenfv ] --- + + /** Unsafe version of: {@link #glTexGenfv TexGenfv} */ + public static native void nglTexGenfv(int coord, int pname, long params); + + /** + * Pointer version of {@link #glTexGenf TexGenf}. + * + * @param coord the coordinate for which to set the parameter + * @param pname the parameter to set. One of:
{@link #GL_OBJECT_PLANE OBJECT_PLANE}{@link #GL_EYE_PLANE EYE_PLANE}
+ * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexGenfv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") FloatBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglTexGenfv(coord, pname, memAddress(params)); + } + + // --- [ glTexGend ] --- + + /** + * Double version of {@link #glTexGeni TexGeni}. + * + * @param coord the coordinate for which to set the parameter + * @param pname the parameter to set + * @param param the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTexGend(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLdouble") double param); + + // --- [ glTexGendv ] --- + + /** Unsafe version of: {@link #glTexGendv TexGendv} */ + public static native void nglTexGendv(int coord, int pname, long params); + + /** + * Pointer version of {@link #glTexGend TexGend}. + * + * @param coord the coordinate for which to set the parameter + * @param pname the parameter to set + * @param params the parameter value + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexGendv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLdouble const *") DoubleBuffer params) { + if (CHECKS) { + check(params, 4); + } + nglTexGendv(coord, pname, memAddress(params)); + } + + // --- [ glTexImage1D ] --- + + /** Unsafe version of: {@link #glTexImage1D TexImage1D} */ + public static void nglTexImage1D(int target, int level, int internalformat, int width, int border, int format, int type, long pixels) { + GL11C.nglTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexImage2D TexImage2D}}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format + * @param width the texture width + * @param border the texture border width + * @param format the texel data format + * @param type the texel data type + * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") ByteBuffer pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexImage2D TexImage2D}}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format + * @param width the texture width + * @param border the texture border width + * @param format the texel data format + * @param type the texel data type + * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") long pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexImage2D TexImage2D}}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format + * @param width the texture width + * @param border the texture border width + * @param format the texel data format + * @param type the texel data type + * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") ShortBuffer pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexImage2D TexImage2D}}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format + * @param width the texture width + * @param border the texture border width + * @param format the texel data format + * @param type the texel data type + * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") IntBuffer pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexImage2D TexImage2D}}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format + * @param width the texture width + * @param border the texture border width + * @param format the texel data format + * @param type the texel data type + * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") FloatBuffer pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexImage2D TexImage2D}}. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_PROXY_TEXTURE_1D PROXY_TEXTURE_1D}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format + * @param width the texture width + * @param border the texture border width + * @param format the texel data format + * @param type the texel data type + * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") DoubleBuffer pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + // --- [ glTexImage2D ] --- + + /** Unsafe version of: {@link #glTexImage2D TexImage2D} */ + public static void nglTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, long pixels) { + GL11C.nglTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Specifies a two-dimensional texture image. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format. One of:
{@link GL11C#GL_RED RED}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
{@link GL30#GL_R8 R8}{@link GL31#GL_R8_SNORM R8_SNORM}{@link GL30#GL_R16 R16}{@link GL31#GL_R16_SNORM R16_SNORM}{@link GL30#GL_RG8 RG8}{@link GL31#GL_RG8_SNORM RG8_SNORM}
{@link GL30#GL_RG16 RG16}{@link GL31#GL_RG16_SNORM RG16_SNORM}{@link GL11C#GL_R3_G3_B2 R3_G3_B2}{@link GL11C#GL_RGB4 RGB4}{@link GL11C#GL_RGB5 RGB5}{@link GL41#GL_RGB565 RGB565}
{@link GL11C#GL_RGB8 RGB8}{@link GL31#GL_RGB8_SNORM RGB8_SNORM}{@link GL11C#GL_RGB10 RGB10}{@link GL11C#GL_RGB12 RGB12}{@link GL11C#GL_RGB16 RGB16}{@link GL31#GL_RGB16_SNORM RGB16_SNORM}
{@link GL11C#GL_RGBA2 RGBA2}{@link GL11C#GL_RGBA4 RGBA4}{@link GL11C#GL_RGB5_A1 RGB5_A1}{@link GL11C#GL_RGBA8 RGBA8}{@link GL31#GL_RGBA8_SNORM RGBA8_SNORM}{@link GL11C#GL_RGB10_A2 RGB10_A2}
{@link GL33#GL_RGB10_A2UI RGB10_A2UI}{@link GL11C#GL_RGBA12 RGBA12}{@link GL11C#GL_RGBA16 RGBA16}{@link GL31#GL_RGBA16_SNORM RGBA16_SNORM}{@link GL21#GL_SRGB8 SRGB8}{@link GL21#GL_SRGB8_ALPHA8 SRGB8_ALPHA8}
{@link GL30#GL_R16F R16F}{@link GL30#GL_RG16F RG16F}{@link GL30#GL_RGB16F RGB16F}{@link GL30#GL_RGBA16F RGBA16F}{@link GL30#GL_R32F R32F}{@link GL30#GL_RG32F RG32F}
{@link GL30#GL_RGB32F RGB32F}{@link GL30#GL_RGBA32F RGBA32F}{@link GL30#GL_R11F_G11F_B10F R11F_G11F_B10F}{@link GL30#GL_RGB9_E5 RGB9_E5}{@link GL30#GL_R8I R8I}{@link GL30#GL_R8UI R8UI}
{@link GL30#GL_R16I R16I}{@link GL30#GL_R16UI R16UI}{@link GL30#GL_R32I R32I}{@link GL30#GL_R32UI R32UI}{@link GL30#GL_RG8I RG8I}{@link GL30#GL_RG8UI RG8UI}
{@link GL30#GL_RG16I RG16I}{@link GL30#GL_RG16UI RG16UI}{@link GL30#GL_RG32I RG32I}{@link GL30#GL_RG32UI RG32UI}{@link GL30#GL_RGB8I RGB8I}{@link GL30#GL_RGB8UI RGB8UI}
{@link GL30#GL_RGB16I RGB16I}{@link GL30#GL_RGB16UI RGB16UI}{@link GL30#GL_RGB32I RGB32I}{@link GL30#GL_RGB32UI RGB32UI}{@link GL30#GL_RGBA8I RGBA8I}{@link GL30#GL_RGBA8UI RGBA8UI}
{@link GL30#GL_RGBA16I RGBA16I}{@link GL30#GL_RGBA16UI RGBA16UI}{@link GL30#GL_RGBA32I RGBA32I}{@link GL30#GL_RGBA32UI RGBA32UI}{@link GL14#GL_DEPTH_COMPONENT16 DEPTH_COMPONENT16}{@link GL14#GL_DEPTH_COMPONENT24 DEPTH_COMPONENT24}
{@link GL14#GL_DEPTH_COMPONENT32 DEPTH_COMPONENT32}{@link GL30#GL_DEPTH24_STENCIL8 DEPTH24_STENCIL8}{@link GL30#GL_DEPTH_COMPONENT32F DEPTH_COMPONENT32F}{@link GL30#GL_DEPTH32F_STENCIL8 DEPTH32F_STENCIL8}{@link GL30#GL_COMPRESSED_RED COMPRESSED_RED}{@link GL30#GL_COMPRESSED_RG COMPRESSED_RG}
{@link GL13#GL_COMPRESSED_RGB COMPRESSED_RGB}{@link GL13#GL_COMPRESSED_RGBA COMPRESSED_RGBA}{@link GL21#GL_COMPRESSED_SRGB COMPRESSED_SRGB}{@link GL21#GL_COMPRESSED_SRGB_ALPHA COMPRESSED_SRGB_ALPHA}{@link GL30#GL_COMPRESSED_RED_RGTC1 COMPRESSED_RED_RGTC1}{@link GL30#GL_COMPRESSED_SIGNED_RED_RGTC1 COMPRESSED_SIGNED_RED_RGTC1}
{@link GL30#GL_COMPRESSED_RG_RGTC2 COMPRESSED_RG_RGTC2}{@link GL30#GL_COMPRESSED_SIGNED_RG_RGTC2 COMPRESSED_SIGNED_RG_RGTC2}{@link GL42#GL_COMPRESSED_RGBA_BPTC_UNORM COMPRESSED_RGBA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM COMPRESSED_SRGB_ALPHA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT COMPRESSED_RGB_BPTC_SIGNED_FLOAT}{@link GL42#GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}
{@link GL43#GL_COMPRESSED_RGB8_ETC2 COMPRESSED_RGB8_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_ETC2 COMPRESSED_SRGB8_ETC2}{@link GL43#GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_RGBA8_ETC2_EAC COMPRESSED_RGBA8_ETC2_EAC}{@link GL43#GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}
{@link GL43#GL_COMPRESSED_R11_EAC COMPRESSED_R11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_R11_EAC COMPRESSED_SIGNED_R11_EAC}{@link GL43#GL_COMPRESSED_RG11_EAC COMPRESSED_RG11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_RG11_EAC COMPRESSED_SIGNED_RG11_EAC}see {@link EXTTextureCompressionS3TC}see {@link EXTTextureCompressionLATC}
see {@link ATITextureCompression3DC}
+ * @param width the texture width + * @param height the texture height + * @param border the texture border width + * @param format the texel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the texel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") ByteBuffer pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Specifies a two-dimensional texture image. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format. One of:
{@link GL11C#GL_RED RED}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
{@link GL30#GL_R8 R8}{@link GL31#GL_R8_SNORM R8_SNORM}{@link GL30#GL_R16 R16}{@link GL31#GL_R16_SNORM R16_SNORM}{@link GL30#GL_RG8 RG8}{@link GL31#GL_RG8_SNORM RG8_SNORM}
{@link GL30#GL_RG16 RG16}{@link GL31#GL_RG16_SNORM RG16_SNORM}{@link GL11C#GL_R3_G3_B2 R3_G3_B2}{@link GL11C#GL_RGB4 RGB4}{@link GL11C#GL_RGB5 RGB5}{@link GL41#GL_RGB565 RGB565}
{@link GL11C#GL_RGB8 RGB8}{@link GL31#GL_RGB8_SNORM RGB8_SNORM}{@link GL11C#GL_RGB10 RGB10}{@link GL11C#GL_RGB12 RGB12}{@link GL11C#GL_RGB16 RGB16}{@link GL31#GL_RGB16_SNORM RGB16_SNORM}
{@link GL11C#GL_RGBA2 RGBA2}{@link GL11C#GL_RGBA4 RGBA4}{@link GL11C#GL_RGB5_A1 RGB5_A1}{@link GL11C#GL_RGBA8 RGBA8}{@link GL31#GL_RGBA8_SNORM RGBA8_SNORM}{@link GL11C#GL_RGB10_A2 RGB10_A2}
{@link GL33#GL_RGB10_A2UI RGB10_A2UI}{@link GL11C#GL_RGBA12 RGBA12}{@link GL11C#GL_RGBA16 RGBA16}{@link GL31#GL_RGBA16_SNORM RGBA16_SNORM}{@link GL21#GL_SRGB8 SRGB8}{@link GL21#GL_SRGB8_ALPHA8 SRGB8_ALPHA8}
{@link GL30#GL_R16F R16F}{@link GL30#GL_RG16F RG16F}{@link GL30#GL_RGB16F RGB16F}{@link GL30#GL_RGBA16F RGBA16F}{@link GL30#GL_R32F R32F}{@link GL30#GL_RG32F RG32F}
{@link GL30#GL_RGB32F RGB32F}{@link GL30#GL_RGBA32F RGBA32F}{@link GL30#GL_R11F_G11F_B10F R11F_G11F_B10F}{@link GL30#GL_RGB9_E5 RGB9_E5}{@link GL30#GL_R8I R8I}{@link GL30#GL_R8UI R8UI}
{@link GL30#GL_R16I R16I}{@link GL30#GL_R16UI R16UI}{@link GL30#GL_R32I R32I}{@link GL30#GL_R32UI R32UI}{@link GL30#GL_RG8I RG8I}{@link GL30#GL_RG8UI RG8UI}
{@link GL30#GL_RG16I RG16I}{@link GL30#GL_RG16UI RG16UI}{@link GL30#GL_RG32I RG32I}{@link GL30#GL_RG32UI RG32UI}{@link GL30#GL_RGB8I RGB8I}{@link GL30#GL_RGB8UI RGB8UI}
{@link GL30#GL_RGB16I RGB16I}{@link GL30#GL_RGB16UI RGB16UI}{@link GL30#GL_RGB32I RGB32I}{@link GL30#GL_RGB32UI RGB32UI}{@link GL30#GL_RGBA8I RGBA8I}{@link GL30#GL_RGBA8UI RGBA8UI}
{@link GL30#GL_RGBA16I RGBA16I}{@link GL30#GL_RGBA16UI RGBA16UI}{@link GL30#GL_RGBA32I RGBA32I}{@link GL30#GL_RGBA32UI RGBA32UI}{@link GL14#GL_DEPTH_COMPONENT16 DEPTH_COMPONENT16}{@link GL14#GL_DEPTH_COMPONENT24 DEPTH_COMPONENT24}
{@link GL14#GL_DEPTH_COMPONENT32 DEPTH_COMPONENT32}{@link GL30#GL_DEPTH24_STENCIL8 DEPTH24_STENCIL8}{@link GL30#GL_DEPTH_COMPONENT32F DEPTH_COMPONENT32F}{@link GL30#GL_DEPTH32F_STENCIL8 DEPTH32F_STENCIL8}{@link GL30#GL_COMPRESSED_RED COMPRESSED_RED}{@link GL30#GL_COMPRESSED_RG COMPRESSED_RG}
{@link GL13#GL_COMPRESSED_RGB COMPRESSED_RGB}{@link GL13#GL_COMPRESSED_RGBA COMPRESSED_RGBA}{@link GL21#GL_COMPRESSED_SRGB COMPRESSED_SRGB}{@link GL21#GL_COMPRESSED_SRGB_ALPHA COMPRESSED_SRGB_ALPHA}{@link GL30#GL_COMPRESSED_RED_RGTC1 COMPRESSED_RED_RGTC1}{@link GL30#GL_COMPRESSED_SIGNED_RED_RGTC1 COMPRESSED_SIGNED_RED_RGTC1}
{@link GL30#GL_COMPRESSED_RG_RGTC2 COMPRESSED_RG_RGTC2}{@link GL30#GL_COMPRESSED_SIGNED_RG_RGTC2 COMPRESSED_SIGNED_RG_RGTC2}{@link GL42#GL_COMPRESSED_RGBA_BPTC_UNORM COMPRESSED_RGBA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM COMPRESSED_SRGB_ALPHA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT COMPRESSED_RGB_BPTC_SIGNED_FLOAT}{@link GL42#GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}
{@link GL43#GL_COMPRESSED_RGB8_ETC2 COMPRESSED_RGB8_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_ETC2 COMPRESSED_SRGB8_ETC2}{@link GL43#GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_RGBA8_ETC2_EAC COMPRESSED_RGBA8_ETC2_EAC}{@link GL43#GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}
{@link GL43#GL_COMPRESSED_R11_EAC COMPRESSED_R11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_R11_EAC COMPRESSED_SIGNED_R11_EAC}{@link GL43#GL_COMPRESSED_RG11_EAC COMPRESSED_RG11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_RG11_EAC COMPRESSED_SIGNED_RG11_EAC}see {@link EXTTextureCompressionS3TC}see {@link EXTTextureCompressionLATC}
see {@link ATITextureCompression3DC}
+ * @param width the texture width + * @param height the texture height + * @param border the texture border width + * @param format the texel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the texel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") long pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Specifies a two-dimensional texture image. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format. One of:
{@link GL11C#GL_RED RED}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
{@link GL30#GL_R8 R8}{@link GL31#GL_R8_SNORM R8_SNORM}{@link GL30#GL_R16 R16}{@link GL31#GL_R16_SNORM R16_SNORM}{@link GL30#GL_RG8 RG8}{@link GL31#GL_RG8_SNORM RG8_SNORM}
{@link GL30#GL_RG16 RG16}{@link GL31#GL_RG16_SNORM RG16_SNORM}{@link GL11C#GL_R3_G3_B2 R3_G3_B2}{@link GL11C#GL_RGB4 RGB4}{@link GL11C#GL_RGB5 RGB5}{@link GL41#GL_RGB565 RGB565}
{@link GL11C#GL_RGB8 RGB8}{@link GL31#GL_RGB8_SNORM RGB8_SNORM}{@link GL11C#GL_RGB10 RGB10}{@link GL11C#GL_RGB12 RGB12}{@link GL11C#GL_RGB16 RGB16}{@link GL31#GL_RGB16_SNORM RGB16_SNORM}
{@link GL11C#GL_RGBA2 RGBA2}{@link GL11C#GL_RGBA4 RGBA4}{@link GL11C#GL_RGB5_A1 RGB5_A1}{@link GL11C#GL_RGBA8 RGBA8}{@link GL31#GL_RGBA8_SNORM RGBA8_SNORM}{@link GL11C#GL_RGB10_A2 RGB10_A2}
{@link GL33#GL_RGB10_A2UI RGB10_A2UI}{@link GL11C#GL_RGBA12 RGBA12}{@link GL11C#GL_RGBA16 RGBA16}{@link GL31#GL_RGBA16_SNORM RGBA16_SNORM}{@link GL21#GL_SRGB8 SRGB8}{@link GL21#GL_SRGB8_ALPHA8 SRGB8_ALPHA8}
{@link GL30#GL_R16F R16F}{@link GL30#GL_RG16F RG16F}{@link GL30#GL_RGB16F RGB16F}{@link GL30#GL_RGBA16F RGBA16F}{@link GL30#GL_R32F R32F}{@link GL30#GL_RG32F RG32F}
{@link GL30#GL_RGB32F RGB32F}{@link GL30#GL_RGBA32F RGBA32F}{@link GL30#GL_R11F_G11F_B10F R11F_G11F_B10F}{@link GL30#GL_RGB9_E5 RGB9_E5}{@link GL30#GL_R8I R8I}{@link GL30#GL_R8UI R8UI}
{@link GL30#GL_R16I R16I}{@link GL30#GL_R16UI R16UI}{@link GL30#GL_R32I R32I}{@link GL30#GL_R32UI R32UI}{@link GL30#GL_RG8I RG8I}{@link GL30#GL_RG8UI RG8UI}
{@link GL30#GL_RG16I RG16I}{@link GL30#GL_RG16UI RG16UI}{@link GL30#GL_RG32I RG32I}{@link GL30#GL_RG32UI RG32UI}{@link GL30#GL_RGB8I RGB8I}{@link GL30#GL_RGB8UI RGB8UI}
{@link GL30#GL_RGB16I RGB16I}{@link GL30#GL_RGB16UI RGB16UI}{@link GL30#GL_RGB32I RGB32I}{@link GL30#GL_RGB32UI RGB32UI}{@link GL30#GL_RGBA8I RGBA8I}{@link GL30#GL_RGBA8UI RGBA8UI}
{@link GL30#GL_RGBA16I RGBA16I}{@link GL30#GL_RGBA16UI RGBA16UI}{@link GL30#GL_RGBA32I RGBA32I}{@link GL30#GL_RGBA32UI RGBA32UI}{@link GL14#GL_DEPTH_COMPONENT16 DEPTH_COMPONENT16}{@link GL14#GL_DEPTH_COMPONENT24 DEPTH_COMPONENT24}
{@link GL14#GL_DEPTH_COMPONENT32 DEPTH_COMPONENT32}{@link GL30#GL_DEPTH24_STENCIL8 DEPTH24_STENCIL8}{@link GL30#GL_DEPTH_COMPONENT32F DEPTH_COMPONENT32F}{@link GL30#GL_DEPTH32F_STENCIL8 DEPTH32F_STENCIL8}{@link GL30#GL_COMPRESSED_RED COMPRESSED_RED}{@link GL30#GL_COMPRESSED_RG COMPRESSED_RG}
{@link GL13#GL_COMPRESSED_RGB COMPRESSED_RGB}{@link GL13#GL_COMPRESSED_RGBA COMPRESSED_RGBA}{@link GL21#GL_COMPRESSED_SRGB COMPRESSED_SRGB}{@link GL21#GL_COMPRESSED_SRGB_ALPHA COMPRESSED_SRGB_ALPHA}{@link GL30#GL_COMPRESSED_RED_RGTC1 COMPRESSED_RED_RGTC1}{@link GL30#GL_COMPRESSED_SIGNED_RED_RGTC1 COMPRESSED_SIGNED_RED_RGTC1}
{@link GL30#GL_COMPRESSED_RG_RGTC2 COMPRESSED_RG_RGTC2}{@link GL30#GL_COMPRESSED_SIGNED_RG_RGTC2 COMPRESSED_SIGNED_RG_RGTC2}{@link GL42#GL_COMPRESSED_RGBA_BPTC_UNORM COMPRESSED_RGBA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM COMPRESSED_SRGB_ALPHA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT COMPRESSED_RGB_BPTC_SIGNED_FLOAT}{@link GL42#GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}
{@link GL43#GL_COMPRESSED_RGB8_ETC2 COMPRESSED_RGB8_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_ETC2 COMPRESSED_SRGB8_ETC2}{@link GL43#GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_RGBA8_ETC2_EAC COMPRESSED_RGBA8_ETC2_EAC}{@link GL43#GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}
{@link GL43#GL_COMPRESSED_R11_EAC COMPRESSED_R11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_R11_EAC COMPRESSED_SIGNED_R11_EAC}{@link GL43#GL_COMPRESSED_RG11_EAC COMPRESSED_RG11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_RG11_EAC COMPRESSED_SIGNED_RG11_EAC}see {@link EXTTextureCompressionS3TC}see {@link EXTTextureCompressionLATC}
see {@link ATITextureCompression3DC}
+ * @param width the texture width + * @param height the texture height + * @param border the texture border width + * @param format the texel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the texel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") ShortBuffer pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Specifies a two-dimensional texture image. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format. One of:
{@link GL11C#GL_RED RED}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
{@link GL30#GL_R8 R8}{@link GL31#GL_R8_SNORM R8_SNORM}{@link GL30#GL_R16 R16}{@link GL31#GL_R16_SNORM R16_SNORM}{@link GL30#GL_RG8 RG8}{@link GL31#GL_RG8_SNORM RG8_SNORM}
{@link GL30#GL_RG16 RG16}{@link GL31#GL_RG16_SNORM RG16_SNORM}{@link GL11C#GL_R3_G3_B2 R3_G3_B2}{@link GL11C#GL_RGB4 RGB4}{@link GL11C#GL_RGB5 RGB5}{@link GL41#GL_RGB565 RGB565}
{@link GL11C#GL_RGB8 RGB8}{@link GL31#GL_RGB8_SNORM RGB8_SNORM}{@link GL11C#GL_RGB10 RGB10}{@link GL11C#GL_RGB12 RGB12}{@link GL11C#GL_RGB16 RGB16}{@link GL31#GL_RGB16_SNORM RGB16_SNORM}
{@link GL11C#GL_RGBA2 RGBA2}{@link GL11C#GL_RGBA4 RGBA4}{@link GL11C#GL_RGB5_A1 RGB5_A1}{@link GL11C#GL_RGBA8 RGBA8}{@link GL31#GL_RGBA8_SNORM RGBA8_SNORM}{@link GL11C#GL_RGB10_A2 RGB10_A2}
{@link GL33#GL_RGB10_A2UI RGB10_A2UI}{@link GL11C#GL_RGBA12 RGBA12}{@link GL11C#GL_RGBA16 RGBA16}{@link GL31#GL_RGBA16_SNORM RGBA16_SNORM}{@link GL21#GL_SRGB8 SRGB8}{@link GL21#GL_SRGB8_ALPHA8 SRGB8_ALPHA8}
{@link GL30#GL_R16F R16F}{@link GL30#GL_RG16F RG16F}{@link GL30#GL_RGB16F RGB16F}{@link GL30#GL_RGBA16F RGBA16F}{@link GL30#GL_R32F R32F}{@link GL30#GL_RG32F RG32F}
{@link GL30#GL_RGB32F RGB32F}{@link GL30#GL_RGBA32F RGBA32F}{@link GL30#GL_R11F_G11F_B10F R11F_G11F_B10F}{@link GL30#GL_RGB9_E5 RGB9_E5}{@link GL30#GL_R8I R8I}{@link GL30#GL_R8UI R8UI}
{@link GL30#GL_R16I R16I}{@link GL30#GL_R16UI R16UI}{@link GL30#GL_R32I R32I}{@link GL30#GL_R32UI R32UI}{@link GL30#GL_RG8I RG8I}{@link GL30#GL_RG8UI RG8UI}
{@link GL30#GL_RG16I RG16I}{@link GL30#GL_RG16UI RG16UI}{@link GL30#GL_RG32I RG32I}{@link GL30#GL_RG32UI RG32UI}{@link GL30#GL_RGB8I RGB8I}{@link GL30#GL_RGB8UI RGB8UI}
{@link GL30#GL_RGB16I RGB16I}{@link GL30#GL_RGB16UI RGB16UI}{@link GL30#GL_RGB32I RGB32I}{@link GL30#GL_RGB32UI RGB32UI}{@link GL30#GL_RGBA8I RGBA8I}{@link GL30#GL_RGBA8UI RGBA8UI}
{@link GL30#GL_RGBA16I RGBA16I}{@link GL30#GL_RGBA16UI RGBA16UI}{@link GL30#GL_RGBA32I RGBA32I}{@link GL30#GL_RGBA32UI RGBA32UI}{@link GL14#GL_DEPTH_COMPONENT16 DEPTH_COMPONENT16}{@link GL14#GL_DEPTH_COMPONENT24 DEPTH_COMPONENT24}
{@link GL14#GL_DEPTH_COMPONENT32 DEPTH_COMPONENT32}{@link GL30#GL_DEPTH24_STENCIL8 DEPTH24_STENCIL8}{@link GL30#GL_DEPTH_COMPONENT32F DEPTH_COMPONENT32F}{@link GL30#GL_DEPTH32F_STENCIL8 DEPTH32F_STENCIL8}{@link GL30#GL_COMPRESSED_RED COMPRESSED_RED}{@link GL30#GL_COMPRESSED_RG COMPRESSED_RG}
{@link GL13#GL_COMPRESSED_RGB COMPRESSED_RGB}{@link GL13#GL_COMPRESSED_RGBA COMPRESSED_RGBA}{@link GL21#GL_COMPRESSED_SRGB COMPRESSED_SRGB}{@link GL21#GL_COMPRESSED_SRGB_ALPHA COMPRESSED_SRGB_ALPHA}{@link GL30#GL_COMPRESSED_RED_RGTC1 COMPRESSED_RED_RGTC1}{@link GL30#GL_COMPRESSED_SIGNED_RED_RGTC1 COMPRESSED_SIGNED_RED_RGTC1}
{@link GL30#GL_COMPRESSED_RG_RGTC2 COMPRESSED_RG_RGTC2}{@link GL30#GL_COMPRESSED_SIGNED_RG_RGTC2 COMPRESSED_SIGNED_RG_RGTC2}{@link GL42#GL_COMPRESSED_RGBA_BPTC_UNORM COMPRESSED_RGBA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM COMPRESSED_SRGB_ALPHA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT COMPRESSED_RGB_BPTC_SIGNED_FLOAT}{@link GL42#GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}
{@link GL43#GL_COMPRESSED_RGB8_ETC2 COMPRESSED_RGB8_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_ETC2 COMPRESSED_SRGB8_ETC2}{@link GL43#GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_RGBA8_ETC2_EAC COMPRESSED_RGBA8_ETC2_EAC}{@link GL43#GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}
{@link GL43#GL_COMPRESSED_R11_EAC COMPRESSED_R11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_R11_EAC COMPRESSED_SIGNED_R11_EAC}{@link GL43#GL_COMPRESSED_RG11_EAC COMPRESSED_RG11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_RG11_EAC COMPRESSED_SIGNED_RG11_EAC}see {@link EXTTextureCompressionS3TC}see {@link EXTTextureCompressionLATC}
see {@link ATITextureCompression3DC}
+ * @param width the texture width + * @param height the texture height + * @param border the texture border width + * @param format the texel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the texel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") IntBuffer pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Specifies a two-dimensional texture image. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format. One of:
{@link GL11C#GL_RED RED}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
{@link GL30#GL_R8 R8}{@link GL31#GL_R8_SNORM R8_SNORM}{@link GL30#GL_R16 R16}{@link GL31#GL_R16_SNORM R16_SNORM}{@link GL30#GL_RG8 RG8}{@link GL31#GL_RG8_SNORM RG8_SNORM}
{@link GL30#GL_RG16 RG16}{@link GL31#GL_RG16_SNORM RG16_SNORM}{@link GL11C#GL_R3_G3_B2 R3_G3_B2}{@link GL11C#GL_RGB4 RGB4}{@link GL11C#GL_RGB5 RGB5}{@link GL41#GL_RGB565 RGB565}
{@link GL11C#GL_RGB8 RGB8}{@link GL31#GL_RGB8_SNORM RGB8_SNORM}{@link GL11C#GL_RGB10 RGB10}{@link GL11C#GL_RGB12 RGB12}{@link GL11C#GL_RGB16 RGB16}{@link GL31#GL_RGB16_SNORM RGB16_SNORM}
{@link GL11C#GL_RGBA2 RGBA2}{@link GL11C#GL_RGBA4 RGBA4}{@link GL11C#GL_RGB5_A1 RGB5_A1}{@link GL11C#GL_RGBA8 RGBA8}{@link GL31#GL_RGBA8_SNORM RGBA8_SNORM}{@link GL11C#GL_RGB10_A2 RGB10_A2}
{@link GL33#GL_RGB10_A2UI RGB10_A2UI}{@link GL11C#GL_RGBA12 RGBA12}{@link GL11C#GL_RGBA16 RGBA16}{@link GL31#GL_RGBA16_SNORM RGBA16_SNORM}{@link GL21#GL_SRGB8 SRGB8}{@link GL21#GL_SRGB8_ALPHA8 SRGB8_ALPHA8}
{@link GL30#GL_R16F R16F}{@link GL30#GL_RG16F RG16F}{@link GL30#GL_RGB16F RGB16F}{@link GL30#GL_RGBA16F RGBA16F}{@link GL30#GL_R32F R32F}{@link GL30#GL_RG32F RG32F}
{@link GL30#GL_RGB32F RGB32F}{@link GL30#GL_RGBA32F RGBA32F}{@link GL30#GL_R11F_G11F_B10F R11F_G11F_B10F}{@link GL30#GL_RGB9_E5 RGB9_E5}{@link GL30#GL_R8I R8I}{@link GL30#GL_R8UI R8UI}
{@link GL30#GL_R16I R16I}{@link GL30#GL_R16UI R16UI}{@link GL30#GL_R32I R32I}{@link GL30#GL_R32UI R32UI}{@link GL30#GL_RG8I RG8I}{@link GL30#GL_RG8UI RG8UI}
{@link GL30#GL_RG16I RG16I}{@link GL30#GL_RG16UI RG16UI}{@link GL30#GL_RG32I RG32I}{@link GL30#GL_RG32UI RG32UI}{@link GL30#GL_RGB8I RGB8I}{@link GL30#GL_RGB8UI RGB8UI}
{@link GL30#GL_RGB16I RGB16I}{@link GL30#GL_RGB16UI RGB16UI}{@link GL30#GL_RGB32I RGB32I}{@link GL30#GL_RGB32UI RGB32UI}{@link GL30#GL_RGBA8I RGBA8I}{@link GL30#GL_RGBA8UI RGBA8UI}
{@link GL30#GL_RGBA16I RGBA16I}{@link GL30#GL_RGBA16UI RGBA16UI}{@link GL30#GL_RGBA32I RGBA32I}{@link GL30#GL_RGBA32UI RGBA32UI}{@link GL14#GL_DEPTH_COMPONENT16 DEPTH_COMPONENT16}{@link GL14#GL_DEPTH_COMPONENT24 DEPTH_COMPONENT24}
{@link GL14#GL_DEPTH_COMPONENT32 DEPTH_COMPONENT32}{@link GL30#GL_DEPTH24_STENCIL8 DEPTH24_STENCIL8}{@link GL30#GL_DEPTH_COMPONENT32F DEPTH_COMPONENT32F}{@link GL30#GL_DEPTH32F_STENCIL8 DEPTH32F_STENCIL8}{@link GL30#GL_COMPRESSED_RED COMPRESSED_RED}{@link GL30#GL_COMPRESSED_RG COMPRESSED_RG}
{@link GL13#GL_COMPRESSED_RGB COMPRESSED_RGB}{@link GL13#GL_COMPRESSED_RGBA COMPRESSED_RGBA}{@link GL21#GL_COMPRESSED_SRGB COMPRESSED_SRGB}{@link GL21#GL_COMPRESSED_SRGB_ALPHA COMPRESSED_SRGB_ALPHA}{@link GL30#GL_COMPRESSED_RED_RGTC1 COMPRESSED_RED_RGTC1}{@link GL30#GL_COMPRESSED_SIGNED_RED_RGTC1 COMPRESSED_SIGNED_RED_RGTC1}
{@link GL30#GL_COMPRESSED_RG_RGTC2 COMPRESSED_RG_RGTC2}{@link GL30#GL_COMPRESSED_SIGNED_RG_RGTC2 COMPRESSED_SIGNED_RG_RGTC2}{@link GL42#GL_COMPRESSED_RGBA_BPTC_UNORM COMPRESSED_RGBA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM COMPRESSED_SRGB_ALPHA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT COMPRESSED_RGB_BPTC_SIGNED_FLOAT}{@link GL42#GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}
{@link GL43#GL_COMPRESSED_RGB8_ETC2 COMPRESSED_RGB8_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_ETC2 COMPRESSED_SRGB8_ETC2}{@link GL43#GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_RGBA8_ETC2_EAC COMPRESSED_RGBA8_ETC2_EAC}{@link GL43#GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}
{@link GL43#GL_COMPRESSED_R11_EAC COMPRESSED_R11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_R11_EAC COMPRESSED_SIGNED_R11_EAC}{@link GL43#GL_COMPRESSED_RG11_EAC COMPRESSED_RG11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_RG11_EAC COMPRESSED_SIGNED_RG11_EAC}see {@link EXTTextureCompressionS3TC}see {@link EXTTextureCompressionLATC}
see {@link ATITextureCompression3DC}
+ * @param width the texture width + * @param height the texture height + * @param border the texture border width + * @param format the texel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the texel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") FloatBuffer pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Specifies a two-dimensional texture image. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
{@link GL11C#GL_PROXY_TEXTURE_2D PROXY_TEXTURE_2D}{@link GL30#GL_PROXY_TEXTURE_1D_ARRAY PROXY_TEXTURE_1D_ARRAY}{@link GL31#GL_PROXY_TEXTURE_RECTANGLE PROXY_TEXTURE_RECTANGLE}{@link GL13#GL_PROXY_TEXTURE_CUBE_MAP PROXY_TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param internalformat the texture internal format. One of:
{@link GL11C#GL_RED RED}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
{@link GL30#GL_R8 R8}{@link GL31#GL_R8_SNORM R8_SNORM}{@link GL30#GL_R16 R16}{@link GL31#GL_R16_SNORM R16_SNORM}{@link GL30#GL_RG8 RG8}{@link GL31#GL_RG8_SNORM RG8_SNORM}
{@link GL30#GL_RG16 RG16}{@link GL31#GL_RG16_SNORM RG16_SNORM}{@link GL11C#GL_R3_G3_B2 R3_G3_B2}{@link GL11C#GL_RGB4 RGB4}{@link GL11C#GL_RGB5 RGB5}{@link GL41#GL_RGB565 RGB565}
{@link GL11C#GL_RGB8 RGB8}{@link GL31#GL_RGB8_SNORM RGB8_SNORM}{@link GL11C#GL_RGB10 RGB10}{@link GL11C#GL_RGB12 RGB12}{@link GL11C#GL_RGB16 RGB16}{@link GL31#GL_RGB16_SNORM RGB16_SNORM}
{@link GL11C#GL_RGBA2 RGBA2}{@link GL11C#GL_RGBA4 RGBA4}{@link GL11C#GL_RGB5_A1 RGB5_A1}{@link GL11C#GL_RGBA8 RGBA8}{@link GL31#GL_RGBA8_SNORM RGBA8_SNORM}{@link GL11C#GL_RGB10_A2 RGB10_A2}
{@link GL33#GL_RGB10_A2UI RGB10_A2UI}{@link GL11C#GL_RGBA12 RGBA12}{@link GL11C#GL_RGBA16 RGBA16}{@link GL31#GL_RGBA16_SNORM RGBA16_SNORM}{@link GL21#GL_SRGB8 SRGB8}{@link GL21#GL_SRGB8_ALPHA8 SRGB8_ALPHA8}
{@link GL30#GL_R16F R16F}{@link GL30#GL_RG16F RG16F}{@link GL30#GL_RGB16F RGB16F}{@link GL30#GL_RGBA16F RGBA16F}{@link GL30#GL_R32F R32F}{@link GL30#GL_RG32F RG32F}
{@link GL30#GL_RGB32F RGB32F}{@link GL30#GL_RGBA32F RGBA32F}{@link GL30#GL_R11F_G11F_B10F R11F_G11F_B10F}{@link GL30#GL_RGB9_E5 RGB9_E5}{@link GL30#GL_R8I R8I}{@link GL30#GL_R8UI R8UI}
{@link GL30#GL_R16I R16I}{@link GL30#GL_R16UI R16UI}{@link GL30#GL_R32I R32I}{@link GL30#GL_R32UI R32UI}{@link GL30#GL_RG8I RG8I}{@link GL30#GL_RG8UI RG8UI}
{@link GL30#GL_RG16I RG16I}{@link GL30#GL_RG16UI RG16UI}{@link GL30#GL_RG32I RG32I}{@link GL30#GL_RG32UI RG32UI}{@link GL30#GL_RGB8I RGB8I}{@link GL30#GL_RGB8UI RGB8UI}
{@link GL30#GL_RGB16I RGB16I}{@link GL30#GL_RGB16UI RGB16UI}{@link GL30#GL_RGB32I RGB32I}{@link GL30#GL_RGB32UI RGB32UI}{@link GL30#GL_RGBA8I RGBA8I}{@link GL30#GL_RGBA8UI RGBA8UI}
{@link GL30#GL_RGBA16I RGBA16I}{@link GL30#GL_RGBA16UI RGBA16UI}{@link GL30#GL_RGBA32I RGBA32I}{@link GL30#GL_RGBA32UI RGBA32UI}{@link GL14#GL_DEPTH_COMPONENT16 DEPTH_COMPONENT16}{@link GL14#GL_DEPTH_COMPONENT24 DEPTH_COMPONENT24}
{@link GL14#GL_DEPTH_COMPONENT32 DEPTH_COMPONENT32}{@link GL30#GL_DEPTH24_STENCIL8 DEPTH24_STENCIL8}{@link GL30#GL_DEPTH_COMPONENT32F DEPTH_COMPONENT32F}{@link GL30#GL_DEPTH32F_STENCIL8 DEPTH32F_STENCIL8}{@link GL30#GL_COMPRESSED_RED COMPRESSED_RED}{@link GL30#GL_COMPRESSED_RG COMPRESSED_RG}
{@link GL13#GL_COMPRESSED_RGB COMPRESSED_RGB}{@link GL13#GL_COMPRESSED_RGBA COMPRESSED_RGBA}{@link GL21#GL_COMPRESSED_SRGB COMPRESSED_SRGB}{@link GL21#GL_COMPRESSED_SRGB_ALPHA COMPRESSED_SRGB_ALPHA}{@link GL30#GL_COMPRESSED_RED_RGTC1 COMPRESSED_RED_RGTC1}{@link GL30#GL_COMPRESSED_SIGNED_RED_RGTC1 COMPRESSED_SIGNED_RED_RGTC1}
{@link GL30#GL_COMPRESSED_RG_RGTC2 COMPRESSED_RG_RGTC2}{@link GL30#GL_COMPRESSED_SIGNED_RG_RGTC2 COMPRESSED_SIGNED_RG_RGTC2}{@link GL42#GL_COMPRESSED_RGBA_BPTC_UNORM COMPRESSED_RGBA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM COMPRESSED_SRGB_ALPHA_BPTC_UNORM}{@link GL42#GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT COMPRESSED_RGB_BPTC_SIGNED_FLOAT}{@link GL42#GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT}
{@link GL43#GL_COMPRESSED_RGB8_ETC2 COMPRESSED_RGB8_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_ETC2 COMPRESSED_SRGB8_ETC2}{@link GL43#GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}{@link GL43#GL_COMPRESSED_RGBA8_ETC2_EAC COMPRESSED_RGBA8_ETC2_EAC}{@link GL43#GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}
{@link GL43#GL_COMPRESSED_R11_EAC COMPRESSED_R11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_R11_EAC COMPRESSED_SIGNED_R11_EAC}{@link GL43#GL_COMPRESSED_RG11_EAC COMPRESSED_RG11_EAC}{@link GL43#GL_COMPRESSED_SIGNED_RG11_EAC COMPRESSED_SIGNED_RG11_EAC}see {@link EXTTextureCompressionS3TC}see {@link EXTTextureCompressionLATC}
see {@link ATITextureCompression3DC}
+ * @param width the texture width + * @param height the texture height + * @param border the texture border width + * @param format the texel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the texel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the texel data + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") DoubleBuffer pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + // --- [ glCopyTexImage1D ] --- + + /** + * Defines a one-dimensional texel array in exactly the manner of {@link #glTexImage1D TexImage1D}, except that the image data are taken from the framebuffer rather + * than from client memory. For the purposes of decoding the texture image, {@code CopyTexImage1D} is equivalent to calling {@link #glCopyTexImage2D CopyTexImage2D} + * with corresponding arguments and height of 1, except that the height of the image is always 1, regardless of the value of border. level, internalformat, + * and border are specified using the same values, with the same meanings, as the corresponding arguments of {@link #glTexImage1D TexImage1D}. The constraints on + * width and border are exactly those of the corresponding arguments of {@link #glTexImage1D TexImage1D}. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail number + * @param internalFormat the texture internal format. See {@link #glTexImage2D TexImage2D} for a list of supported formats. + * @param x the left framebuffer pixel coordinate + * @param y the lower framebuffer pixel coordinate + * @param width the texture width + * @param border the texture border width + * + * @see Reference Page + */ + public static void glCopyTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int internalFormat, @NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLint") int border) { + GL11C.glCopyTexImage1D(target, level, internalFormat, x, y, width, border); + } + + // --- [ glCopyTexImage2D ] --- + + /** + * Defines a two-dimensional texel array in exactly the manner of {@link #glTexImage2D TexImage2D}, except that the image data are taken from the framebuffer rather + * than from client memory. + * + *

{@code x}, {@code y}, {@code width}, and {@code height} correspond precisely to the corresponding arguments to {@link #glReadPixels ReadPixels}; they specify the + * image's width and height, and the lower left (x, y) coordinates of the framebuffer region to be copied.

+ * + *

The image is taken from the framebuffer exactly as if these arguments were passed to {@link GL11#glCopyPixels CopyPixels} with argument type set to {@link GL11C#GL_COLOR COLOR}, + * {@link GL11C#GL_DEPTH DEPTH}, or {@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}, depending on {@code internalformat}. RGBA data is taken from the current color buffer, while depth + * component and stencil index data are taken from the depth and stencil buffers, respectively.

+ * + *

Subsequent processing is identical to that described for {@link #glTexImage2D TexImage2D}, beginning with clamping of the R, G, B, A, or depth values, and masking + * of the stencil index values from the resulting pixel groups. Parameters {@code level}, {@code internalformat}, and {@code border} are specified using + * the same values, with the same meanings, as the corresponding arguments of {@link #glTexImage2D TexImage2D}.

+ * + *

The constraints on width, height, and border are exactly those for the corresponding arguments of {@link #glTexImage2D TexImage2D}.

+ * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param internalFormat the texture internal format. See {@link #glTexImage2D TexImage2D} for a list of supported formats. + * @param x the left framebuffer pixel coordinate + * @param y the lower framebuffer pixel coordinate + * @param width the texture width + * @param height the texture height + * @param border the texture border width + * + * @see Reference Page + */ + public static void glCopyTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int internalFormat, @NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border) { + GL11C.glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border); + } + + // --- [ glCopyTexSubImage1D ] --- + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the {@code internalformat}, {@code width} or {@code border} + * parameters of the specified texel array, nor is any change made to texel values outside the specified subregion. See {@link #glCopyTexImage1D CopyTexImage1D} for more + * details. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail number + * @param xoffset the left texel coordinate of the texture subregion to update + * @param x the left framebuffer pixel coordinate + * @param y the lower framebuffer pixel coordinate + * @param width the texture subregion width + * + * @see Reference Page + */ + public static void glCopyTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width) { + GL11C.glCopyTexSubImage1D(target, level, xoffset, x, y, width); + } + + // --- [ glCopyTexSubImage2D ] --- + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the {@code internalformat}, {@code width}, {@code height}, + * or {@code border} parameters of the specified texel array, nor is any change made to texel values outside the specified subregion. See + * {@link #glCopyTexImage2D CopyTexImage2D} for more details. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail number + * @param xoffset the left texel coordinate of the texture subregion to update + * @param yoffset the lower texel coordinate of the texture subregion to update + * @param x the left framebuffer pixel coordinate + * @param y the lower framebuffer pixel coordinate + * @param width the texture subregion width + * @param height the texture subregion height + * + * @see Reference Page + */ + public static void glCopyTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height) { + GL11C.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + } + + // --- [ glTexParameteri ] --- + + /** + * Sets the integer value of a texture parameter, which controls how the texel array is treated when specified or changed, and when applied to a fragment. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL12#GL_TEXTURE_3D TEXTURE_3D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}
{@link GL30#GL_TEXTURE_2D_ARRAY TEXTURE_2D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}{@link GL40#GL_TEXTURE_CUBE_MAP_ARRAY TEXTURE_CUBE_MAP_ARRAY}
{@link GL32#GL_TEXTURE_2D_MULTISAMPLE TEXTURE_2D_MULTISAMPLE}{@link GL32#GL_TEXTURE_2D_MULTISAMPLE_ARRAY TEXTURE_2D_MULTISAMPLE_ARRAY}
+ * @param pname the parameter to set. One of:
{@link GL12#GL_TEXTURE_BASE_LEVEL TEXTURE_BASE_LEVEL}{@link GL11C#GL_TEXTURE_BORDER_COLOR TEXTURE_BORDER_COLOR}{@link GL14#GL_TEXTURE_COMPARE_MODE TEXTURE_COMPARE_MODE}{@link GL14#GL_TEXTURE_COMPARE_FUNC TEXTURE_COMPARE_FUNC}
{@link GL14#GL_TEXTURE_LOD_BIAS TEXTURE_LOD_BIAS}{@link GL11C#GL_TEXTURE_MAG_FILTER TEXTURE_MAG_FILTER}{@link GL12#GL_TEXTURE_MAX_LEVEL TEXTURE_MAX_LEVEL}{@link GL12#GL_TEXTURE_MAX_LOD TEXTURE_MAX_LOD}
{@link GL11C#GL_TEXTURE_MIN_FILTER TEXTURE_MIN_FILTER}{@link GL12#GL_TEXTURE_MIN_LOD TEXTURE_MIN_LOD}{@link GL33#GL_TEXTURE_SWIZZLE_R TEXTURE_SWIZZLE_R}{@link GL33#GL_TEXTURE_SWIZZLE_G TEXTURE_SWIZZLE_G}
{@link GL33#GL_TEXTURE_SWIZZLE_B TEXTURE_SWIZZLE_B}{@link GL33#GL_TEXTURE_SWIZZLE_A TEXTURE_SWIZZLE_A}{@link GL33#GL_TEXTURE_SWIZZLE_RGBA TEXTURE_SWIZZLE_RGBA}{@link GL11C#GL_TEXTURE_WRAP_S TEXTURE_WRAP_S}
{@link GL11C#GL_TEXTURE_WRAP_T TEXTURE_WRAP_T}{@link GL12#GL_TEXTURE_WRAP_R TEXTURE_WRAP_R}{@link GL14#GL_DEPTH_TEXTURE_MODE DEPTH_TEXTURE_MODE}{@link GL14#GL_GENERATE_MIPMAP GENERATE_MIPMAP}
+ * @param param the parameter value + * + * @see Reference Page + */ + public static void glTexParameteri(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint") int param) { + GL11C.glTexParameteri(target, pname, param); + } + + // --- [ glTexParameteriv ] --- + + /** Unsafe version of: {@link #glTexParameteriv TexParameteriv} */ + public static void nglTexParameteriv(int target, int pname, long params) { + GL11C.nglTexParameteriv(target, pname, params); + } + + /** + * Pointer version of {@link #glTexParameteri TexParameteri}. + * + * @param target the texture target + * @param pname the parameter to set + * @param params the parameter value + * + * @see Reference Page + */ + public static void glTexParameteriv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint const *") IntBuffer params) { + GL11C.glTexParameteriv(target, pname, params); + } + + // --- [ glTexParameterf ] --- + + /** + * Float version of {@link #glTexParameteri TexParameteri}. + * + * @param target the texture target + * @param pname the parameter to set + * @param param the parameter value + * + * @see Reference Page + */ + public static void glTexParameterf(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat") float param) { + GL11C.glTexParameterf(target, pname, param); + } + + // --- [ glTexParameterfv ] --- + + /** Unsafe version of: {@link #glTexParameterfv TexParameterfv} */ + public static void nglTexParameterfv(int target, int pname, long params) { + GL11C.nglTexParameterfv(target, pname, params); + } + + /** + * Pointer version of {@link #glTexParameterf TexParameterf}. + * + * @param target the texture target + * @param pname the parameter to set + * @param params the parameter value + * + * @see Reference Page + */ + public static void glTexParameterfv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") FloatBuffer params) { + GL11C.glTexParameterfv(target, pname, params); + } + + // --- [ glTexSubImage1D ] --- + + /** Unsafe version of: {@link #glTexSubImage1D TexSubImage1D} */ + public static void nglTexSubImage1D(int target, int level, int xoffset, int width, int format, int type, long pixels) { + GL11C.nglTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexSubImage2D TexSubImage2D}. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param width the subregion width + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") ByteBuffer pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexSubImage2D TexSubImage2D}. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param width the subregion width + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") long pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexSubImage2D TexSubImage2D}. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param width the subregion width + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") ShortBuffer pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexSubImage2D TexSubImage2D}. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param width the subregion width + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") IntBuffer pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexSubImage2D TexSubImage2D}. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param width the subregion width + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") FloatBuffer pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * One-dimensional version of {@link #glTexSubImage2D TexSubImage2D}. + * + * @param target the texture target. Must be:
{@link GL11C#GL_TEXTURE_1D TEXTURE_1D}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param width the subregion width + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") DoubleBuffer pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + // --- [ glTexSubImage2D ] --- + + /** Unsafe version of: {@link #glTexSubImage2D TexSubImage2D} */ + public static void nglTexSubImage2D(int target, int level, int xoffset, int yoffset, int width, int height, int format, int type, long pixels) { + GL11C.nglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the internalformat, width, height, depth, or border parameters of + * the specified texel array, nor is any change made to texel values outside the specified subregion. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param yoffset the bottom coordinate of the texel subregion + * @param width the subregion width + * @param height the subregion height + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") ByteBuffer pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the internalformat, width, height, depth, or border parameters of + * the specified texel array, nor is any change made to texel values outside the specified subregion. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param yoffset the bottom coordinate of the texel subregion + * @param width the subregion width + * @param height the subregion height + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") long pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the internalformat, width, height, depth, or border parameters of + * the specified texel array, nor is any change made to texel values outside the specified subregion. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param yoffset the bottom coordinate of the texel subregion + * @param width the subregion width + * @param height the subregion height + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") ShortBuffer pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the internalformat, width, height, depth, or border parameters of + * the specified texel array, nor is any change made to texel values outside the specified subregion. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param yoffset the bottom coordinate of the texel subregion + * @param width the subregion width + * @param height the subregion height + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") IntBuffer pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the internalformat, width, height, depth, or border parameters of + * the specified texel array, nor is any change made to texel values outside the specified subregion. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param yoffset the bottom coordinate of the texel subregion + * @param width the subregion width + * @param height the subregion height + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") FloatBuffer pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Respecifies a rectangular subregion of an existing texel array. No change is made to the internalformat, width, height, depth, or border parameters of + * the specified texel array, nor is any change made to texel values outside the specified subregion. + * + * @param target the texture target. One of:
{@link GL11C#GL_TEXTURE_2D TEXTURE_2D}{@link GL30#GL_TEXTURE_1D_ARRAY TEXTURE_1D_ARRAY}{@link GL31#GL_TEXTURE_RECTANGLE TEXTURE_RECTANGLE}{@link GL13#GL_TEXTURE_CUBE_MAP TEXTURE_CUBE_MAP}
+ * @param level the level-of-detail-number + * @param xoffset the left coordinate of the texel subregion + * @param yoffset the bottom coordinate of the texel subregion + * @param width the subregion width + * @param height the subregion height + * @param format the pixel data format. One of:
{@link GL11C#GL_RED RED}{@link GL11C#GL_GREEN GREEN}{@link GL11C#GL_BLUE BLUE}{@link GL11C#GL_ALPHA ALPHA}{@link GL30#GL_RG RG}{@link GL11C#GL_RGB RGB}{@link GL11C#GL_RGBA RGBA}{@link GL12#GL_BGR BGR}
{@link GL12#GL_BGRA BGRA}{@link GL30#GL_RED_INTEGER RED_INTEGER}{@link GL30#GL_GREEN_INTEGER GREEN_INTEGER}{@link GL30#GL_BLUE_INTEGER BLUE_INTEGER}{@link GL30#GL_ALPHA_INTEGER ALPHA_INTEGER}{@link GL30#GL_RG_INTEGER RG_INTEGER}{@link GL30#GL_RGB_INTEGER RGB_INTEGER}{@link GL30#GL_RGBA_INTEGER RGBA_INTEGER}
{@link GL30#GL_BGR_INTEGER BGR_INTEGER}{@link GL30#GL_BGRA_INTEGER BGRA_INTEGER}{@link GL11C#GL_STENCIL_INDEX STENCIL_INDEX}{@link GL11C#GL_DEPTH_COMPONENT DEPTH_COMPONENT}{@link GL30#GL_DEPTH_STENCIL DEPTH_STENCIL}
+ * @param type the pixel data type. One of:
{@link GL11C#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11C#GL_BYTE BYTE}{@link GL11C#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11C#GL_SHORT SHORT}
{@link GL11C#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL11C#GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11C#GL_FLOAT FLOAT}
{@link GL12#GL_UNSIGNED_BYTE_3_3_2 UNSIGNED_BYTE_3_3_2}{@link GL12#GL_UNSIGNED_BYTE_2_3_3_REV UNSIGNED_BYTE_2_3_3_REV}{@link GL12#GL_UNSIGNED_SHORT_5_6_5 UNSIGNED_SHORT_5_6_5}{@link GL12#GL_UNSIGNED_SHORT_5_6_5_REV UNSIGNED_SHORT_5_6_5_REV}
{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4 UNSIGNED_SHORT_4_4_4_4}{@link GL12#GL_UNSIGNED_SHORT_4_4_4_4_REV UNSIGNED_SHORT_4_4_4_4_REV}{@link GL12#GL_UNSIGNED_SHORT_5_5_5_1 UNSIGNED_SHORT_5_5_5_1}{@link GL12#GL_UNSIGNED_SHORT_1_5_5_5_REV UNSIGNED_SHORT_1_5_5_5_REV}
{@link GL12#GL_UNSIGNED_INT_8_8_8_8 UNSIGNED_INT_8_8_8_8}{@link GL12#GL_UNSIGNED_INT_8_8_8_8_REV UNSIGNED_INT_8_8_8_8_REV}{@link GL12#GL_UNSIGNED_INT_10_10_10_2 UNSIGNED_INT_10_10_10_2}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}
{@link GL30#GL_UNSIGNED_INT_24_8 UNSIGNED_INT_24_8}{@link GL30#GL_UNSIGNED_INT_10F_11F_11F_REV UNSIGNED_INT_10F_11F_11F_REV}{@link GL30#GL_UNSIGNED_INT_5_9_9_9_REV UNSIGNED_INT_5_9_9_9_REV}{@link GL30#GL_FLOAT_32_UNSIGNED_INT_24_8_REV FLOAT_32_UNSIGNED_INT_24_8_REV}
+ * @param pixels the pixel data + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") DoubleBuffer pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + // --- [ glTranslatef ] --- + + /** + * Manipulates the current matrix with a translation matrix along the x-, y- and z- axes. + * + *

Calling this function is equivalent to calling {@link #glMultMatrixf MultMatrixf} with the following matrix:

+ * + * + * + * + * + * + *
100x
010y
001z
0001
+ * + * @param x the x-axis translation + * @param y the y-axis translation + * @param z the z-axis translation + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTranslatef(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y, @NativeType("GLfloat") float z); + + // --- [ glTranslated ] --- + + /** + * Double version of {@link #glTranslatef Translatef}. + * + * @param x the x-axis translation + * @param y the y-axis translation + * @param z the z-axis translation + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glTranslated(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y, @NativeType("GLdouble") double z); + + // --- [ glVertex2f ] --- + + /** + * Specifies a single vertex between {@link #glBegin Begin} and {@link #glEnd End} by giving its coordinates in two dimensions. The z coordinate is implicitly set + * to zero and the w coordinate to one. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex2f(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y); + + // --- [ glVertex2s ] --- + + /** + * Short version of {@link #glVertex2f Vertex2f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex2s(@NativeType("GLshort") short x, @NativeType("GLshort") short y); + + // --- [ glVertex2i ] --- + + /** + * Integer version of {@link #glVertex2f Vertex2f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex2i(@NativeType("GLint") int x, @NativeType("GLint") int y); + + // --- [ glVertex2d ] --- + + /** + * Double version of {@link #glVertex2f Vertex2f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex2d(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y); + + // --- [ glVertex2fv ] --- + + /** Unsafe version of: {@link #glVertex2fv Vertex2fv} */ + public static native void nglVertex2fv(long coords); + + /** + * Pointer version of {@link #glVertex2f Vertex2f}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2fv(@NativeType("GLfloat const *") FloatBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglVertex2fv(memAddress(coords)); + } + + // --- [ glVertex2sv ] --- + + /** Unsafe version of: {@link #glVertex2sv Vertex2sv} */ + public static native void nglVertex2sv(long coords); + + /** + * Pointer version of {@link #glVertex2s Vertex2s}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2sv(@NativeType("GLshort const *") ShortBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglVertex2sv(memAddress(coords)); + } + + // --- [ glVertex2iv ] --- + + /** Unsafe version of: {@link #glVertex2iv Vertex2iv} */ + public static native void nglVertex2iv(long coords); + + /** + * Pointer version of {@link #glVertex2i Vertex2i}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2iv(@NativeType("GLint const *") IntBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglVertex2iv(memAddress(coords)); + } + + // --- [ glVertex2dv ] --- + + /** Unsafe version of: {@link #glVertex2dv Vertex2dv} */ + public static native void nglVertex2dv(long coords); + + /** + * Pointer version of {@link #glVertex2d Vertex2d}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2dv(@NativeType("GLdouble const *") DoubleBuffer coords) { + if (CHECKS) { + check(coords, 2); + } + nglVertex2dv(memAddress(coords)); + } + + // --- [ glVertex3f ] --- + + /** + * Specifies a single vertex between {@link #glBegin Begin} and {@link #glEnd End} by giving its coordinates in three dimensions. The w coordinate is implicitly set + * to one. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex3f(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y, @NativeType("GLfloat") float z); + + // --- [ glVertex3s ] --- + + /** + * Short version of {@link #glVertex3f Vertex3f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex3s(@NativeType("GLshort") short x, @NativeType("GLshort") short y, @NativeType("GLshort") short z); + + // --- [ glVertex3i ] --- + + /** + * Integer version of {@link #glVertex3f Vertex3f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex3i(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLint") int z); + + // --- [ glVertex3d ] --- + + /** + * Double version of {@link #glVertex3f Vertex3f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex3d(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y, @NativeType("GLdouble") double z); + + // --- [ glVertex3fv ] --- + + /** Unsafe version of: {@link #glVertex3fv Vertex3fv} */ + public static native void nglVertex3fv(long coords); + + /** + * Pointer version of {@link #glVertex3f Vertex3f}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3fv(@NativeType("GLfloat const *") FloatBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglVertex3fv(memAddress(coords)); + } + + // --- [ glVertex3sv ] --- + + /** Unsafe version of: {@link #glVertex3sv Vertex3sv} */ + public static native void nglVertex3sv(long coords); + + /** + * Pointer version of {@link #glVertex3s Vertex3s}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3sv(@NativeType("GLshort const *") ShortBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglVertex3sv(memAddress(coords)); + } + + // --- [ glVertex3iv ] --- + + /** Unsafe version of: {@link #glVertex3iv Vertex3iv} */ + public static native void nglVertex3iv(long coords); + + /** + * Pointer version of {@link #glVertex3i Vertex3i}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3iv(@NativeType("GLint const *") IntBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglVertex3iv(memAddress(coords)); + } + + // --- [ glVertex3dv ] --- + + /** Unsafe version of: {@link #glVertex3dv Vertex3dv} */ + public static native void nglVertex3dv(long coords); + + /** + * Pointer version of {@link #glVertex3d Vertex3d}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3dv(@NativeType("GLdouble const *") DoubleBuffer coords) { + if (CHECKS) { + check(coords, 3); + } + nglVertex3dv(memAddress(coords)); + } + + // --- [ glVertex4f ] --- + + /** + * Specifies a single vertex between {@link #glBegin Begin} and {@link #glEnd End} by giving its coordinates in four dimensions. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * @param w the vertex w coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex4f(@NativeType("GLfloat") float x, @NativeType("GLfloat") float y, @NativeType("GLfloat") float z, @NativeType("GLfloat") float w); + + // --- [ glVertex4s ] --- + + /** + * Short version of {@link #glVertex4f Vertex4f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * @param w the vertex w coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex4s(@NativeType("GLshort") short x, @NativeType("GLshort") short y, @NativeType("GLshort") short z, @NativeType("GLshort") short w); + + // --- [ glVertex4i ] --- + + /** + * Integer version of {@link #glVertex4f Vertex4f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * @param w the vertex w coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex4i(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLint") int z, @NativeType("GLint") int w); + + // --- [ glVertex4d ] --- + + /** + * Double version of {@link #glVertex4f Vertex4f}. + * + * @param x the vertex x coordinate + * @param y the vertex y coordinate + * @param z the vertex z coordinate + * @param w the vertex w coordinate + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static native void glVertex4d(@NativeType("GLdouble") double x, @NativeType("GLdouble") double y, @NativeType("GLdouble") double z, @NativeType("GLdouble") double w); + + // --- [ glVertex4fv ] --- + + /** Unsafe version of: {@link #glVertex4fv Vertex4fv} */ + public static native void nglVertex4fv(long coords); + + /** + * Pointer version of {@link #glVertex4f Vertex4f}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4fv(@NativeType("GLfloat const *") FloatBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglVertex4fv(memAddress(coords)); + } + + // --- [ glVertex4sv ] --- + + /** Unsafe version of: {@link #glVertex4sv Vertex4sv} */ + public static native void nglVertex4sv(long coords); + + /** + * Pointer version of {@link #glVertex4s Vertex4s}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4sv(@NativeType("GLshort const *") ShortBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglVertex4sv(memAddress(coords)); + } + + // --- [ glVertex4iv ] --- + + /** Unsafe version of: {@link #glVertex4iv Vertex4iv} */ + public static native void nglVertex4iv(long coords); + + /** + * Pointer version of {@link #glVertex4i Vertex4i}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4iv(@NativeType("GLint const *") IntBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglVertex4iv(memAddress(coords)); + } + + // --- [ glVertex4dv ] --- + + /** Unsafe version of: {@link #glVertex4dv Vertex4dv} */ + public static native void nglVertex4dv(long coords); + + /** + * Pointer version of {@link #glVertex4d Vertex4d}. + * + * @param coords the vertex buffer + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4dv(@NativeType("GLdouble const *") DoubleBuffer coords) { + if (CHECKS) { + check(coords, 4); + } + nglVertex4dv(memAddress(coords)); + } + + // --- [ glVertexPointer ] --- + + /** Unsafe version of: {@link #glVertexPointer VertexPointer} */ + public static native void nglVertexPointer(int size, int type, int stride, long pointer); + + /** + * Specifies the location and organization of a vertex array. + * + * @param size the number of values per vertex that are stored in the array. One of:
234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertexPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + nglVertexPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a vertex array. + * + * @param size the number of values per vertex that are stored in the array. One of:
234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertexPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") long pointer) { + nglVertexPointer(size, type, stride, pointer); + } + + /** + * Specifies the location and organization of a vertex array. + * + * @param size the number of values per vertex that are stored in the array. One of:
234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertexPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") ShortBuffer pointer) { + nglVertexPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a vertex array. + * + * @param size the number of values per vertex that are stored in the array. One of:
234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertexPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") IntBuffer pointer) { + nglVertexPointer(size, type, stride, memAddress(pointer)); + } + + /** + * Specifies the location and organization of a vertex array. + * + * @param size the number of values per vertex that are stored in the array. One of:
234
+ * @param type the data type of the values stored in the array. One of:
{@link #GL_SHORT SHORT}{@link #GL_INT INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link #GL_FLOAT FLOAT}{@link #GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}
+ * @param stride the vertex stride in bytes. If specified as zero, then array elements are stored sequentially + * @param pointer the vertex array data + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertexPointer(@NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLsizei") int stride, @NativeType("void const *") FloatBuffer pointer) { + nglVertexPointer(size, type, stride, memAddress(pointer)); + } + + // --- [ glViewport ] --- + + /** + * Specifies the viewport transformation parameters for all viewports. + * + *

The location of the viewport's bottom-left corner, given by {@code (x, y)}, are clamped to be within the implementation-dependent viewport bounds range. + * The viewport bounds range {@code [min, max]} tuple may be determined by calling {@link #glGetFloatv GetFloatv} with the symbolic + * constant {@link GL41#GL_VIEWPORT_BOUNDS_RANGE VIEWPORT_BOUNDS_RANGE}. Viewport width and height are clamped to implementation-dependent maximums when specified. The maximum + * width and height may be found by calling {@link #glGetFloatv GetFloatv} with the symbolic constant {@link GL11C#GL_MAX_VIEWPORT_DIMS MAX_VIEWPORT_DIMS}. The + * maximum viewport dimensions must be greater than or equal to the larger of the visible dimensions of the display being rendered to (if a display + * exists), and the largest renderbuffer image which can be successfully created and attached to a framebuffer object.

+ * + *

In the initial state, {@code w} and {@code h} for each viewport are set to the width and height, respectively, of the window into which the GL is to do + * its rendering. If the default framebuffer is bound but no default framebuffer is associated with the GL context, then {@code w} and {@code h} are + * initially set to zero.

+ * + * @param x the left viewport coordinate + * @param y the bottom viewport coordinate + * @param w the viewport width + * @param h the viewport height + * + * @see Reference Page + */ + public static void glViewport(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int w, @NativeType("GLsizei") int h) { + GL11C.glViewport(x, y, w, h); + } + + /** + * Array version of: {@link #glAreTexturesResident AreTexturesResident} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + @NativeType("GLboolean") + public static boolean glAreTexturesResident(@NativeType("GLuint const *") int[] textures, @NativeType("GLboolean *") ByteBuffer residences) { + long __functionAddress = GL.getICD().glAreTexturesResident; + if (CHECKS) { + check(__functionAddress); + check(residences, textures.length); + } + return callPPZ(textures.length, textures, memAddress(residences), __functionAddress); + } + + /** + * Array version of: {@link #glClipPlane ClipPlane} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glClipPlane(@NativeType("GLenum") int plane, @NativeType("GLdouble const *") double[] equation) { + long __functionAddress = GL.getICD().glClipPlane; + if (CHECKS) { + check(__functionAddress); + check(equation, 4); + } + callPV(plane, equation, __functionAddress); + } + + /** + * Array version of: {@link #glColor3sv Color3sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3sv(@NativeType("GLshort const *") short[] v) { + long __functionAddress = GL.getICD().glColor3sv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor3iv Color3iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3iv(@NativeType("GLint const *") int[] v) { + long __functionAddress = GL.getICD().glColor3iv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor3fv Color3fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3fv(@NativeType("GLfloat const *") float[] v) { + long __functionAddress = GL.getICD().glColor3fv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor3dv Color3dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3dv(@NativeType("GLdouble const *") double[] v) { + long __functionAddress = GL.getICD().glColor3dv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor3usv Color3usv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3usv(@NativeType("GLushort const *") short[] v) { + long __functionAddress = GL.getICD().glColor3usv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor3uiv Color3uiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor3uiv(@NativeType("GLuint const *") int[] v) { + long __functionAddress = GL.getICD().glColor3uiv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor4sv Color4sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4sv(@NativeType("GLshort const *") short[] v) { + long __functionAddress = GL.getICD().glColor4sv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor4iv Color4iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4iv(@NativeType("GLint const *") int[] v) { + long __functionAddress = GL.getICD().glColor4iv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor4fv Color4fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4fv(@NativeType("GLfloat const *") float[] v) { + long __functionAddress = GL.getICD().glColor4fv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor4dv Color4dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4dv(@NativeType("GLdouble const *") double[] v) { + long __functionAddress = GL.getICD().glColor4dv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor4usv Color4usv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4usv(@NativeType("GLushort const *") short[] v) { + long __functionAddress = GL.getICD().glColor4usv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glColor4uiv Color4uiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glColor4uiv(@NativeType("GLuint const *") int[] v) { + long __functionAddress = GL.getICD().glColor4uiv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glDrawPixels DrawPixels} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") short[] pixels) { + long __functionAddress = GL.getICD().glDrawPixels; + if (CHECKS) { + check(__functionAddress); + } + callPV(width, height, format, type, pixels, __functionAddress); + } + + /** + * Array version of: {@link #glDrawPixels DrawPixels} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") int[] pixels) { + long __functionAddress = GL.getICD().glDrawPixels; + if (CHECKS) { + check(__functionAddress); + } + callPV(width, height, format, type, pixels, __functionAddress); + } + + /** + * Array version of: {@link #glDrawPixels DrawPixels} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glDrawPixels(@NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") float[] pixels) { + long __functionAddress = GL.getICD().glDrawPixels; + if (CHECKS) { + check(__functionAddress); + } + callPV(width, height, format, type, pixels, __functionAddress); + } + + /** + * Array version of: {@link #glEvalCoord1fv EvalCoord1fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord1fv(@NativeType("GLfloat const *") float[] u) { + long __functionAddress = GL.getICD().glEvalCoord1fv; + if (CHECKS) { + check(__functionAddress); + check(u, 1); + } + callPV(u, __functionAddress); + } + + /** + * Array version of: {@link #glEvalCoord1dv EvalCoord1dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord1dv(@NativeType("GLdouble const *") double[] u) { + long __functionAddress = GL.getICD().glEvalCoord1dv; + if (CHECKS) { + check(__functionAddress); + check(u, 1); + } + callPV(u, __functionAddress); + } + + /** + * Array version of: {@link #glEvalCoord2fv EvalCoord2fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord2fv(@NativeType("GLfloat const *") float[] u) { + long __functionAddress = GL.getICD().glEvalCoord2fv; + if (CHECKS) { + check(__functionAddress); + check(u, 2); + } + callPV(u, __functionAddress); + } + + /** + * Array version of: {@link #glEvalCoord2dv EvalCoord2dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glEvalCoord2dv(@NativeType("GLdouble const *") double[] u) { + long __functionAddress = GL.getICD().glEvalCoord2dv; + if (CHECKS) { + check(__functionAddress); + check(u, 2); + } + callPV(u, __functionAddress); + } + + /** + * Array version of: {@link #glFeedbackBuffer FeedbackBuffer} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glFeedbackBuffer(@NativeType("GLenum") int type, @NativeType("GLfloat *") float[] buffer) { + long __functionAddress = GL.getICD().glFeedbackBuffer; + if (CHECKS) { + check(__functionAddress); + } + callPV(buffer.length, type, buffer, __functionAddress); + } + + /** + * Array version of: {@link #glFogiv Fogiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glFogiv(@NativeType("GLenum") int pname, @NativeType("GLint const *") int[] params) { + long __functionAddress = GL.getICD().glFogiv; + if (CHECKS) { + check(__functionAddress); + check(params, 1); + } + callPV(pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glFogfv Fogfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glFogfv(@NativeType("GLenum") int pname, @NativeType("GLfloat const *") float[] params) { + long __functionAddress = GL.getICD().glFogfv; + if (CHECKS) { + check(__functionAddress); + check(params, 1); + } + callPV(pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glGenTextures GenTextures} + * + * @see Reference Page + */ + public static void glGenTextures(@NativeType("GLuint *") int[] textures) { + GL11C.glGenTextures(textures); + } + + /** + * Array version of: {@link #glDeleteTextures DeleteTextures} + * + * @see Reference Page + */ + public static void glDeleteTextures(@NativeType("GLuint const *") int[] textures) { + GL11C.glDeleteTextures(textures); + } + + /** + * Array version of: {@link #glGetClipPlane GetClipPlane} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetClipPlane(@NativeType("GLenum") int plane, @NativeType("GLdouble *") double[] equation) { + long __functionAddress = GL.getICD().glGetClipPlane; + if (CHECKS) { + check(__functionAddress); + check(equation, 4); + } + callPV(plane, equation, __functionAddress); + } + + /** + * Array version of: {@link #glGetFloatv GetFloatv} + * + * @see Reference Page + */ + public static void glGetFloatv(@NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] params) { + GL11C.glGetFloatv(pname, params); + } + + /** + * Array version of: {@link #glGetIntegerv GetIntegerv} + * + * @see Reference Page + */ + public static void glGetIntegerv(@NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL11C.glGetIntegerv(pname, params); + } + + /** + * Array version of: {@link #glGetDoublev GetDoublev} + * + * @see Reference Page + */ + public static void glGetDoublev(@NativeType("GLenum") int pname, @NativeType("GLdouble *") double[] params) { + GL11C.glGetDoublev(pname, params); + } + + /** + * Array version of: {@link #glGetLightiv GetLightiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetLightiv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] data) { + long __functionAddress = GL.getICD().glGetLightiv; + if (CHECKS) { + check(__functionAddress); + check(data, 4); + } + callPV(light, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetLightfv GetLightfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetLightfv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] data) { + long __functionAddress = GL.getICD().glGetLightfv; + if (CHECKS) { + check(__functionAddress); + check(data, 4); + } + callPV(light, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetMapiv GetMapiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMapiv(@NativeType("GLenum") int target, @NativeType("GLenum") int query, @NativeType("GLint *") int[] data) { + long __functionAddress = GL.getICD().glGetMapiv; + if (CHECKS) { + check(__functionAddress); + check(data, 4); + } + callPV(target, query, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetMapfv GetMapfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMapfv(@NativeType("GLenum") int target, @NativeType("GLenum") int query, @NativeType("GLfloat *") float[] data) { + long __functionAddress = GL.getICD().glGetMapfv; + if (CHECKS) { + check(__functionAddress); + check(data, 4); + } + callPV(target, query, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetMapdv GetMapdv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMapdv(@NativeType("GLenum") int target, @NativeType("GLenum") int query, @NativeType("GLdouble *") double[] data) { + long __functionAddress = GL.getICD().glGetMapdv; + if (CHECKS) { + check(__functionAddress); + check(data, 4); + } + callPV(target, query, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetMaterialiv GetMaterialiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMaterialiv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] data) { + long __functionAddress = GL.getICD().glGetMaterialiv; + if (CHECKS) { + check(__functionAddress); + check(data, 1); + } + callPV(face, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetMaterialfv GetMaterialfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetMaterialfv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] data) { + long __functionAddress = GL.getICD().glGetMaterialfv; + if (CHECKS) { + check(__functionAddress); + check(data, 1); + } + callPV(face, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetPixelMapfv GetPixelMapfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapfv(@NativeType("GLenum") int map, @NativeType("GLfloat *") float[] data) { + long __functionAddress = GL.getICD().glGetPixelMapfv; + if (CHECKS) { + check(__functionAddress); + check(data, 32); + } + callPV(map, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetPixelMapusv GetPixelMapusv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapusv(@NativeType("GLenum") int map, @NativeType("GLushort *") short[] data) { + long __functionAddress = GL.getICD().glGetPixelMapusv; + if (CHECKS) { + check(__functionAddress); + check(data, 32); + } + callPV(map, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetPixelMapuiv GetPixelMapuiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetPixelMapuiv(@NativeType("GLenum") int map, @NativeType("GLuint *") int[] data) { + long __functionAddress = GL.getICD().glGetPixelMapuiv; + if (CHECKS) { + check(__functionAddress); + check(data, 32); + } + callPV(map, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetTexEnviv GetTexEnviv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexEnviv(@NativeType("GLenum") int env, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] data) { + long __functionAddress = GL.getICD().glGetTexEnviv; + if (CHECKS) { + check(__functionAddress); + check(data, 1); + } + callPV(env, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetTexEnvfv GetTexEnvfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexEnvfv(@NativeType("GLenum") int env, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] data) { + long __functionAddress = GL.getICD().glGetTexEnvfv; + if (CHECKS) { + check(__functionAddress); + check(data, 1); + } + callPV(env, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetTexGeniv GetTexGeniv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexGeniv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] data) { + long __functionAddress = GL.getICD().glGetTexGeniv; + if (CHECKS) { + check(__functionAddress); + check(data, 1); + } + callPV(coord, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetTexGenfv GetTexGenfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexGenfv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] data) { + long __functionAddress = GL.getICD().glGetTexGenfv; + if (CHECKS) { + check(__functionAddress); + check(data, 4); + } + callPV(coord, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetTexGendv GetTexGendv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glGetTexGendv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLdouble *") double[] data) { + long __functionAddress = GL.getICD().glGetTexGendv; + if (CHECKS) { + check(__functionAddress); + check(data, 4); + } + callPV(coord, pname, data, __functionAddress); + } + + /** + * Array version of: {@link #glGetTexImage GetTexImage} + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") short[] pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Array version of: {@link #glGetTexImage GetTexImage} + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") int[] pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Array version of: {@link #glGetTexImage GetTexImage} + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") float[] pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Array version of: {@link #glGetTexImage GetTexImage} + * + * @see Reference Page + */ + public static void glGetTexImage(@NativeType("GLenum") int tex, @NativeType("GLint") int level, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") double[] pixels) { + GL11C.glGetTexImage(tex, level, format, type, pixels); + } + + /** + * Array version of: {@link #glGetTexLevelParameteriv GetTexLevelParameteriv} + * + * @see Reference Page + */ + public static void glGetTexLevelParameteriv(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL11C.glGetTexLevelParameteriv(target, level, pname, params); + } + + /** + * Array version of: {@link #glGetTexLevelParameterfv GetTexLevelParameterfv} + * + * @see Reference Page + */ + public static void glGetTexLevelParameterfv(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] params) { + GL11C.glGetTexLevelParameterfv(target, level, pname, params); + } + + /** + * Array version of: {@link #glGetTexParameteriv GetTexParameteriv} + * + * @see Reference Page + */ + public static void glGetTexParameteriv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL11C.glGetTexParameteriv(target, pname, params); + } + + /** + * Array version of: {@link #glGetTexParameterfv GetTexParameterfv} + * + * @see Reference Page + */ + public static void glGetTexParameterfv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] params) { + GL11C.glGetTexParameterfv(target, pname, params); + } + + /** + * Array version of: {@link #glIndexiv Indexiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexiv(@NativeType("GLint const *") int[] index) { + long __functionAddress = GL.getICD().glIndexiv; + if (CHECKS) { + check(__functionAddress); + check(index, 1); + } + callPV(index, __functionAddress); + } + + /** + * Array version of: {@link #glIndexsv Indexsv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexsv(@NativeType("GLshort const *") short[] index) { + long __functionAddress = GL.getICD().glIndexsv; + if (CHECKS) { + check(__functionAddress); + check(index, 1); + } + callPV(index, __functionAddress); + } + + /** + * Array version of: {@link #glIndexfv Indexfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexfv(@NativeType("GLfloat const *") float[] index) { + long __functionAddress = GL.getICD().glIndexfv; + if (CHECKS) { + check(__functionAddress); + check(index, 1); + } + callPV(index, __functionAddress); + } + + /** + * Array version of: {@link #glIndexdv Indexdv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glIndexdv(@NativeType("GLdouble const *") double[] index) { + long __functionAddress = GL.getICD().glIndexdv; + if (CHECKS) { + check(__functionAddress); + check(index, 1); + } + callPV(index, __functionAddress); + } + + /** + * Array version of: {@link #glInterleavedArrays InterleavedArrays} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") short[] pointer) { + long __functionAddress = GL.getICD().glInterleavedArrays; + if (CHECKS) { + check(__functionAddress); + } + callPV(format, stride, pointer, __functionAddress); + } + + /** + * Array version of: {@link #glInterleavedArrays InterleavedArrays} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") int[] pointer) { + long __functionAddress = GL.getICD().glInterleavedArrays; + if (CHECKS) { + check(__functionAddress); + } + callPV(format, stride, pointer, __functionAddress); + } + + /** + * Array version of: {@link #glInterleavedArrays InterleavedArrays} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") float[] pointer) { + long __functionAddress = GL.getICD().glInterleavedArrays; + if (CHECKS) { + check(__functionAddress); + } + callPV(format, stride, pointer, __functionAddress); + } + + /** + * Array version of: {@link #glInterleavedArrays InterleavedArrays} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glInterleavedArrays(@NativeType("GLenum") int format, @NativeType("GLsizei") int stride, @NativeType("void const *") double[] pointer) { + long __functionAddress = GL.getICD().glInterleavedArrays; + if (CHECKS) { + check(__functionAddress); + } + callPV(format, stride, pointer, __functionAddress); + } + + /** + * Array version of: {@link #glLightModeliv LightModeliv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightModeliv(@NativeType("GLenum") int pname, @NativeType("GLint const *") int[] params) { + long __functionAddress = GL.getICD().glLightModeliv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glLightModelfv LightModelfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightModelfv(@NativeType("GLenum") int pname, @NativeType("GLfloat const *") float[] params) { + long __functionAddress = GL.getICD().glLightModelfv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glLightiv Lightiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightiv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLint const *") int[] params) { + long __functionAddress = GL.getICD().glLightiv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(light, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glLightfv Lightfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLightfv(@NativeType("GLenum") int light, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") float[] params) { + long __functionAddress = GL.getICD().glLightfv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(light, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glLoadMatrixf LoadMatrixf} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLoadMatrixf(@NativeType("GLfloat const *") float[] m) { + long __functionAddress = GL.getICD().glLoadMatrixf; + if (CHECKS) { + check(__functionAddress); + check(m, 16); + } + callPV(m, __functionAddress); + } + + /** + * Array version of: {@link #glLoadMatrixd LoadMatrixd} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glLoadMatrixd(@NativeType("GLdouble const *") double[] m) { + long __functionAddress = GL.getICD().glLoadMatrixd; + if (CHECKS) { + check(__functionAddress); + check(m, 16); + } + callPV(m, __functionAddress); + } + + /** + * Array version of: {@link #glMap1f Map1f} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap1f(@NativeType("GLenum") int target, @NativeType("GLfloat") float u1, @NativeType("GLfloat") float u2, @NativeType("GLint") int stride, @NativeType("GLint") int order, @NativeType("GLfloat const *") float[] points) { + long __functionAddress = GL.getICD().glMap1f; + if (CHECKS) { + check(__functionAddress); + check(points, order * stride); + } + callPV(target, u1, u2, stride, order, points, __functionAddress); + } + + /** + * Array version of: {@link #glMap1d Map1d} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap1d(@NativeType("GLenum") int target, @NativeType("GLdouble") double u1, @NativeType("GLdouble") double u2, @NativeType("GLint") int stride, @NativeType("GLint") int order, @NativeType("GLdouble const *") double[] points) { + long __functionAddress = GL.getICD().glMap1d; + if (CHECKS) { + check(__functionAddress); + check(points, stride * order); + } + callPV(target, u1, u2, stride, order, points, __functionAddress); + } + + /** + * Array version of: {@link #glMap2f Map2f} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap2f(@NativeType("GLenum") int target, @NativeType("GLfloat") float u1, @NativeType("GLfloat") float u2, @NativeType("GLint") int ustride, @NativeType("GLint") int uorder, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2, @NativeType("GLint") int vstride, @NativeType("GLint") int vorder, @NativeType("GLfloat const *") float[] points) { + long __functionAddress = GL.getICD().glMap2f; + if (CHECKS) { + check(__functionAddress); + check(points, ustride * uorder * vstride * vorder); + } + callPV(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points, __functionAddress); + } + + /** + * Array version of: {@link #glMap2d Map2d} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMap2d(@NativeType("GLenum") int target, @NativeType("GLdouble") double u1, @NativeType("GLdouble") double u2, @NativeType("GLint") int ustride, @NativeType("GLint") int uorder, @NativeType("GLdouble") double v1, @NativeType("GLdouble") double v2, @NativeType("GLint") int vstride, @NativeType("GLint") int vorder, @NativeType("GLdouble const *") double[] points) { + long __functionAddress = GL.getICD().glMap2d; + if (CHECKS) { + check(__functionAddress); + check(points, ustride * uorder * vstride * vorder); + } + callPV(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points, __functionAddress); + } + + /** + * Array version of: {@link #glMaterialiv Materialiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMaterialiv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLint const *") int[] params) { + long __functionAddress = GL.getICD().glMaterialiv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(face, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glMaterialfv Materialfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMaterialfv(@NativeType("GLenum") int face, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") float[] params) { + long __functionAddress = GL.getICD().glMaterialfv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(face, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glMultMatrixf MultMatrixf} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMultMatrixf(@NativeType("GLfloat const *") float[] m) { + long __functionAddress = GL.getICD().glMultMatrixf; + if (CHECKS) { + check(__functionAddress); + check(m, 16); + } + callPV(m, __functionAddress); + } + + /** + * Array version of: {@link #glMultMatrixd MultMatrixd} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glMultMatrixd(@NativeType("GLdouble const *") double[] m) { + long __functionAddress = GL.getICD().glMultMatrixd; + if (CHECKS) { + check(__functionAddress); + check(m, 16); + } + callPV(m, __functionAddress); + } + + /** + * Array version of: {@link #glNormal3fv Normal3fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3fv(@NativeType("GLfloat const *") float[] v) { + long __functionAddress = GL.getICD().glNormal3fv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glNormal3sv Normal3sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3sv(@NativeType("GLshort const *") short[] v) { + long __functionAddress = GL.getICD().glNormal3sv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glNormal3iv Normal3iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3iv(@NativeType("GLint const *") int[] v) { + long __functionAddress = GL.getICD().glNormal3iv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glNormal3dv Normal3dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glNormal3dv(@NativeType("GLdouble const *") double[] v) { + long __functionAddress = GL.getICD().glNormal3dv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glPixelMapfv PixelMapfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapfv(@NativeType("GLenum") int map, @NativeType("GLfloat const *") float[] values) { + long __functionAddress = GL.getICD().glPixelMapfv; + if (CHECKS) { + check(__functionAddress); + } + callPV(map, values.length, values, __functionAddress); + } + + /** + * Array version of: {@link #glPixelMapusv PixelMapusv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapusv(@NativeType("GLenum") int map, @NativeType("GLushort const *") short[] values) { + long __functionAddress = GL.getICD().glPixelMapusv; + if (CHECKS) { + check(__functionAddress); + } + callPV(map, values.length, values, __functionAddress); + } + + /** + * Array version of: {@link #glPixelMapuiv PixelMapuiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPixelMapuiv(@NativeType("GLenum") int map, @NativeType("GLuint const *") int[] values) { + long __functionAddress = GL.getICD().glPixelMapuiv; + if (CHECKS) { + check(__functionAddress); + } + callPV(map, values.length, values, __functionAddress); + } + + /** + * Array version of: {@link #glPrioritizeTextures PrioritizeTextures} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glPrioritizeTextures(@NativeType("GLuint const *") int[] textures, @NativeType("GLfloat const *") float[] priorities) { + long __functionAddress = GL.getICD().glPrioritizeTextures; + if (CHECKS) { + check(__functionAddress); + check(priorities, textures.length); + } + callPPV(textures.length, textures, priorities, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos2iv RasterPos2iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2iv(@NativeType("GLint const *") int[] coords) { + long __functionAddress = GL.getICD().glRasterPos2iv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos2sv RasterPos2sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2sv(@NativeType("GLshort const *") short[] coords) { + long __functionAddress = GL.getICD().glRasterPos2sv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos2fv RasterPos2fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2fv(@NativeType("GLfloat const *") float[] coords) { + long __functionAddress = GL.getICD().glRasterPos2fv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos2dv RasterPos2dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos2dv(@NativeType("GLdouble const *") double[] coords) { + long __functionAddress = GL.getICD().glRasterPos2dv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos3iv RasterPos3iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3iv(@NativeType("GLint const *") int[] coords) { + long __functionAddress = GL.getICD().glRasterPos3iv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos3sv RasterPos3sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3sv(@NativeType("GLshort const *") short[] coords) { + long __functionAddress = GL.getICD().glRasterPos3sv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos3fv RasterPos3fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3fv(@NativeType("GLfloat const *") float[] coords) { + long __functionAddress = GL.getICD().glRasterPos3fv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos3dv RasterPos3dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos3dv(@NativeType("GLdouble const *") double[] coords) { + long __functionAddress = GL.getICD().glRasterPos3dv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos4iv RasterPos4iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4iv(@NativeType("GLint const *") int[] coords) { + long __functionAddress = GL.getICD().glRasterPos4iv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos4sv RasterPos4sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4sv(@NativeType("GLshort const *") short[] coords) { + long __functionAddress = GL.getICD().glRasterPos4sv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos4fv RasterPos4fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4fv(@NativeType("GLfloat const *") float[] coords) { + long __functionAddress = GL.getICD().glRasterPos4fv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glRasterPos4dv RasterPos4dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRasterPos4dv(@NativeType("GLdouble const *") double[] coords) { + long __functionAddress = GL.getICD().glRasterPos4dv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glReadPixels ReadPixels} + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") short[] pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * Array version of: {@link #glReadPixels ReadPixels} + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") int[] pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * Array version of: {@link #glReadPixels ReadPixels} + * + * @see Reference Page + */ + public static void glReadPixels(@NativeType("GLint") int x, @NativeType("GLint") int y, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void *") float[] pixels) { + GL11C.glReadPixels(x, y, width, height, format, type, pixels); + } + + /** + * Array version of: {@link #glRectiv Rectiv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectiv(@NativeType("GLint const *") int[] v1, @NativeType("GLint const *") int[] v2) { + long __functionAddress = GL.getICD().glRectiv; + if (CHECKS) { + check(__functionAddress); + check(v1, 2); + check(v2, 2); + } + callPPV(v1, v2, __functionAddress); + } + + /** + * Array version of: {@link #glRectsv Rectsv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectsv(@NativeType("GLshort const *") short[] v1, @NativeType("GLshort const *") short[] v2) { + long __functionAddress = GL.getICD().glRectsv; + if (CHECKS) { + check(__functionAddress); + check(v1, 2); + check(v2, 2); + } + callPPV(v1, v2, __functionAddress); + } + + /** + * Array version of: {@link #glRectfv Rectfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectfv(@NativeType("GLfloat const *") float[] v1, @NativeType("GLfloat const *") float[] v2) { + long __functionAddress = GL.getICD().glRectfv; + if (CHECKS) { + check(__functionAddress); + check(v1, 2); + check(v2, 2); + } + callPPV(v1, v2, __functionAddress); + } + + /** + * Array version of: {@link #glRectdv Rectdv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glRectdv(@NativeType("GLdouble const *") double[] v1, @NativeType("GLdouble const *") double[] v2) { + long __functionAddress = GL.getICD().glRectdv; + if (CHECKS) { + check(__functionAddress); + check(v1, 2); + check(v2, 2); + } + callPPV(v1, v2, __functionAddress); + } + + /** + * Array version of: {@link #glSelectBuffer SelectBuffer} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glSelectBuffer(@NativeType("GLuint *") int[] buffer) { + long __functionAddress = GL.getICD().glSelectBuffer; + if (CHECKS) { + check(__functionAddress); + } + callPV(buffer.length, buffer, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord1fv TexCoord1fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1fv(@NativeType("GLfloat const *") float[] v) { + long __functionAddress = GL.getICD().glTexCoord1fv; + if (CHECKS) { + check(__functionAddress); + check(v, 1); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord1sv TexCoord1sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1sv(@NativeType("GLshort const *") short[] v) { + long __functionAddress = GL.getICD().glTexCoord1sv; + if (CHECKS) { + check(__functionAddress); + check(v, 1); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord1iv TexCoord1iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1iv(@NativeType("GLint const *") int[] v) { + long __functionAddress = GL.getICD().glTexCoord1iv; + if (CHECKS) { + check(__functionAddress); + check(v, 1); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord1dv TexCoord1dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord1dv(@NativeType("GLdouble const *") double[] v) { + long __functionAddress = GL.getICD().glTexCoord1dv; + if (CHECKS) { + check(__functionAddress); + check(v, 1); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord2fv TexCoord2fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2fv(@NativeType("GLfloat const *") float[] v) { + long __functionAddress = GL.getICD().glTexCoord2fv; + if (CHECKS) { + check(__functionAddress); + check(v, 2); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord2sv TexCoord2sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2sv(@NativeType("GLshort const *") short[] v) { + long __functionAddress = GL.getICD().glTexCoord2sv; + if (CHECKS) { + check(__functionAddress); + check(v, 2); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord2iv TexCoord2iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2iv(@NativeType("GLint const *") int[] v) { + long __functionAddress = GL.getICD().glTexCoord2iv; + if (CHECKS) { + check(__functionAddress); + check(v, 2); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord2dv TexCoord2dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord2dv(@NativeType("GLdouble const *") double[] v) { + long __functionAddress = GL.getICD().glTexCoord2dv; + if (CHECKS) { + check(__functionAddress); + check(v, 2); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord3fv TexCoord3fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3fv(@NativeType("GLfloat const *") float[] v) { + long __functionAddress = GL.getICD().glTexCoord3fv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord3sv TexCoord3sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3sv(@NativeType("GLshort const *") short[] v) { + long __functionAddress = GL.getICD().glTexCoord3sv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord3iv TexCoord3iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3iv(@NativeType("GLint const *") int[] v) { + long __functionAddress = GL.getICD().glTexCoord3iv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord3dv TexCoord3dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord3dv(@NativeType("GLdouble const *") double[] v) { + long __functionAddress = GL.getICD().glTexCoord3dv; + if (CHECKS) { + check(__functionAddress); + check(v, 3); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord4fv TexCoord4fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4fv(@NativeType("GLfloat const *") float[] v) { + long __functionAddress = GL.getICD().glTexCoord4fv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord4sv TexCoord4sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4sv(@NativeType("GLshort const *") short[] v) { + long __functionAddress = GL.getICD().glTexCoord4sv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord4iv TexCoord4iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4iv(@NativeType("GLint const *") int[] v) { + long __functionAddress = GL.getICD().glTexCoord4iv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexCoord4dv TexCoord4dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexCoord4dv(@NativeType("GLdouble const *") double[] v) { + long __functionAddress = GL.getICD().glTexCoord4dv; + if (CHECKS) { + check(__functionAddress); + check(v, 4); + } + callPV(v, __functionAddress); + } + + /** + * Array version of: {@link #glTexEnviv TexEnviv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexEnviv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint const *") int[] params) { + long __functionAddress = GL.getICD().glTexEnviv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(target, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glTexEnvfv TexEnvfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexEnvfv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") float[] params) { + long __functionAddress = GL.getICD().glTexEnvfv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(target, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glTexGeniv TexGeniv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexGeniv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLint const *") int[] params) { + long __functionAddress = GL.getICD().glTexGeniv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(coord, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glTexGenfv TexGenfv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexGenfv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") float[] params) { + long __functionAddress = GL.getICD().glTexGenfv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(coord, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glTexGendv TexGendv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glTexGendv(@NativeType("GLenum") int coord, @NativeType("GLenum") int pname, @NativeType("GLdouble const *") double[] params) { + long __functionAddress = GL.getICD().glTexGendv; + if (CHECKS) { + check(__functionAddress); + check(params, 4); + } + callPV(coord, pname, params, __functionAddress); + } + + /** + * Array version of: {@link #glTexImage1D TexImage1D} + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") short[] pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexImage1D TexImage1D} + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") int[] pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexImage1D TexImage1D} + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") float[] pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexImage1D TexImage1D} + * + * @see Reference Page + */ + public static void glTexImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") double[] pixels) { + GL11C.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexImage2D TexImage2D} + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") short[] pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexImage2D TexImage2D} + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") int[] pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexImage2D TexImage2D} + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") float[] pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexImage2D TexImage2D} + * + * @see Reference Page + */ + public static void glTexImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int internalformat, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLint") int border, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @Nullable @NativeType("void const *") double[] pixels) { + GL11C.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + } + + /** + * Array version of: {@link #glTexParameteriv TexParameteriv} + * + * @see Reference Page + */ + public static void glTexParameteriv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint const *") int[] params) { + GL11C.glTexParameteriv(target, pname, params); + } + + /** + * Array version of: {@link #glTexParameterfv TexParameterfv} + * + * @see Reference Page + */ + public static void glTexParameterfv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLfloat const *") float[] params) { + GL11C.glTexParameterfv(target, pname, params); + } + + /** + * Array version of: {@link #glTexSubImage1D TexSubImage1D} + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") short[] pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * Array version of: {@link #glTexSubImage1D TexSubImage1D} + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") int[] pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * Array version of: {@link #glTexSubImage1D TexSubImage1D} + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") float[] pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * Array version of: {@link #glTexSubImage1D TexSubImage1D} + * + * @see Reference Page + */ + public static void glTexSubImage1D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLsizei") int width, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") double[] pixels) { + GL11C.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + } + + /** + * Array version of: {@link #glTexSubImage2D TexSubImage2D} + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") short[] pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Array version of: {@link #glTexSubImage2D TexSubImage2D} + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") int[] pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Array version of: {@link #glTexSubImage2D TexSubImage2D} + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") float[] pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Array version of: {@link #glTexSubImage2D TexSubImage2D} + * + * @see Reference Page + */ + public static void glTexSubImage2D(@NativeType("GLenum") int target, @NativeType("GLint") int level, @NativeType("GLint") int xoffset, @NativeType("GLint") int yoffset, @NativeType("GLsizei") int width, @NativeType("GLsizei") int height, @NativeType("GLenum") int format, @NativeType("GLenum") int type, @NativeType("void const *") double[] pixels) { + GL11C.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } + + /** + * Array version of: {@link #glVertex2fv Vertex2fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2fv(@NativeType("GLfloat const *") float[] coords) { + long __functionAddress = GL.getICD().glVertex2fv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex2sv Vertex2sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2sv(@NativeType("GLshort const *") short[] coords) { + long __functionAddress = GL.getICD().glVertex2sv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex2iv Vertex2iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2iv(@NativeType("GLint const *") int[] coords) { + long __functionAddress = GL.getICD().glVertex2iv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex2dv Vertex2dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex2dv(@NativeType("GLdouble const *") double[] coords) { + long __functionAddress = GL.getICD().glVertex2dv; + if (CHECKS) { + check(__functionAddress); + check(coords, 2); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex3fv Vertex3fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3fv(@NativeType("GLfloat const *") float[] coords) { + long __functionAddress = GL.getICD().glVertex3fv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex3sv Vertex3sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3sv(@NativeType("GLshort const *") short[] coords) { + long __functionAddress = GL.getICD().glVertex3sv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex3iv Vertex3iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3iv(@NativeType("GLint const *") int[] coords) { + long __functionAddress = GL.getICD().glVertex3iv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex3dv Vertex3dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex3dv(@NativeType("GLdouble const *") double[] coords) { + long __functionAddress = GL.getICD().glVertex3dv; + if (CHECKS) { + check(__functionAddress); + check(coords, 3); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex4fv Vertex4fv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4fv(@NativeType("GLfloat const *") float[] coords) { + long __functionAddress = GL.getICD().glVertex4fv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex4sv Vertex4sv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4sv(@NativeType("GLshort const *") short[] coords) { + long __functionAddress = GL.getICD().glVertex4sv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex4iv Vertex4iv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4iv(@NativeType("GLint const *") int[] coords) { + long __functionAddress = GL.getICD().glVertex4iv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + + /** + * Array version of: {@link #glVertex4dv Vertex4dv} + * + * @see Reference Page - This function is deprecated and unavailable in the Core profile + */ + public static void glVertex4dv(@NativeType("GLdouble const *") double[] coords) { + long __functionAddress = GL.getICD().glVertex4dv; + if (CHECKS) { + check(__functionAddress); + check(coords, 4); + } + callPV(coords, __functionAddress); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL15.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL15.java new file mode 100644 index 000000000..373c620e3 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL15.java @@ -0,0 +1,1200 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.opengl; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; + +/** + * The OpenGL functionality up to version 1.5. Includes the deprecated symbols of the Compatibility Profile. + * + *

Extensions promoted to core in this release:

+ * + * + */ +public class GL15 extends GL14 { + + /** New token names. */ + public static final int + GL_FOG_COORD_SRC = 0x8450, + GL_FOG_COORD = 0x8451, + GL_CURRENT_FOG_COORD = 0x8453, + GL_FOG_COORD_ARRAY_TYPE = 0x8454, + GL_FOG_COORD_ARRAY_STRIDE = 0x8455, + GL_FOG_COORD_ARRAY_POINTER = 0x8456, + GL_FOG_COORD_ARRAY = 0x8457, + GL_FOG_COORD_ARRAY_BUFFER_BINDING = 0x889D, + GL_SRC0_RGB = 0x8580, + GL_SRC1_RGB = 0x8581, + GL_SRC2_RGB = 0x8582, + GL_SRC0_ALPHA = 0x8588, + GL_SRC1_ALPHA = 0x8589, + GL_SRC2_ALPHA = 0x858A; + + /** + * Accepted by the {@code target} parameters of BindBuffer, BufferData, BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, + * GetBufferParameteriv, and GetBufferPointerv. + */ + public static final int + GL_ARRAY_BUFFER = 0x8892, + GL_ELEMENT_ARRAY_BUFFER = 0x8893; + + /** Accepted by the {@code pname} parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev. */ + public static final int + GL_ARRAY_BUFFER_BINDING = 0x8894, + GL_ELEMENT_ARRAY_BUFFER_BINDING = 0x8895, + GL_VERTEX_ARRAY_BUFFER_BINDING = 0x8896, + GL_NORMAL_ARRAY_BUFFER_BINDING = 0x8897, + GL_COLOR_ARRAY_BUFFER_BINDING = 0x8898, + GL_INDEX_ARRAY_BUFFER_BINDING = 0x8899, + GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = 0x889A, + GL_EDGE_FLAG_ARRAY_BUFFER_BINDING = 0x889B, + GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = 0x889C, + GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = 0x889D, + GL_WEIGHT_ARRAY_BUFFER_BINDING = 0x889E; + + /** Accepted by the {@code pname} parameter of GetVertexAttribiv. */ + public static final int GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F; + + /** Accepted by the {@code usage} parameter of BufferData. */ + public static final int + GL_STREAM_DRAW = 0x88E0, + GL_STREAM_READ = 0x88E1, + GL_STREAM_COPY = 0x88E2, + GL_STATIC_DRAW = 0x88E4, + GL_STATIC_READ = 0x88E5, + GL_STATIC_COPY = 0x88E6, + GL_DYNAMIC_DRAW = 0x88E8, + GL_DYNAMIC_READ = 0x88E9, + GL_DYNAMIC_COPY = 0x88EA; + + /** Accepted by the {@code access} parameter of MapBuffer. */ + public static final int + GL_READ_ONLY = 0x88B8, + GL_WRITE_ONLY = 0x88B9, + GL_READ_WRITE = 0x88BA; + + /** Accepted by the {@code pname} parameter of GetBufferParameteriv. */ + public static final int + GL_BUFFER_SIZE = 0x8764, + GL_BUFFER_USAGE = 0x8765, + GL_BUFFER_ACCESS = 0x88BB, + GL_BUFFER_MAPPED = 0x88BC; + + /** Accepted by the {@code pname} parameter of GetBufferPointerv. */ + public static final int GL_BUFFER_MAP_POINTER = 0x88BD; + + /** Accepted by the {@code target} parameter of BeginQuery, EndQuery, and GetQueryiv. */ + public static final int GL_SAMPLES_PASSED = 0x8914; + + /** Accepted by the {@code pname} parameter of GetQueryiv. */ + public static final int + GL_QUERY_COUNTER_BITS = 0x8864, + GL_CURRENT_QUERY = 0x8865; + + /** Accepted by the {@code pname} parameter of GetQueryObjectiv and GetQueryObjectuiv. */ + public static final int + GL_QUERY_RESULT = 0x8866, + GL_QUERY_RESULT_AVAILABLE = 0x8867; + + static { GL.initialize(); } + + protected GL15() { + throw new UnsupportedOperationException(); + } + + static boolean isAvailable(GLCapabilities caps) { + return checkFunctions( + caps.glBindBuffer, caps.glDeleteBuffers, caps.glGenBuffers, caps.glIsBuffer, caps.glBufferData, caps.glBufferSubData, caps.glGetBufferSubData, + caps.glMapBuffer, caps.glUnmapBuffer, caps.glGetBufferParameteriv, caps.glGetBufferPointerv, caps.glGenQueries, caps.glDeleteQueries, + caps.glIsQuery, caps.glBeginQuery, caps.glEndQuery, caps.glGetQueryiv, caps.glGetQueryObjectiv, caps.glGetQueryObjectuiv + ); + } + + // --- [ glBindBuffer ] --- + + /** + * Binds a named buffer object. + * + * @param target the target to which the buffer object is bound. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param buffer the name of a buffer object + * + * @see Reference Page + */ + public static void glBindBuffer(@NativeType("GLenum") int target, @NativeType("GLuint") int buffer) { + GL15C.glBindBuffer(target, buffer); + } + + // --- [ glDeleteBuffers ] --- + + /** + * Unsafe version of: {@link #glDeleteBuffers DeleteBuffers} + * + * @param n the number of buffer objects to be deleted + */ + public static void nglDeleteBuffers(int n, long buffers) { + GL15C.nglDeleteBuffers(n, buffers); + } + + /** + * Deletes named buffer objects. + * + * @param buffers an array of buffer objects to be deleted + * + * @see Reference Page + */ + public static void glDeleteBuffers(@NativeType("GLuint const *") IntBuffer buffers) { + GL15C.glDeleteBuffers(buffers); + } + + /** + * Deletes named buffer objects. + * + * @see Reference Page + */ + public static void glDeleteBuffers(@NativeType("GLuint const *") int buffer) { + GL15C.glDeleteBuffers(buffer); + } + + // --- [ glGenBuffers ] --- + + /** + * Unsafe version of: {@link #glGenBuffers GenBuffers} + * + * @param n the number of buffer object names to be generated + */ + public static void nglGenBuffers(int n, long buffers) { + GL15C.nglGenBuffers(n, buffers); + } + + /** + * Generates buffer object names. + * + * @param buffers a buffer in which the generated buffer object names are stored + * + * @see Reference Page + */ + public static void glGenBuffers(@NativeType("GLuint *") IntBuffer buffers) { + GL15C.glGenBuffers(buffers); + } + + /** + * Generates buffer object names. + * + * @see Reference Page + */ + @NativeType("void") + public static int glGenBuffers() { + return GL15C.glGenBuffers(); + } + + // --- [ glIsBuffer ] --- + + /** + * Determines if a name corresponds to a buffer object. + * + * @param buffer a value that may be the name of a buffer object + * + * @see Reference Page + */ + @NativeType("GLboolean") + public static boolean glIsBuffer(@NativeType("GLuint") int buffer) { + return GL15C.glIsBuffer(buffer); + } + + // --- [ glBufferData ] --- + + /** + * Unsafe version of: {@link #glBufferData BufferData} + * + * @param size the size in bytes of the buffer object's new data store + */ + public static void nglBufferData(int target, long size, long data, int usage) { + GL15C.nglBufferData(target, size, data, usage); + } + + /** + * Creates and initializes a buffer object's data store. + * + *

{@code usage} is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make + * more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store. + * {@code usage} can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access. The + * frequency of access may be one of these:

+ * + *
    + *
  • STREAM - The data store contents will be modified once and used at most a few times.
  • + *
  • STATIC - The data store contents will be modified once and used many times.
  • + *
  • DYNAMIC - The data store contents will be modified repeatedly and used many times.
  • + *
+ * + *

The nature of access may be one of these:

+ * + *
    + *
  • DRAW - The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
  • + *
  • READ - The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
  • + *
  • COPY - The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.
  • + *
+ * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param size the size in bytes of the buffer object's new data store + * @param usage the expected usage pattern of the data store. One of:
{@link GL15C#GL_STREAM_DRAW STREAM_DRAW}{@link GL15C#GL_STREAM_READ STREAM_READ}{@link GL15C#GL_STREAM_COPY STREAM_COPY}{@link GL15C#GL_STATIC_DRAW STATIC_DRAW}{@link GL15C#GL_STATIC_READ STATIC_READ}{@link GL15C#GL_STATIC_COPY STATIC_COPY}{@link GL15C#GL_DYNAMIC_DRAW DYNAMIC_DRAW}
{@link GL15C#GL_DYNAMIC_READ DYNAMIC_READ}{@link GL15C#GL_DYNAMIC_COPY DYNAMIC_COPY}
+ * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("GLsizeiptr") long size, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, size, usage); + } + + /** + * Creates and initializes a buffer object's data store. + * + *

{@code usage} is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make + * more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store. + * {@code usage} can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access. The + * frequency of access may be one of these:

+ * + *
    + *
  • STREAM - The data store contents will be modified once and used at most a few times.
  • + *
  • STATIC - The data store contents will be modified once and used many times.
  • + *
  • DYNAMIC - The data store contents will be modified repeatedly and used many times.
  • + *
+ * + *

The nature of access may be one of these:

+ * + *
    + *
  • DRAW - The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
  • + *
  • READ - The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
  • + *
  • COPY - The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.
  • + *
+ * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied + * @param usage the expected usage pattern of the data store. One of:
{@link GL15C#GL_STREAM_DRAW STREAM_DRAW}{@link GL15C#GL_STREAM_READ STREAM_READ}{@link GL15C#GL_STREAM_COPY STREAM_COPY}{@link GL15C#GL_STATIC_DRAW STATIC_DRAW}{@link GL15C#GL_STATIC_READ STATIC_READ}{@link GL15C#GL_STATIC_COPY STATIC_COPY}{@link GL15C#GL_DYNAMIC_DRAW DYNAMIC_DRAW}
{@link GL15C#GL_DYNAMIC_READ DYNAMIC_READ}{@link GL15C#GL_DYNAMIC_COPY DYNAMIC_COPY}
+ * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") ByteBuffer data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Creates and initializes a buffer object's data store. + * + *

{@code usage} is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make + * more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store. + * {@code usage} can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access. The + * frequency of access may be one of these:

+ * + *
    + *
  • STREAM - The data store contents will be modified once and used at most a few times.
  • + *
  • STATIC - The data store contents will be modified once and used many times.
  • + *
  • DYNAMIC - The data store contents will be modified repeatedly and used many times.
  • + *
+ * + *

The nature of access may be one of these:

+ * + *
    + *
  • DRAW - The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
  • + *
  • READ - The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
  • + *
  • COPY - The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.
  • + *
+ * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied + * @param usage the expected usage pattern of the data store. One of:
{@link GL15C#GL_STREAM_DRAW STREAM_DRAW}{@link GL15C#GL_STREAM_READ STREAM_READ}{@link GL15C#GL_STREAM_COPY STREAM_COPY}{@link GL15C#GL_STATIC_DRAW STATIC_DRAW}{@link GL15C#GL_STATIC_READ STATIC_READ}{@link GL15C#GL_STATIC_COPY STATIC_COPY}{@link GL15C#GL_DYNAMIC_DRAW DYNAMIC_DRAW}
{@link GL15C#GL_DYNAMIC_READ DYNAMIC_READ}{@link GL15C#GL_DYNAMIC_COPY DYNAMIC_COPY}
+ * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") ShortBuffer data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Creates and initializes a buffer object's data store. + * + *

{@code usage} is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make + * more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store. + * {@code usage} can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access. The + * frequency of access may be one of these:

+ * + *
    + *
  • STREAM - The data store contents will be modified once and used at most a few times.
  • + *
  • STATIC - The data store contents will be modified once and used many times.
  • + *
  • DYNAMIC - The data store contents will be modified repeatedly and used many times.
  • + *
+ * + *

The nature of access may be one of these:

+ * + *
    + *
  • DRAW - The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
  • + *
  • READ - The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
  • + *
  • COPY - The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.
  • + *
+ * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied + * @param usage the expected usage pattern of the data store. One of:
{@link GL15C#GL_STREAM_DRAW STREAM_DRAW}{@link GL15C#GL_STREAM_READ STREAM_READ}{@link GL15C#GL_STREAM_COPY STREAM_COPY}{@link GL15C#GL_STATIC_DRAW STATIC_DRAW}{@link GL15C#GL_STATIC_READ STATIC_READ}{@link GL15C#GL_STATIC_COPY STATIC_COPY}{@link GL15C#GL_DYNAMIC_DRAW DYNAMIC_DRAW}
{@link GL15C#GL_DYNAMIC_READ DYNAMIC_READ}{@link GL15C#GL_DYNAMIC_COPY DYNAMIC_COPY}
+ * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") IntBuffer data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Creates and initializes a buffer object's data store. + * + *

{@code usage} is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make + * more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store. + * {@code usage} can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access. The + * frequency of access may be one of these:

+ * + *
    + *
  • STREAM - The data store contents will be modified once and used at most a few times.
  • + *
  • STATIC - The data store contents will be modified once and used many times.
  • + *
  • DYNAMIC - The data store contents will be modified repeatedly and used many times.
  • + *
+ * + *

The nature of access may be one of these:

+ * + *
    + *
  • DRAW - The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
  • + *
  • READ - The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
  • + *
  • COPY - The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.
  • + *
+ * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied + * @param usage the expected usage pattern of the data store. One of:
{@link GL15C#GL_STREAM_DRAW STREAM_DRAW}{@link GL15C#GL_STREAM_READ STREAM_READ}{@link GL15C#GL_STREAM_COPY STREAM_COPY}{@link GL15C#GL_STATIC_DRAW STATIC_DRAW}{@link GL15C#GL_STATIC_READ STATIC_READ}{@link GL15C#GL_STATIC_COPY STATIC_COPY}{@link GL15C#GL_DYNAMIC_DRAW DYNAMIC_DRAW}
{@link GL15C#GL_DYNAMIC_READ DYNAMIC_READ}{@link GL15C#GL_DYNAMIC_COPY DYNAMIC_COPY}
+ * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") LongBuffer data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Creates and initializes a buffer object's data store. + * + *

{@code usage} is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make + * more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store. + * {@code usage} can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access. The + * frequency of access may be one of these:

+ * + *
    + *
  • STREAM - The data store contents will be modified once and used at most a few times.
  • + *
  • STATIC - The data store contents will be modified once and used many times.
  • + *
  • DYNAMIC - The data store contents will be modified repeatedly and used many times.
  • + *
+ * + *

The nature of access may be one of these:

+ * + *
    + *
  • DRAW - The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
  • + *
  • READ - The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
  • + *
  • COPY - The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.
  • + *
+ * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied + * @param usage the expected usage pattern of the data store. One of:
{@link GL15C#GL_STREAM_DRAW STREAM_DRAW}{@link GL15C#GL_STREAM_READ STREAM_READ}{@link GL15C#GL_STREAM_COPY STREAM_COPY}{@link GL15C#GL_STATIC_DRAW STATIC_DRAW}{@link GL15C#GL_STATIC_READ STATIC_READ}{@link GL15C#GL_STATIC_COPY STATIC_COPY}{@link GL15C#GL_DYNAMIC_DRAW DYNAMIC_DRAW}
{@link GL15C#GL_DYNAMIC_READ DYNAMIC_READ}{@link GL15C#GL_DYNAMIC_COPY DYNAMIC_COPY}
+ * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") FloatBuffer data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Creates and initializes a buffer object's data store. + * + *

{@code usage} is a hint to the GL implementation as to how a buffer object's data store will be accessed. This enables the GL implementation to make + * more intelligent decisions that may significantly impact buffer object performance. It does not, however, constrain the actual usage of the data store. + * {@code usage} can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access. The + * frequency of access may be one of these:

+ * + *
    + *
  • STREAM - The data store contents will be modified once and used at most a few times.
  • + *
  • STATIC - The data store contents will be modified once and used many times.
  • + *
  • DYNAMIC - The data store contents will be modified repeatedly and used many times.
  • + *
+ * + *

The nature of access may be one of these:

+ * + *
    + *
  • DRAW - The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.
  • + *
  • READ - The data store contents are modified by reading data from the GL, and used to return that data when queried by the application.
  • + *
  • COPY - The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.
  • + *
+ * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param data a pointer to data that will be copied into the data store for initialization, or {@code NULL} if no data is to be copied + * @param usage the expected usage pattern of the data store. One of:
{@link GL15C#GL_STREAM_DRAW STREAM_DRAW}{@link GL15C#GL_STREAM_READ STREAM_READ}{@link GL15C#GL_STREAM_COPY STREAM_COPY}{@link GL15C#GL_STATIC_DRAW STATIC_DRAW}{@link GL15C#GL_STATIC_READ STATIC_READ}{@link GL15C#GL_STATIC_COPY STATIC_COPY}{@link GL15C#GL_DYNAMIC_DRAW DYNAMIC_DRAW}
{@link GL15C#GL_DYNAMIC_READ DYNAMIC_READ}{@link GL15C#GL_DYNAMIC_COPY DYNAMIC_COPY}
+ * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") DoubleBuffer data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + // --- [ glBufferSubData ] --- + + /** + * Unsafe version of: {@link #glBufferSubData BufferSubData} + * + * @param size the size in bytes of the data store region being replaced + */ + public static void nglBufferSubData(int target, long offset, long size, long data) { + GL15C.nglBufferSubData(target, offset, size, data); + } + + /** + * Updates a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes + * @param data a pointer to the new data that will be copied into the data store + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") ByteBuffer data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Updates a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes + * @param data a pointer to the new data that will be copied into the data store + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") ShortBuffer data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Updates a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes + * @param data a pointer to the new data that will be copied into the data store + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") IntBuffer data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Updates a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes + * @param data a pointer to the new data that will be copied into the data store + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") LongBuffer data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Updates a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes + * @param data a pointer to the new data that will be copied into the data store + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") FloatBuffer data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Updates a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store where data replacement will begin, measured in bytes + * @param data a pointer to the new data that will be copied into the data store + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") DoubleBuffer data) { + GL15C.glBufferSubData(target, offset, data); + } + + // --- [ glGetBufferSubData ] --- + + /** + * Unsafe version of: {@link #glGetBufferSubData GetBufferSubData} + * + * @param size the size in bytes of the data store region being returned + */ + public static void nglGetBufferSubData(int target, long offset, long size, long data) { + GL15C.nglGetBufferSubData(target, offset, size, data); + } + + /** + * Returns a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store from which data will be returned, measured in bytes + * @param data a pointer to the location where buffer object data is returned + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") ByteBuffer data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Returns a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store from which data will be returned, measured in bytes + * @param data a pointer to the location where buffer object data is returned + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") ShortBuffer data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Returns a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store from which data will be returned, measured in bytes + * @param data a pointer to the location where buffer object data is returned + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") IntBuffer data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Returns a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store from which data will be returned, measured in bytes + * @param data a pointer to the location where buffer object data is returned + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") LongBuffer data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Returns a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store from which data will be returned, measured in bytes + * @param data a pointer to the location where buffer object data is returned + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") FloatBuffer data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Returns a subset of a buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param offset the offset into the buffer object's data store from which data will be returned, measured in bytes + * @param data a pointer to the location where buffer object data is returned + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") DoubleBuffer data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + // --- [ glMapBuffer ] --- + + /** Unsafe version of: {@link #glMapBuffer MapBuffer} */ + public static long nglMapBuffer(int target, int access) { + return GL15C.nglMapBuffer(target, access); + } + + /** + * Maps a buffer object's data store. + * + *

LWJGL note: This method comes in 3 flavors:

+ * + *
    + *
  1. {@link #glMapBuffer(int, int)} - Calls {@link #glGetBufferParameteriv GetBufferParameteriv} to retrieve the buffer size and a new ByteBuffer instance is always returned.
  2. + *
  3. {@link #glMapBuffer(int, int, ByteBuffer)} - Calls {@link #glGetBufferParameteriv GetBufferParameteriv} to retrieve the buffer size and the {@code old_buffer} parameter is reused if not null.
  4. + *
  5. {@link #glMapBuffer(int, int, long, ByteBuffer)} - The buffer size is explicitly specified and the {@code old_buffer} parameter is reused if not null. This is the most efficient method.
  6. + *
+ * + * @param target the target buffer object being mapped. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param access the access policy, indicating whether it will be possible to read from, write to, or both read from and write to the buffer object's mapped data store. One of:
{@link GL15C#GL_READ_ONLY READ_ONLY}{@link GL15C#GL_WRITE_ONLY WRITE_ONLY}{@link GL15C#GL_READ_WRITE READ_WRITE}
+ * + * @see Reference Page + */ + @Nullable + @NativeType("void *") + public static ByteBuffer glMapBuffer(@NativeType("GLenum") int target, @NativeType("GLenum") int access) { + return GL15C.glMapBuffer(target, access); + } + + /** + * Maps a buffer object's data store. + * + *

LWJGL note: This method comes in 3 flavors:

+ * + *
    + *
  1. {@link #glMapBuffer(int, int)} - Calls {@link #glGetBufferParameteriv GetBufferParameteriv} to retrieve the buffer size and a new ByteBuffer instance is always returned.
  2. + *
  3. {@link #glMapBuffer(int, int, ByteBuffer)} - Calls {@link #glGetBufferParameteriv GetBufferParameteriv} to retrieve the buffer size and the {@code old_buffer} parameter is reused if not null.
  4. + *
  5. {@link #glMapBuffer(int, int, long, ByteBuffer)} - The buffer size is explicitly specified and the {@code old_buffer} parameter is reused if not null. This is the most efficient method.
  6. + *
+ * + * @param target the target buffer object being mapped. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param access the access policy, indicating whether it will be possible to read from, write to, or both read from and write to the buffer object's mapped data store. One of:
{@link GL15C#GL_READ_ONLY READ_ONLY}{@link GL15C#GL_WRITE_ONLY WRITE_ONLY}{@link GL15C#GL_READ_WRITE READ_WRITE}
+ * + * @see Reference Page + */ + @Nullable + @NativeType("void *") + public static ByteBuffer glMapBuffer(@NativeType("GLenum") int target, @NativeType("GLenum") int access, @Nullable ByteBuffer old_buffer) { + return GL15C.glMapBuffer(target, access, old_buffer); + } + + /** + * Maps a buffer object's data store. + * + *

LWJGL note: This method comes in 3 flavors:

+ * + *
    + *
  1. {@link #glMapBuffer(int, int)} - Calls {@link #glGetBufferParameteriv GetBufferParameteriv} to retrieve the buffer size and a new ByteBuffer instance is always returned.
  2. + *
  3. {@link #glMapBuffer(int, int, ByteBuffer)} - Calls {@link #glGetBufferParameteriv GetBufferParameteriv} to retrieve the buffer size and the {@code old_buffer} parameter is reused if not null.
  4. + *
  5. {@link #glMapBuffer(int, int, long, ByteBuffer)} - The buffer size is explicitly specified and the {@code old_buffer} parameter is reused if not null. This is the most efficient method.
  6. + *
+ * + * @param target the target buffer object being mapped. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param access the access policy, indicating whether it will be possible to read from, write to, or both read from and write to the buffer object's mapped data store. One of:
{@link GL15C#GL_READ_ONLY READ_ONLY}{@link GL15C#GL_WRITE_ONLY WRITE_ONLY}{@link GL15C#GL_READ_WRITE READ_WRITE}
+ * + * @see Reference Page + */ + @Nullable + @NativeType("void *") + public static ByteBuffer glMapBuffer(@NativeType("GLenum") int target, @NativeType("GLenum") int access, long length, @Nullable ByteBuffer old_buffer) { + return GL15C.glMapBuffer(target, access, length, old_buffer); + } + + // --- [ glUnmapBuffer ] --- + + /** + * Relinquishes the mapping of a buffer object and invalidates the pointer to its data store. + * + *

Returns TRUE unless data values in the buffer’s data store have become corrupted during the period that the buffer was mapped. Such corruption can be + * the result of a screen resolution change or other window system-dependent event that causes system heaps such as those for high-performance graphics + * memory to be discarded. GL implementations must guarantee that such corruption can occur only during the periods that a buffer’s data store is mapped. + * If such corruption has occurred, UnmapBuffer returns FALSE, and the contents of the buffer’s data store become undefined.

+ * + * @param target the target buffer object being unmapped. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * + * @see Reference Page + */ + @NativeType("GLboolean") + public static boolean glUnmapBuffer(@NativeType("GLenum") int target) { + return GL15C.glUnmapBuffer(target); + } + + // --- [ glGetBufferParameteriv ] --- + + /** Unsafe version of: {@link #glGetBufferParameteriv GetBufferParameteriv} */ + public static void nglGetBufferParameteriv(int target, int pname, long params) { + GL15C.nglGetBufferParameteriv(target, pname, params); + } + + /** + * Returns the value of a buffer object parameter. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param pname the symbolic name of a buffer object parameter. One of:
{@link GL15#GL_BUFFER_SIZE BUFFER_SIZE}{@link GL15C#GL_BUFFER_USAGE BUFFER_USAGE}{@link GL15C#GL_BUFFER_ACCESS BUFFER_ACCESS}{@link GL15C#GL_BUFFER_MAPPED BUFFER_MAPPED}
{@link GL30#GL_BUFFER_ACCESS_FLAGS BUFFER_ACCESS_FLAGS}{@link GL30#GL_BUFFER_MAP_LENGTH BUFFER_MAP_LENGTH}{@link GL30#GL_BUFFER_MAP_OFFSET BUFFER_MAP_OFFSET}{@link GL44#GL_BUFFER_IMMUTABLE_STORAGE BUFFER_IMMUTABLE_STORAGE}
{@link GL44#GL_BUFFER_STORAGE_FLAGS BUFFER_STORAGE_FLAGS}
+ * @param params the requested parameter + * + * @see Reference Page + */ + public static void glGetBufferParameteriv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL15C.glGetBufferParameteriv(target, pname, params); + } + + /** + * Returns the value of a buffer object parameter. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param pname the symbolic name of a buffer object parameter. One of:
{@link GL15#GL_BUFFER_SIZE BUFFER_SIZE}{@link GL15C#GL_BUFFER_USAGE BUFFER_USAGE}{@link GL15C#GL_BUFFER_ACCESS BUFFER_ACCESS}{@link GL15C#GL_BUFFER_MAPPED BUFFER_MAPPED}
{@link GL30#GL_BUFFER_ACCESS_FLAGS BUFFER_ACCESS_FLAGS}{@link GL30#GL_BUFFER_MAP_LENGTH BUFFER_MAP_LENGTH}{@link GL30#GL_BUFFER_MAP_OFFSET BUFFER_MAP_OFFSET}{@link GL44#GL_BUFFER_IMMUTABLE_STORAGE BUFFER_IMMUTABLE_STORAGE}
{@link GL44#GL_BUFFER_STORAGE_FLAGS BUFFER_STORAGE_FLAGS}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetBufferParameteri(@NativeType("GLenum") int target, @NativeType("GLenum") int pname) { + return GL15C.glGetBufferParameteri(target, pname); + } + + // --- [ glGetBufferPointerv ] --- + + /** Unsafe version of: {@link #glGetBufferPointerv GetBufferPointerv} */ + public static void nglGetBufferPointerv(int target, int pname, long params) { + GL15C.nglGetBufferPointerv(target, pname, params); + } + + /** + * Returns the pointer to a mapped buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param pname the pointer to be returned. Must be:
{@link GL15C#GL_BUFFER_MAP_POINTER BUFFER_MAP_POINTER}
+ * @param params the pointer value specified by {@code pname} + * + * @see Reference Page + */ + public static void glGetBufferPointerv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("void **") PointerBuffer params) { + GL15C.glGetBufferPointerv(target, pname, params); + } + + /** + * Returns the pointer to a mapped buffer object's data store. + * + * @param target the target buffer object. One of:
{@link GL15C#GL_ARRAY_BUFFER ARRAY_BUFFER}{@link GL15C#GL_ELEMENT_ARRAY_BUFFER ELEMENT_ARRAY_BUFFER}{@link GL21#GL_PIXEL_PACK_BUFFER PIXEL_PACK_BUFFER}{@link GL21#GL_PIXEL_UNPACK_BUFFER PIXEL_UNPACK_BUFFER}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER TRANSFORM_FEEDBACK_BUFFER}{@link GL31#GL_UNIFORM_BUFFER UNIFORM_BUFFER}{@link GL31#GL_TEXTURE_BUFFER TEXTURE_BUFFER}{@link GL31#GL_COPY_READ_BUFFER COPY_READ_BUFFER}
{@link GL31#GL_COPY_WRITE_BUFFER COPY_WRITE_BUFFER}{@link GL40#GL_DRAW_INDIRECT_BUFFER DRAW_INDIRECT_BUFFER}{@link GL42#GL_ATOMIC_COUNTER_BUFFER ATOMIC_COUNTER_BUFFER}{@link GL43#GL_DISPATCH_INDIRECT_BUFFER DISPATCH_INDIRECT_BUFFER}
{@link GL43#GL_SHADER_STORAGE_BUFFER SHADER_STORAGE_BUFFER}{@link ARBIndirectParameters#GL_PARAMETER_BUFFER_ARB PARAMETER_BUFFER_ARB}
+ * @param pname the pointer to be returned. Must be:
{@link GL15C#GL_BUFFER_MAP_POINTER BUFFER_MAP_POINTER}
+ * + * @see Reference Page + */ + @NativeType("void") + public static long glGetBufferPointer(@NativeType("GLenum") int target, @NativeType("GLenum") int pname) { + return GL15C.glGetBufferPointer(target, pname); + } + + // --- [ glGenQueries ] --- + + /** + * Unsafe version of: {@link #glGenQueries GenQueries} + * + * @param n the number of query object names to be generated + */ + public static void nglGenQueries(int n, long ids) { + GL15C.nglGenQueries(n, ids); + } + + /** + * Generates query object names. + * + * @param ids a buffer in which the generated query object names are stored + * + * @see Reference Page + */ + public static void glGenQueries(@NativeType("GLuint *") IntBuffer ids) { + GL15C.glGenQueries(ids); + } + + /** + * Generates query object names. + * + * @see Reference Page + */ + @NativeType("void") + public static int glGenQueries() { + return GL15C.glGenQueries(); + } + + // --- [ glDeleteQueries ] --- + + /** + * Unsafe version of: {@link #glDeleteQueries DeleteQueries} + * + * @param n the number of query objects to be deleted + */ + public static void nglDeleteQueries(int n, long ids) { + GL15C.nglDeleteQueries(n, ids); + } + + /** + * Deletes named query objects. + * + * @param ids an array of query objects to be deleted + * + * @see Reference Page + */ + public static void glDeleteQueries(@NativeType("GLuint const *") IntBuffer ids) { + GL15C.glDeleteQueries(ids); + } + + /** + * Deletes named query objects. + * + * @see Reference Page + */ + public static void glDeleteQueries(@NativeType("GLuint const *") int id) { + GL15C.glDeleteQueries(id); + } + + // --- [ glIsQuery ] --- + + /** + * Determine if a name corresponds to a query object. + * + * @param id a value that may be the name of a query object + * + * @see Reference Page + */ + @NativeType("GLboolean") + public static boolean glIsQuery(@NativeType("GLuint") int id) { + return GL15C.glIsQuery(id); + } + + // --- [ glBeginQuery ] --- + + /** + * Creates a query object and makes it active. + * + * @param target the target type of query object established. One of:
{@link GL15C#GL_SAMPLES_PASSED SAMPLES_PASSED}{@link GL30#GL_PRIMITIVES_GENERATED PRIMITIVES_GENERATED}{@link GL30#GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN}{@link GL33#GL_TIME_ELAPSED TIME_ELAPSED}
{@link GL33#GL_TIMESTAMP TIMESTAMP}{@link GL33#GL_ANY_SAMPLES_PASSED ANY_SAMPLES_PASSED}{@link GL43#GL_ANY_SAMPLES_PASSED_CONSERVATIVE ANY_SAMPLES_PASSED_CONSERVATIVE}
+ * @param id the name of a query object + * + * @see Reference Page + */ + public static void glBeginQuery(@NativeType("GLenum") int target, @NativeType("GLuint") int id) { + GL15C.glBeginQuery(target, id); + } + + // --- [ glEndQuery ] --- + + /** + * Marks the end of the sequence of commands to be tracked for the active query specified by {@code target}. + * + * @param target the query object target. One of:
{@link GL15C#GL_SAMPLES_PASSED SAMPLES_PASSED}{@link GL30#GL_PRIMITIVES_GENERATED PRIMITIVES_GENERATED}{@link GL30#GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN}{@link GL33#GL_TIME_ELAPSED TIME_ELAPSED}
{@link GL33#GL_TIMESTAMP TIMESTAMP}{@link GL33#GL_ANY_SAMPLES_PASSED ANY_SAMPLES_PASSED}{@link GL43#GL_ANY_SAMPLES_PASSED_CONSERVATIVE ANY_SAMPLES_PASSED_CONSERVATIVE}
+ * + * @see Reference Page + */ + public static void glEndQuery(@NativeType("GLenum") int target) { + GL15C.glEndQuery(target); + } + + // --- [ glGetQueryiv ] --- + + /** Unsafe version of: {@link #glGetQueryiv GetQueryiv} */ + public static void nglGetQueryiv(int target, int pname, long params) { + GL15C.nglGetQueryiv(target, pname, params); + } + + /** + * Returns parameters of a query object target. + * + * @param target the query object target. One of:
{@link GL15C#GL_SAMPLES_PASSED SAMPLES_PASSED}{@link GL30#GL_PRIMITIVES_GENERATED PRIMITIVES_GENERATED}{@link GL30#GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN}{@link GL33#GL_TIME_ELAPSED TIME_ELAPSED}
{@link GL33#GL_TIMESTAMP TIMESTAMP}{@link GL33#GL_ANY_SAMPLES_PASSED ANY_SAMPLES_PASSED}{@link GL43#GL_ANY_SAMPLES_PASSED_CONSERVATIVE ANY_SAMPLES_PASSED_CONSERVATIVE}
+ * @param pname the symbolic name of a query object target parameter. One of:
{@link GL15C#GL_QUERY_COUNTER_BITS QUERY_COUNTER_BITS}{@link GL15C#GL_CURRENT_QUERY CURRENT_QUERY}
+ * @param params the requested data + * + * @see Reference Page + */ + public static void glGetQueryiv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL15C.glGetQueryiv(target, pname, params); + } + + /** + * Returns parameters of a query object target. + * + * @param target the query object target. One of:
{@link GL15C#GL_SAMPLES_PASSED SAMPLES_PASSED}{@link GL30#GL_PRIMITIVES_GENERATED PRIMITIVES_GENERATED}{@link GL30#GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN}{@link GL33#GL_TIME_ELAPSED TIME_ELAPSED}
{@link GL33#GL_TIMESTAMP TIMESTAMP}{@link GL33#GL_ANY_SAMPLES_PASSED ANY_SAMPLES_PASSED}{@link GL43#GL_ANY_SAMPLES_PASSED_CONSERVATIVE ANY_SAMPLES_PASSED_CONSERVATIVE}
+ * @param pname the symbolic name of a query object target parameter. One of:
{@link GL15C#GL_QUERY_COUNTER_BITS QUERY_COUNTER_BITS}{@link GL15C#GL_CURRENT_QUERY CURRENT_QUERY}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetQueryi(@NativeType("GLenum") int target, @NativeType("GLenum") int pname) { + return GL15C.glGetQueryi(target, pname); + } + + // --- [ glGetQueryObjectiv ] --- + + /** Unsafe version of: {@link #glGetQueryObjectiv GetQueryObjectiv} */ + public static void nglGetQueryObjectiv(int id, int pname, long params) { + GL15C.nglGetQueryObjectiv(id, pname, params); + } + + /** + * Returns the integer value of a query object parameter. + * + * @param id the name of a query object + * @param pname the symbolic name of a query object parameter. One of:
{@link GL15C#GL_QUERY_RESULT QUERY_RESULT}{@link GL15C#GL_QUERY_RESULT_AVAILABLE QUERY_RESULT_AVAILABLE}
+ * @param params the requested data + * + * @see Reference Page + */ + public static void glGetQueryObjectiv(@NativeType("GLuint") int id, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL15C.glGetQueryObjectiv(id, pname, params); + } + + /** + * Returns the integer value of a query object parameter. + * + * @param id the name of a query object + * @param pname the symbolic name of a query object parameter. One of:
{@link GL15C#GL_QUERY_RESULT QUERY_RESULT}{@link GL15C#GL_QUERY_RESULT_AVAILABLE QUERY_RESULT_AVAILABLE}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetQueryObjecti(@NativeType("GLuint") int id, @NativeType("GLenum") int pname) { + return GL15C.glGetQueryObjecti(id, pname); + } + + // --- [ glGetQueryObjectuiv ] --- + + /** Unsafe version of: {@link #glGetQueryObjectuiv GetQueryObjectuiv} */ + public static void nglGetQueryObjectuiv(int id, int pname, long params) { + GL15C.nglGetQueryObjectuiv(id, pname, params); + } + + /** + * Unsigned version of {@link #glGetQueryObjectiv GetQueryObjectiv}. + * + * @param id the name of a query object + * @param pname the symbolic name of a query object parameter. One of:
{@link GL15C#GL_QUERY_RESULT QUERY_RESULT}{@link GL15C#GL_QUERY_RESULT_AVAILABLE QUERY_RESULT_AVAILABLE}
+ * @param params the requested data + * + * @see Reference Page + */ + public static void glGetQueryObjectuiv(@NativeType("GLuint") int id, @NativeType("GLenum") int pname, @NativeType("GLuint *") IntBuffer params) { + GL15C.glGetQueryObjectuiv(id, pname, params); + } + + /** + * Unsigned version of {@link #glGetQueryObjectiv GetQueryObjectiv}. + * + * @param id the name of a query object + * @param pname the symbolic name of a query object parameter. One of:
{@link GL15C#GL_QUERY_RESULT QUERY_RESULT}{@link GL15C#GL_QUERY_RESULT_AVAILABLE QUERY_RESULT_AVAILABLE}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetQueryObjectui(@NativeType("GLuint") int id, @NativeType("GLenum") int pname) { + return GL15C.glGetQueryObjectui(id, pname); + } + + /** + * Array version of: {@link #glDeleteBuffers DeleteBuffers} + * + * @see Reference Page + */ + public static void glDeleteBuffers(@NativeType("GLuint const *") int[] buffers) { + GL15C.glDeleteBuffers(buffers); + } + + /** + * Array version of: {@link #glGenBuffers GenBuffers} + * + * @see Reference Page + */ + public static void glGenBuffers(@NativeType("GLuint *") int[] buffers) { + GL15C.glGenBuffers(buffers); + } + + /** + * Array version of: {@link #glBufferData BufferData} + * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") short[] data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Array version of: {@link #glBufferData BufferData} + * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") int[] data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Array version of: {@link #glBufferData BufferData} + * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") long[] data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Array version of: {@link #glBufferData BufferData} + * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") float[] data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Array version of: {@link #glBufferData BufferData} + * + * @see Reference Page + */ + public static void glBufferData(@NativeType("GLenum") int target, @NativeType("void const *") double[] data, @NativeType("GLenum") int usage) { + GL15C.glBufferData(target, data, usage); + } + + /** + * Array version of: {@link #glBufferSubData BufferSubData} + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") short[] data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glBufferSubData BufferSubData} + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") int[] data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glBufferSubData BufferSubData} + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") long[] data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glBufferSubData BufferSubData} + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") float[] data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glBufferSubData BufferSubData} + * + * @see Reference Page + */ + public static void glBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void const *") double[] data) { + GL15C.glBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glGetBufferSubData GetBufferSubData} + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") short[] data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glGetBufferSubData GetBufferSubData} + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") int[] data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glGetBufferSubData GetBufferSubData} + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") long[] data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glGetBufferSubData GetBufferSubData} + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") float[] data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glGetBufferSubData GetBufferSubData} + * + * @see Reference Page + */ + public static void glGetBufferSubData(@NativeType("GLenum") int target, @NativeType("GLintptr") long offset, @NativeType("void *") double[] data) { + GL15C.glGetBufferSubData(target, offset, data); + } + + /** + * Array version of: {@link #glGetBufferParameteriv GetBufferParameteriv} + * + * @see Reference Page + */ + public static void glGetBufferParameteriv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL15C.glGetBufferParameteriv(target, pname, params); + } + + /** + * Array version of: {@link #glGenQueries GenQueries} + * + * @see Reference Page + */ + public static void glGenQueries(@NativeType("GLuint *") int[] ids) { + GL15C.glGenQueries(ids); + } + + /** + * Array version of: {@link #glDeleteQueries DeleteQueries} + * + * @see Reference Page + */ + public static void glDeleteQueries(@NativeType("GLuint const *") int[] ids) { + GL15C.glDeleteQueries(ids); + } + + /** + * Array version of: {@link #glGetQueryiv GetQueryiv} + * + * @see Reference Page + */ + public static void glGetQueryiv(@NativeType("GLenum") int target, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL15C.glGetQueryiv(target, pname, params); + } + + /** + * Array version of: {@link #glGetQueryObjectiv GetQueryObjectiv} + * + * @see Reference Page + */ + public static void glGetQueryObjectiv(@NativeType("GLuint") int id, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL15C.glGetQueryObjectiv(id, pname, params); + } + + /** + * Array version of: {@link #glGetQueryObjectuiv GetQueryObjectuiv} + * + * @see Reference Page + */ + public static void glGetQueryObjectuiv(@NativeType("GLuint") int id, @NativeType("GLenum") int pname, @NativeType("GLuint *") int[] params) { + GL15C.glGetQueryObjectuiv(id, pname, params); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL20.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL20.java new file mode 100644 index 000000000..92151666e --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GL20.java @@ -0,0 +1,2925 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.opengl; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.Checks.*; + +/** + * The OpenGL functionality up to version 2.0. Includes the deprecated symbols of the Compatibility Profile. + * + *

Extensions promoted to core in this release:

+ * + * + */ +public class GL20 extends GL15 { + + /** Accepted by the {@code name} parameter of GetString. */ + public static final int GL_SHADING_LANGUAGE_VERSION = 0x8B8C; + + /** Accepted by the {@code pname} parameter of GetInteger. */ + public static final int GL_CURRENT_PROGRAM = 0x8B8D; + + /** Accepted by the {@code pname} parameter of GetShaderiv. */ + public static final int + GL_SHADER_TYPE = 0x8B4F, + GL_DELETE_STATUS = 0x8B80, + GL_COMPILE_STATUS = 0x8B81, + GL_LINK_STATUS = 0x8B82, + GL_VALIDATE_STATUS = 0x8B83, + GL_INFO_LOG_LENGTH = 0x8B84, + GL_ATTACHED_SHADERS = 0x8B85, + GL_ACTIVE_UNIFORMS = 0x8B86, + GL_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, + GL_ACTIVE_ATTRIBUTES = 0x8B89, + GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, + GL_SHADER_SOURCE_LENGTH = 0x8B88; + + /** Returned by the {@code type} parameter of GetActiveUniform. */ + public static final int + GL_FLOAT_VEC2 = 0x8B50, + GL_FLOAT_VEC3 = 0x8B51, + GL_FLOAT_VEC4 = 0x8B52, + GL_INT_VEC2 = 0x8B53, + GL_INT_VEC3 = 0x8B54, + GL_INT_VEC4 = 0x8B55, + GL_BOOL = 0x8B56, + GL_BOOL_VEC2 = 0x8B57, + GL_BOOL_VEC3 = 0x8B58, + GL_BOOL_VEC4 = 0x8B59, + GL_FLOAT_MAT2 = 0x8B5A, + GL_FLOAT_MAT3 = 0x8B5B, + GL_FLOAT_MAT4 = 0x8B5C, + GL_SAMPLER_1D = 0x8B5D, + GL_SAMPLER_2D = 0x8B5E, + GL_SAMPLER_3D = 0x8B5F, + GL_SAMPLER_CUBE = 0x8B60, + GL_SAMPLER_1D_SHADOW = 0x8B61, + GL_SAMPLER_2D_SHADOW = 0x8B62; + + /** Accepted by the {@code type} argument of CreateShader and returned by the {@code params} parameter of GetShaderiv. */ + public static final int GL_VERTEX_SHADER = 0x8B31; + + /** Accepted by the {@code pname} parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev. */ + public static final int + GL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A, + GL_MAX_VARYING_FLOATS = 0x8B4B, + GL_MAX_VERTEX_ATTRIBS = 0x8869, + GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872, + GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C, + GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D, + GL_MAX_TEXTURE_COORDS = 0x8871; + + /** + * Accepted by the {@code cap} parameter of Disable, Enable, and IsEnabled, and by the {@code pname} parameter of GetBooleanv, GetIntegerv, GetFloatv, and + * GetDoublev. + */ + public static final int + GL_VERTEX_PROGRAM_POINT_SIZE = 0x8642, + GL_VERTEX_PROGRAM_TWO_SIDE = 0x8643; + + /** Accepted by the {@code pname} parameter of GetVertexAttrib{dfi}v. */ + public static final int + GL_VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622, + GL_VERTEX_ATTRIB_ARRAY_SIZE = 0x8623, + GL_VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624, + GL_VERTEX_ATTRIB_ARRAY_TYPE = 0x8625, + GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A, + GL_CURRENT_VERTEX_ATTRIB = 0x8626; + + /** Accepted by the {@code pname} parameter of GetVertexAttribPointerv. */ + public static final int GL_VERTEX_ATTRIB_ARRAY_POINTER = 0x8645; + + /** Accepted by the {@code type} argument of CreateShader and returned by the {@code params} parameter of GetShaderiv. */ + public static final int GL_FRAGMENT_SHADER = 0x8B30; + + /** Accepted by the {@code pname} parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev. */ + public static final int GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49; + + /** Accepted by the {@code target} parameter of Hint and the {@code pname} parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev. */ + public static final int GL_FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B; + + /** Accepted by the {@code pname} parameters of GetIntegerv, GetFloatv, and GetDoublev. */ + public static final int + GL_MAX_DRAW_BUFFERS = 0x8824, + GL_DRAW_BUFFER0 = 0x8825, + GL_DRAW_BUFFER1 = 0x8826, + GL_DRAW_BUFFER2 = 0x8827, + GL_DRAW_BUFFER3 = 0x8828, + GL_DRAW_BUFFER4 = 0x8829, + GL_DRAW_BUFFER5 = 0x882A, + GL_DRAW_BUFFER6 = 0x882B, + GL_DRAW_BUFFER7 = 0x882C, + GL_DRAW_BUFFER8 = 0x882D, + GL_DRAW_BUFFER9 = 0x882E, + GL_DRAW_BUFFER10 = 0x882F, + GL_DRAW_BUFFER11 = 0x8830, + GL_DRAW_BUFFER12 = 0x8831, + GL_DRAW_BUFFER13 = 0x8832, + GL_DRAW_BUFFER14 = 0x8833, + GL_DRAW_BUFFER15 = 0x8834; + + /** + * Accepted by the {@code cap} parameter of Enable, Disable, and IsEnabled, by the {@code pname} parameter of GetBooleanv, GetIntegerv, GetFloatv, and + * GetDoublev, and by the {@code target} parameter of TexEnvi, TexEnviv, TexEnvf, TexEnvfv, GetTexEnviv, and GetTexEnvfv. + */ + public static final int GL_POINT_SPRITE = 0x8861; + + /** + * When the {@code target} parameter of TexEnvf, TexEnvfv, TexEnvi, TexEnviv, GetTexEnvfv, or GetTexEnviv is POINT_SPRITE, then the value of + * {@code pname} may be. + */ + public static final int GL_COORD_REPLACE = 0x8862; + + /** Accepted by the {@code pname} parameter of PointParameter{if}v. */ + public static final int GL_POINT_SPRITE_COORD_ORIGIN = 0x8CA0; + + /** Accepted by the {@code param} parameter of PointParameter{if}v. */ + public static final int + GL_LOWER_LEFT = 0x8CA1, + GL_UPPER_LEFT = 0x8CA2; + + /** Accepted by the {@code pname} parameter of GetBooleanv, GetIntegerv, GetFloatv, and GetDoublev. */ + public static final int + GL_BLEND_EQUATION_RGB = 0x8009, + GL_BLEND_EQUATION_ALPHA = 0x883D; + + /** Accepted by the {@code pname} parameter of GetIntegerv. */ + public static final int + GL_STENCIL_BACK_FUNC = 0x8800, + GL_STENCIL_BACK_FAIL = 0x8801, + GL_STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802, + GL_STENCIL_BACK_PASS_DEPTH_PASS = 0x8803, + GL_STENCIL_BACK_REF = 0x8CA3, + GL_STENCIL_BACK_VALUE_MASK = 0x8CA4, + GL_STENCIL_BACK_WRITEMASK = 0x8CA5; + + static { GL.initialize(); } + + protected GL20() { + throw new UnsupportedOperationException(); + } + + static boolean isAvailable(GLCapabilities caps) { + return checkFunctions( + caps.glCreateProgram, caps.glDeleteProgram, caps.glIsProgram, caps.glCreateShader, caps.glDeleteShader, caps.glIsShader, caps.glAttachShader, + caps.glDetachShader, caps.glShaderSource, caps.glCompileShader, caps.glLinkProgram, caps.glUseProgram, caps.glValidateProgram, caps.glUniform1f, + caps.glUniform2f, caps.glUniform3f, caps.glUniform4f, caps.glUniform1i, caps.glUniform2i, caps.glUniform3i, caps.glUniform4i, caps.glUniform1fv, + caps.glUniform2fv, caps.glUniform3fv, caps.glUniform4fv, caps.glUniform1iv, caps.glUniform2iv, caps.glUniform3iv, caps.glUniform4iv, + caps.glUniformMatrix2fv, caps.glUniformMatrix3fv, caps.glUniformMatrix4fv, caps.glGetShaderiv, caps.glGetProgramiv, caps.glGetShaderInfoLog, + caps.glGetProgramInfoLog, caps.glGetAttachedShaders, caps.glGetUniformLocation, caps.glGetActiveUniform, caps.glGetUniformfv, caps.glGetUniformiv, + caps.glGetShaderSource, caps.glVertexAttrib1f, caps.glVertexAttrib1s, caps.glVertexAttrib1d, caps.glVertexAttrib2f, caps.glVertexAttrib2s, + caps.glVertexAttrib2d, caps.glVertexAttrib3f, caps.glVertexAttrib3s, caps.glVertexAttrib3d, caps.glVertexAttrib4f, caps.glVertexAttrib4s, + caps.glVertexAttrib4d, caps.glVertexAttrib4Nub, caps.glVertexAttrib1fv, caps.glVertexAttrib1sv, caps.glVertexAttrib1dv, caps.glVertexAttrib2fv, + caps.glVertexAttrib2sv, caps.glVertexAttrib2dv, caps.glVertexAttrib3fv, caps.glVertexAttrib3sv, caps.glVertexAttrib3dv, caps.glVertexAttrib4fv, + caps.glVertexAttrib4sv, caps.glVertexAttrib4dv, caps.glVertexAttrib4iv, caps.glVertexAttrib4bv, caps.glVertexAttrib4ubv, caps.glVertexAttrib4usv, + caps.glVertexAttrib4uiv, caps.glVertexAttrib4Nbv, caps.glVertexAttrib4Nsv, caps.glVertexAttrib4Niv, caps.glVertexAttrib4Nubv, + caps.glVertexAttrib4Nusv, caps.glVertexAttrib4Nuiv, caps.glVertexAttribPointer, caps.glEnableVertexAttribArray, caps.glDisableVertexAttribArray, + caps.glBindAttribLocation, caps.glGetActiveAttrib, caps.glGetAttribLocation, caps.glGetVertexAttribiv, caps.glGetVertexAttribfv, + caps.glGetVertexAttribdv, caps.glGetVertexAttribPointerv, caps.glDrawBuffers, caps.glBlendEquationSeparate, caps.glStencilOpSeparate, + caps.glStencilFuncSeparate, caps.glStencilMaskSeparate + ); + } + +// -- Begin LWJGL2 part -- + public static void glVertexAttribPointer(int index, int size, + boolean unsigned, boolean normalized, + int stride, ByteBuffer buffer) { + int type = unsigned ? GL11.GL_UNSIGNED_BYTE : GL11.GL_BYTE; + GL20.glVertexAttribPointer(index, size, type, normalized, stride, buffer); + } + + public static void glVertexAttribPointer(int index, int size, + boolean unsigned, boolean normalized, + int stride, ShortBuffer buffer) { + GL20.nglVertexAttribPointer(index, size, unsigned ? GL11.GL_UNSIGNED_SHORT : GL11.GL_SHORT, normalized, stride, MemoryUtil.memAddress(buffer)); + } + + public static void glVertexAttribPointer(int index, int size, + boolean unsigned, boolean normalized, + int stride, IntBuffer buffer) { + GL20.nglVertexAttribPointer(index, size, unsigned ? GL11.GL_UNSIGNED_INT : GL11.GL_INT, normalized, stride, MemoryUtil.memAddress(buffer)); + } + + public static String glGetActiveAttrib(int program, int index, int maxLength, + IntBuffer sizeType) { + //TODO check if correct + IntBuffer type = BufferUtils.createIntBuffer(1); + String s = GL20.glGetActiveAttrib(program, index, maxLength, sizeType, type); + sizeType.put(type.get(0)); + return s; + } + + public static String glGetActiveUniform(int program, int index, int maxLength, + IntBuffer sizeType) { + //TODO if correct + IntBuffer type = BufferUtils.createIntBuffer(1); + String s = GL20.glGetActiveUniform(program, index, maxLength, sizeType, type); + sizeType.put(type.get(0)); + return s; + } + + public static void glShaderSource(int shader, ByteBuffer string) { + byte[] b = new byte[string.remaining()]; + string.get(b); + glShaderSource(shader, new String(b)); + } + + // TODO port below +/* + public static String glGetActiveAttrib(int i, int i2, int i3) { + int i4 = i; + int i5 = i2; + int i6 = i3; + ContextCapabilities capabilities = GLContext.getCapabilities(); + long j = capabilities.glGetActiveAttrib; + BufferChecks.checkFunctionAddress(j); + Buffer lengths = APIUtil.getLengths(capabilities); + ByteBuffer bufferByte = APIUtil.getBufferByte(capabilities, i6); + nglGetActiveAttrib(i4, i5, i6, MemoryUtil.memAddress(lengths), MemoryUtil.memAddress(APIUtil.getBufferInt(capabilities)), MemoryUtil.getAddress(APIUtil.getBufferInt(capabilities), 1), MemoryUtil.getAddress(bufferByte), j); + Buffer limit = bufferByte.limit(lengths.get(0)); + return APIUtil.getString(capabilities, bufferByte); + } + + public static int glGetActiveAttribSize(int i, int i2) { + int i3 = i; + int i4 = i2; + ContextCapabilities capabilities = GLContext.getCapabilities(); + long j = capabilities.glGetActiveAttrib; + BufferChecks.checkFunctionAddress(j); + IntBuffer bufferInt = APIUtil.getBufferInt(capabilities); + nglGetActiveAttrib(i3, i4, 0, 0, MemoryUtil.getAddress(bufferInt), MemoryUtil.getAddress(bufferInt, 1), APIUtil.getBufferByte0(capabilities), j); + return bufferInt.get(0); + } + + public static int glGetActiveAttribType(int i, int i2) { + int i3 = i; + int i4 = i2; + ContextCapabilities capabilities = GLContext.getCapabilities(); + long j = capabilities.glGetActiveAttrib; + BufferChecks.checkFunctionAddress(j); + IntBuffer bufferInt = APIUtil.getBufferInt(capabilities); + nglGetActiveAttrib(i3, i4, 0, 0, MemoryUtil.getAddress(bufferInt, 1), MemoryUtil.getAddress(bufferInt), APIUtil.getBufferByte0(capabilities), j); + return bufferInt.get(0); + } + + public static String glGetActiveUniform(int i, int i2, int i3) { + int i4 = i; + int i5 = i2; + int i6 = i3; + ContextCapabilities capabilities = GLContext.getCapabilities(); + long j = capabilities.glGetActiveUniform; + BufferChecks.checkFunctionAddress(j); + Buffer lengths = APIUtil.getLengths(capabilities); + ByteBuffer bufferByte = APIUtil.getBufferByte(capabilities, i6); + nglGetActiveUniform(i4, i5, i6, MemoryUtil.memAddress(lengths), MemoryUtil.memAddress(APIUtil.getBufferInt(capabilities)), MemoryUtil.getAddress(APIUtil.getBufferInt(capabilities), 1), MemoryUtil.getAddress(bufferByte), j); + Buffer limit = bufferByte.limit(lengths.get(0)); + return APIUtil.getString(capabilities, bufferByte); + } + + public static int glGetActiveUniformSize(int i, int i2) { + int i3 = i; + int i4 = i2; + ContextCapabilities capabilities = GLContext.getCapabilities(); + long j = capabilities.glGetActiveUniform; + BufferChecks.checkFunctionAddress(j); + IntBuffer bufferInt = APIUtil.getBufferInt(capabilities); + nglGetActiveUniform(i3, i4, 1, 0, MemoryUtil.getAddress(bufferInt), MemoryUtil.getAddress(bufferInt, 1), APIUtil.getBufferByte0(capabilities), j); + return bufferInt.get(0); + } + + public static int glGetActiveUniformType(int i, int i2) { + int i3 = i; + int i4 = i2; + ContextCapabilities capabilities = GLContext.getCapabilities(); + long j = capabilities.glGetActiveUniform; + BufferChecks.checkFunctionAddress(j); + IntBuffer bufferInt = APIUtil.getBufferInt(capabilities); + nglGetActiveUniform(i3, i4, 0, 0, MemoryUtil.getAddress(bufferInt, 1), MemoryUtil.getAddress(bufferInt), APIUtil.getBufferByte0(capabilities), j); + return bufferInt.get(0); + } +*/ + + @Deprecated + public static int glGetProgram(int i, int i2) { + return glGetProgrami(i, i2); + } + + public static void glGetProgram(int program, int pname, IntBuffer params) { + glGetProgramiv(program, pname, params); + } + + @Deprecated + public static int glGetShader(int i, int i2) { + return glGetShaderi(i, i2); + } + + public static void glGetShader(int shader, int pname, IntBuffer params) { + glGetShaderiv(shader, pname, params); + } + + public static void glGetUniform(int program, int location, FloatBuffer params) { + glGetUniformfv(program, location, params); + } + + public static void glGetUniform(int program, int location, IntBuffer params) { + glGetUniformiv(program, location, params); + } + + public static void glGetVertexAttrib(int index, int pname, DoubleBuffer params) { + glGetVertexAttribdv(index, pname, params); + } + + public static void glGetVertexAttrib(int index, int pname, FloatBuffer params) { + glGetVertexAttribfv(index, pname, params); + } + + public static void glGetVertexAttrib(int index, int pname, IntBuffer params) { + glGetVertexAttribiv(index, pname, params); + } + + // FIXME +/* + public static ByteBuffer glGetVertexAttribPointer(int i, int i2, long j) { + glGetVertexa + } + + public static void glGetVertexAttribPointer(int index, int pname, ByteBuffer buffer) { + glGetVertexAttribPointer(index, pname); + } +*/ + public static void glUniform1(int location, FloatBuffer buffer) { + glUniform1fv(location, buffer); + } + + public static void glUniform1(int location, IntBuffer buffer) { + glUniform1iv(location, buffer); + } + + public static void glUniform2(int location, FloatBuffer buffer) { + glUniform2fv(location, buffer); + } + + public static void glUniform2(int location, IntBuffer buffer) { + glUniform2iv(location, buffer); + } + + public static void glUniform3(int location, FloatBuffer buffer) { + glUniform3fv(location, buffer); + } + + public static void glUniform3(int location, IntBuffer buffer) { + glUniform3iv(location, buffer); + } + + public static void glUniform4(int location, FloatBuffer buffer) { + glUniform4fv(location, buffer); + } + + public static void glUniform4(int location, IntBuffer buffer) { + glUniform4iv(location, buffer); + } + + public static void glUniformMatrix2(int location, boolean transpose, FloatBuffer buffer) { + glUniformMatrix2fv(location, transpose, buffer); + } + + public static void glUniformMatrix3(int location, boolean transpose, FloatBuffer buffer) { + glUniformMatrix3fv(location, transpose, buffer); + } + + public static void glUniformMatrix4(int location, boolean transpose, FloatBuffer buffer) { + glUniformMatrix4fv(location, transpose, buffer); + } + + // FIXME +/* + public static void glVertexAttribPointer(int index, int size, boolean normalized, int stride, DoubleBuffer buffer) { + glVertexAttribPointer(index, size, GL11.GL_DOUBLE, normalized, stride, buffer); + } +*/ + public static void glVertexAttribPointer(int index, int size, boolean normalized, int stride, FloatBuffer buffer) { + glVertexAttribPointer(index, size, GL11.GL_FLOAT, normalized, stride, buffer); + } +// -- End LWJGL2 part -- + + // --- [ glCreateProgram ] --- + + /** + * Creates a program object. + * + * @see Reference Page + */ + @NativeType("GLuint") + public static int glCreateProgram() { + return GL20C.glCreateProgram(); + } + + // --- [ glDeleteProgram ] --- + + /** + * Deletes a program object. + * + * @param program the program object to be deleted + * + * @see Reference Page + */ + public static void glDeleteProgram(@NativeType("GLuint") int program) { + GL20C.glDeleteProgram(program); + } + + // --- [ glIsProgram ] --- + + /** + * Returns {@link GL11#GL_TRUE TRUE} if {@code program} is the name of a program object. If {@code program} is zero, or a non-zero value that is not the name of a program + * object, IsProgram returns {@link GL11#GL_FALSE FALSE}. No error is generated if program is not a valid program object name. + * + * @param program the program object name to query + * + * @see Reference Page + */ + @NativeType("GLboolean") + public static boolean glIsProgram(@NativeType("GLuint") int program) { + return GL20C.glIsProgram(program); + } + + // --- [ glCreateShader ] --- + + /** + * Creates a shader object. + * + * @param type the type of shader to be created. One of:
{@link GL20C#GL_VERTEX_SHADER VERTEX_SHADER}{@link GL20C#GL_FRAGMENT_SHADER FRAGMENT_SHADER}{@link GL32#GL_GEOMETRY_SHADER GEOMETRY_SHADER}{@link GL40#GL_TESS_CONTROL_SHADER TESS_CONTROL_SHADER}
{@link GL40#GL_TESS_EVALUATION_SHADER TESS_EVALUATION_SHADER}
+ * + * @see Reference Page + */ + @NativeType("GLuint") + public static int glCreateShader(@NativeType("GLenum") int type) { + return GL20C.glCreateShader(type); + } + + // --- [ glDeleteShader ] --- + + /** + * Deletes a shader object. + * + * @param shader the shader object to be deleted + * + * @see Reference Page + */ + public static void glDeleteShader(@NativeType("GLuint") int shader) { + GL20C.glDeleteShader(shader); + } + + // --- [ glIsShader ] --- + + /** + * Returns {@link GL11#GL_TRUE TRUE} if {@code shader} is the name of a shader object. If {@code shader} is zero, or a nonzero value that is not the name of a shader + * object, IsShader returns {@link GL11#GL_FALSE FALSE}. No error is generated if shader is not a valid shader object name. + * + * @param shader the shader object name to query + * + * @see Reference Page + */ + @NativeType("GLboolean") + public static boolean glIsShader(@NativeType("GLuint") int shader) { + return GL20C.glIsShader(shader); + } + + // --- [ glAttachShader ] --- + + /** + * Attaches a shader object to a program object. + * + *

In order to create a complete shader program, there must be a way to specify the list of things that will be linked together. Program objects provide + * this mechanism. Shaders that are to be linked together in a program object must first be attached to that program object. glAttachShader attaches the + * shader object specified by shader to the program object specified by program. This indicates that shader will be included in link operations that will + * be performed on program.

+ * + *

All operations that can be performed on a shader object are valid whether or not the shader object is attached to a program object. It is permissible to + * attach a shader object to a program object before source code has been loaded into the shader object or before the shader object has been compiled. It + * is permissible to attach multiple shader objects of the same type because each may contain a portion of the complete shader. It is also permissible to + * attach a shader object to more than one program object. If a shader object is deleted while it is attached to a program object, it will be flagged for + * deletion, and deletion will not occur until glDetachShader is called to detach it from all program objects to which it is attached.

+ * + * @param program the program object to which a shader object will be attached + * @param shader the shader object that is to be attached + * + * @see Reference Page + */ + public static void glAttachShader(@NativeType("GLuint") int program, @NativeType("GLuint") int shader) { + GL20C.glAttachShader(program, shader); + } + + // --- [ glDetachShader ] --- + + /** + * Detaches a shader object from a program object to which it is attached. + * + * @param program the program object from which to detach the shader object + * @param shader the shader object to be detached + * + * @see Reference Page + */ + public static void glDetachShader(@NativeType("GLuint") int program, @NativeType("GLuint") int shader) { + GL20C.glDetachShader(program, shader); + } + + // --- [ glShaderSource ] --- + + /** + * Unsafe version of: {@link #glShaderSource ShaderSource} + * + * @param count the number of elements in the string and length arrays + */ + public static void nglShaderSource(int shader, int count, long strings, long length) { + GL20C.nglShaderSource(shader, count, strings, length); + } + + /** + * Sets the source code in {@code shader} to the source code in the array of strings specified by {@code strings}. Any source code previously stored in the + * shader object is completely replaced. The number of strings in the array is specified by {@code count}. If {@code length} is {@code NULL}, each string is + * assumed to be null terminated. If {@code length} is a value other than {@code NULL}, it points to an array containing a string length for each of the + * corresponding elements of {@code strings}. Each element in the length array may contain the length of the corresponding string (the null character is not + * counted as part of the string length) or a value less than 0 to indicate that the string is null terminated. The source code strings are not scanned or + * parsed at this time; they are simply copied into the specified shader object. + * + * @param shader the shader object whose source code is to be replaced + * @param strings an array of pointers to strings containing the source code to be loaded into the shader + * @param length an array of string lengths + * + * @see Reference Page + */ + public static void glShaderSource(@NativeType("GLuint") int shader, @NativeType("GLchar const **") PointerBuffer strings, @Nullable @NativeType("GLint const *") IntBuffer length) { + GL20C.glShaderSource(shader, strings, length); + } + + /** + * Sets the source code in {@code shader} to the source code in the array of strings specified by {@code strings}. Any source code previously stored in the + * shader object is completely replaced. The number of strings in the array is specified by {@code count}. If {@code length} is {@code NULL}, each string is + * assumed to be null terminated. If {@code length} is a value other than {@code NULL}, it points to an array containing a string length for each of the + * corresponding elements of {@code strings}. Each element in the length array may contain the length of the corresponding string (the null character is not + * counted as part of the string length) or a value less than 0 to indicate that the string is null terminated. The source code strings are not scanned or + * parsed at this time; they are simply copied into the specified shader object. + * + * @param shader the shader object whose source code is to be replaced + * @param strings an array of pointers to strings containing the source code to be loaded into the shader + * + * @see Reference Page + */ + public static void glShaderSource(@NativeType("GLuint") int shader, @NativeType("GLchar const **") CharSequence... strings) { + GL20C.glShaderSource(shader, strings); + } + + /** + * Sets the source code in {@code shader} to the source code in the array of strings specified by {@code strings}. Any source code previously stored in the + * shader object is completely replaced. The number of strings in the array is specified by {@code count}. If {@code length} is {@code NULL}, each string is + * assumed to be null terminated. If {@code length} is a value other than {@code NULL}, it points to an array containing a string length for each of the + * corresponding elements of {@code strings}. Each element in the length array may contain the length of the corresponding string (the null character is not + * counted as part of the string length) or a value less than 0 to indicate that the string is null terminated. The source code strings are not scanned or + * parsed at this time; they are simply copied into the specified shader object. + * + * @param shader the shader object whose source code is to be replaced + * + * @see Reference Page + */ + public static void glShaderSource(@NativeType("GLuint") int shader, @NativeType("GLchar const **") CharSequence string) { + GL20C.glShaderSource(shader, string); + } + + // --- [ glCompileShader ] --- + + /** + * Compiles a shader object. + * + * @param shader the shader object to be compiled + * + * @see Reference Page + */ + public static void glCompileShader(@NativeType("GLuint") int shader) { + GL20C.glCompileShader(shader); + } + + // --- [ glLinkProgram ] --- + + /** + * Links a program object. + * + * @param program the program object to be linked + * + * @see Reference Page + */ + public static void glLinkProgram(@NativeType("GLuint") int program) { + GL20C.glLinkProgram(program); + } + + // --- [ glUseProgram ] --- + + /** + * Installs a program object as part of current rendering state. + * + * @param program the program object whose executables are to be used as part of current rendering state + * + * @see Reference Page + */ + public static void glUseProgram(@NativeType("GLuint") int program) { + GL20C.glUseProgram(program); + } + + // --- [ glValidateProgram ] --- + + /** + * Validates a program object. + * + * @param program the program object to be validated + * + * @see Reference Page + */ + public static void glValidateProgram(@NativeType("GLuint") int program) { + GL20C.glValidateProgram(program); + } + + // --- [ glUniform1f ] --- + + /** + * Specifies the value of a float uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform value + * + * @see Reference Page + */ + public static void glUniform1f(@NativeType("GLint") int location, @NativeType("GLfloat") float v0) { + GL20C.glUniform1f(location, v0); + } + + // --- [ glUniform2f ] --- + + /** + * Specifies the value of a vec2 uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform x value + * @param v1 the uniform y value + * + * @see Reference Page + */ + public static void glUniform2f(@NativeType("GLint") int location, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1) { + GL20C.glUniform2f(location, v0, v1); + } + + // --- [ glUniform3f ] --- + + /** + * Specifies the value of a vec3 uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + * + * @see Reference Page + */ + public static void glUniform3f(@NativeType("GLint") int location, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2) { + GL20C.glUniform3f(location, v0, v1, v2); + } + + // --- [ glUniform4f ] --- + + /** + * Specifies the value of a vec4 uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + * @param v3 the uniform w value + * + * @see Reference Page + */ + public static void glUniform4f(@NativeType("GLint") int location, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2, @NativeType("GLfloat") float v3) { + GL20C.glUniform4f(location, v0, v1, v2, v3); + } + + // --- [ glUniform1i ] --- + + /** + * Specifies the value of an int uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform value + * + * @see Reference Page + */ + public static void glUniform1i(@NativeType("GLint") int location, @NativeType("GLint") int v0) { + GL20C.glUniform1i(location, v0); + } + + // --- [ glUniform2i ] --- + + /** + * Specifies the value of an ivec2 uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform x value + * @param v1 the uniform y value + * + * @see Reference Page + */ + public static void glUniform2i(@NativeType("GLint") int location, @NativeType("GLint") int v0, @NativeType("GLint") int v1) { + GL20C.glUniform2i(location, v0, v1); + } + + // --- [ glUniform3i ] --- + + /** + * Specifies the value of an ivec3 uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + * + * @see Reference Page + */ + public static void glUniform3i(@NativeType("GLint") int location, @NativeType("GLint") int v0, @NativeType("GLint") int v1, @NativeType("GLint") int v2) { + GL20C.glUniform3i(location, v0, v1, v2); + } + + // --- [ glUniform4i ] --- + + /** + * Specifies the value of an ivec4 uniform variable for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param v0 the uniform x value + * @param v1 the uniform y value + * @param v2 the uniform z value + * @param v3 the uniform w value + * + * @see Reference Page + */ + public static void glUniform4i(@NativeType("GLint") int location, @NativeType("GLint") int v0, @NativeType("GLint") int v1, @NativeType("GLint") int v2, @NativeType("GLint") int v3) { + GL20C.glUniform4i(location, v0, v1, v2, v3); + } + + // --- [ glUniform1fv ] --- + + /** + * Unsafe version of: {@link #glUniform1fv Uniform1fv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform1fv(int location, int count, long value) { + GL20C.nglUniform1fv(location, count, value); + } + + /** + * Specifies the value of a single float uniform variable or a float uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform1fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + GL20C.glUniform1fv(location, value); + } + + // --- [ glUniform2fv ] --- + + /** + * Unsafe version of: {@link #glUniform2fv Uniform2fv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform2fv(int location, int count, long value) { + GL20C.nglUniform2fv(location, count, value); + } + + /** + * Specifies the value of a single vec2 uniform variable or a vec2 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform2fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + GL20C.glUniform2fv(location, value); + } + + // --- [ glUniform3fv ] --- + + /** + * Unsafe version of: {@link #glUniform3fv Uniform3fv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform3fv(int location, int count, long value) { + GL20C.nglUniform3fv(location, count, value); + } + + /** + * Specifies the value of a single vec3 uniform variable or a vec3 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform3fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + GL20C.glUniform3fv(location, value); + } + + // --- [ glUniform4fv ] --- + + /** + * Unsafe version of: {@link #glUniform4fv Uniform4fv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform4fv(int location, int count, long value) { + GL20C.nglUniform4fv(location, count, value); + } + + /** + * Specifies the value of a single vec4 uniform variable or a vec4 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform4fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") FloatBuffer value) { + GL20C.glUniform4fv(location, value); + } + + // --- [ glUniform1iv ] --- + + /** + * Unsafe version of: {@link #glUniform1iv Uniform1iv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform1iv(int location, int count, long value) { + GL20C.nglUniform1iv(location, count, value); + } + + /** + * Specifies the value of a single int uniform variable or a int uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform1iv(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + GL20C.glUniform1iv(location, value); + } + + // --- [ glUniform2iv ] --- + + /** + * Unsafe version of: {@link #glUniform2iv Uniform2iv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform2iv(int location, int count, long value) { + GL20C.nglUniform2iv(location, count, value); + } + + /** + * Specifies the value of a single ivec2 uniform variable or an ivec2 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform2iv(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + GL20C.glUniform2iv(location, value); + } + + // --- [ glUniform3iv ] --- + + /** + * Unsafe version of: {@link #glUniform3iv Uniform3iv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform3iv(int location, int count, long value) { + GL20C.nglUniform3iv(location, count, value); + } + + /** + * Specifies the value of a single ivec3 uniform variable or an ivec3 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform3iv(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + GL20C.glUniform3iv(location, value); + } + + // --- [ glUniform4iv ] --- + + /** + * Unsafe version of: {@link #glUniform4iv Uniform4iv} + * + * @param count the number of elements that are to be modified. This should be 1 if the targeted uniform variable is not an array, and 1 or more if it is an array. + */ + public static void nglUniform4iv(int location, int count, long value) { + GL20C.nglUniform4iv(location, count, value); + } + + /** + * Specifies the value of a single ivec4 uniform variable or an ivec4 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniform4iv(@NativeType("GLint") int location, @NativeType("GLint const *") IntBuffer value) { + GL20C.glUniform4iv(location, value); + } + + // --- [ glUniformMatrix2fv ] --- + + /** + * Unsafe version of: {@link #glUniformMatrix2fv UniformMatrix2fv} + * + * @param count the number of matrices that are to be modified. This should be 1 if the targeted uniform variable is not an array of matrices, and 1 or more if it is an array of matrices. + */ + public static void nglUniformMatrix2fv(int location, int count, boolean transpose, long value) { + GL20C.nglUniformMatrix2fv(location, count, transpose, value); + } + + /** + * Specifies the value of a single mat2 uniform variable or a mat2 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param transpose whether to transpose the matrix as the values are loaded into the uniform variable + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniformMatrix2fv(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") FloatBuffer value) { + GL20C.glUniformMatrix2fv(location, transpose, value); + } + + // --- [ glUniformMatrix3fv ] --- + + /** + * Unsafe version of: {@link #glUniformMatrix3fv UniformMatrix3fv} + * + * @param count the number of matrices that are to be modified. This should be 1 if the targeted uniform variable is not an array of matrices, and 1 or more if it is an array of matrices. + */ + public static void nglUniformMatrix3fv(int location, int count, boolean transpose, long value) { + GL20C.nglUniformMatrix3fv(location, count, transpose, value); + } + + /** + * Specifies the value of a single mat3 uniform variable or a mat3 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param transpose whether to transpose the matrix as the values are loaded into the uniform variable + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniformMatrix3fv(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") FloatBuffer value) { + GL20C.glUniformMatrix3fv(location, transpose, value); + } + + // --- [ glUniformMatrix4fv ] --- + + /** + * Unsafe version of: {@link #glUniformMatrix4fv UniformMatrix4fv} + * + * @param count the number of matrices that are to be modified. This should be 1 if the targeted uniform variable is not an array of matrices, and 1 or more if it is an array of matrices. + */ + public static void nglUniformMatrix4fv(int location, int count, boolean transpose, long value) { + GL20C.nglUniformMatrix4fv(location, count, transpose, value); + } + + /** + * Specifies the value of a single mat4 uniform variable or a mat4 uniform variable array for the current program object. + * + * @param location the location of the uniform variable to be modified + * @param transpose whether to transpose the matrix as the values are loaded into the uniform variable + * @param value a pointer to an array of {@code count} values that will be used to update the specified uniform variable + * + * @see Reference Page + */ + public static void glUniformMatrix4fv(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") FloatBuffer value) { + GL20C.glUniformMatrix4fv(location, transpose, value); + } + + // --- [ glGetShaderiv ] --- + + /** Unsafe version of: {@link #glGetShaderiv GetShaderiv} */ + public static void nglGetShaderiv(int shader, int pname, long params) { + GL20C.nglGetShaderiv(shader, pname, params); + } + + /** + * Returns a parameter from a shader object. + * + * @param shader the shader object to be queried + * @param pname the object parameter. One of:
{@link GL20C#GL_SHADER_TYPE SHADER_TYPE}{@link GL20C#GL_DELETE_STATUS DELETE_STATUS}{@link GL20C#GL_COMPILE_STATUS COMPILE_STATUS}{@link GL20C#GL_INFO_LOG_LENGTH INFO_LOG_LENGTH}{@link GL20C#GL_SHADER_SOURCE_LENGTH SHADER_SOURCE_LENGTH}
+ * @param params the requested object parameter + * + * @see Reference Page + */ + public static void glGetShaderiv(@NativeType("GLuint") int shader, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL20C.glGetShaderiv(shader, pname, params); + } + + /** + * Returns a parameter from a shader object. + * + * @param shader the shader object to be queried + * @param pname the object parameter. One of:
{@link GL20C#GL_SHADER_TYPE SHADER_TYPE}{@link GL20C#GL_DELETE_STATUS DELETE_STATUS}{@link GL20C#GL_COMPILE_STATUS COMPILE_STATUS}{@link GL20C#GL_INFO_LOG_LENGTH INFO_LOG_LENGTH}{@link GL20C#GL_SHADER_SOURCE_LENGTH SHADER_SOURCE_LENGTH}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetShaderi(@NativeType("GLuint") int shader, @NativeType("GLenum") int pname) { + return GL20C.glGetShaderi(shader, pname); + } + + // --- [ glGetProgramiv ] --- + + /** Unsafe version of: {@link #glGetProgramiv GetProgramiv} */ + public static void nglGetProgramiv(int program, int pname, long params) { + GL20C.nglGetProgramiv(program, pname, params); + } + + /** + * Returns a parameter from a program object. + * + * @param program the program object to be queried + * @param pname the object parameter. One of:
{@link GL20C#GL_DELETE_STATUS DELETE_STATUS}{@link GL20C#GL_LINK_STATUS LINK_STATUS}{@link GL20C#GL_VALIDATE_STATUS VALIDATE_STATUS}
{@link GL20C#GL_INFO_LOG_LENGTH INFO_LOG_LENGTH}{@link GL20C#GL_ATTACHED_SHADERS ATTACHED_SHADERS}{@link GL20C#GL_ACTIVE_ATTRIBUTES ACTIVE_ATTRIBUTES}
{@link GL20C#GL_ACTIVE_ATTRIBUTE_MAX_LENGTH ACTIVE_ATTRIBUTE_MAX_LENGTH}{@link GL20C#GL_ACTIVE_UNIFORMS ACTIVE_UNIFORMS}{@link GL20C#GL_ACTIVE_UNIFORM_MAX_LENGTH ACTIVE_UNIFORM_MAX_LENGTH}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER_MODE TRANSFORM_FEEDBACK_BUFFER_MODE}{@link GL30#GL_TRANSFORM_FEEDBACK_VARYINGS TRANSFORM_FEEDBACK_VARYINGS}{@link GL30#GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH}
{@link GL31#GL_ACTIVE_UNIFORM_BLOCKS ACTIVE_UNIFORM_BLOCKS}{@link GL31#GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH}{@link GL32#GL_GEOMETRY_VERTICES_OUT GEOMETRY_VERTICES_OUT}
{@link GL32#GL_GEOMETRY_INPUT_TYPE GEOMETRY_INPUT_TYPE}{@link GL32#GL_GEOMETRY_OUTPUT_TYPE GEOMETRY_OUTPUT_TYPE}{@link GL41#GL_PROGRAM_BINARY_LENGTH PROGRAM_BINARY_LENGTH}
{@link GL42#GL_ACTIVE_ATOMIC_COUNTER_BUFFERS ACTIVE_ATOMIC_COUNTER_BUFFERS}{@link GL43#GL_COMPUTE_WORK_GROUP_SIZE COMPUTE_WORK_GROUP_SIZE}
+ * @param params the requested object parameter + * + * @see Reference Page + */ + public static void glGetProgramiv(@NativeType("GLuint") int program, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL20C.glGetProgramiv(program, pname, params); + } + + /** + * Returns a parameter from a program object. + * + * @param program the program object to be queried + * @param pname the object parameter. One of:
{@link GL20C#GL_DELETE_STATUS DELETE_STATUS}{@link GL20C#GL_LINK_STATUS LINK_STATUS}{@link GL20C#GL_VALIDATE_STATUS VALIDATE_STATUS}
{@link GL20C#GL_INFO_LOG_LENGTH INFO_LOG_LENGTH}{@link GL20C#GL_ATTACHED_SHADERS ATTACHED_SHADERS}{@link GL20C#GL_ACTIVE_ATTRIBUTES ACTIVE_ATTRIBUTES}
{@link GL20C#GL_ACTIVE_ATTRIBUTE_MAX_LENGTH ACTIVE_ATTRIBUTE_MAX_LENGTH}{@link GL20C#GL_ACTIVE_UNIFORMS ACTIVE_UNIFORMS}{@link GL20C#GL_ACTIVE_UNIFORM_MAX_LENGTH ACTIVE_UNIFORM_MAX_LENGTH}
{@link GL30#GL_TRANSFORM_FEEDBACK_BUFFER_MODE TRANSFORM_FEEDBACK_BUFFER_MODE}{@link GL30#GL_TRANSFORM_FEEDBACK_VARYINGS TRANSFORM_FEEDBACK_VARYINGS}{@link GL30#GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH}
{@link GL31#GL_ACTIVE_UNIFORM_BLOCKS ACTIVE_UNIFORM_BLOCKS}{@link GL31#GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH}{@link GL32#GL_GEOMETRY_VERTICES_OUT GEOMETRY_VERTICES_OUT}
{@link GL32#GL_GEOMETRY_INPUT_TYPE GEOMETRY_INPUT_TYPE}{@link GL32#GL_GEOMETRY_OUTPUT_TYPE GEOMETRY_OUTPUT_TYPE}{@link GL41#GL_PROGRAM_BINARY_LENGTH PROGRAM_BINARY_LENGTH}
{@link GL42#GL_ACTIVE_ATOMIC_COUNTER_BUFFERS ACTIVE_ATOMIC_COUNTER_BUFFERS}{@link GL43#GL_COMPUTE_WORK_GROUP_SIZE COMPUTE_WORK_GROUP_SIZE}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetProgrami(@NativeType("GLuint") int program, @NativeType("GLenum") int pname) { + return GL20C.glGetProgrami(program, pname); + } + + // --- [ glGetShaderInfoLog ] --- + + /** + * Unsafe version of: {@link #glGetShaderInfoLog GetShaderInfoLog} + * + * @param maxLength the size of the character buffer for storing the returned information log + */ + public static void nglGetShaderInfoLog(int shader, int maxLength, long length, long infoLog) { + GL20C.nglGetShaderInfoLog(shader, maxLength, length, infoLog); + } + + /** + * Returns the information log for a shader object. + * + * @param shader the shader object whose information log is to be queried + * @param length the length of the string returned in {@code infoLog} (excluding the null terminator) + * @param infoLog an array of characters that is used to return the information log + * + * @see Reference Page + */ + public static void glGetShaderInfoLog(@NativeType("GLuint") int shader, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLchar *") ByteBuffer infoLog) { + GL20C.glGetShaderInfoLog(shader, length, infoLog); + } + + /** + * Returns the information log for a shader object. + * + * @param shader the shader object whose information log is to be queried + * @param maxLength the size of the character buffer for storing the returned information log + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetShaderInfoLog(@NativeType("GLuint") int shader, @NativeType("GLsizei") int maxLength) { + return GL20C.glGetShaderInfoLog(shader, maxLength); + } + + /** + * Returns the information log for a shader object. + * + * @param shader the shader object whose information log is to be queried + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetShaderInfoLog(@NativeType("GLuint") int shader) { + return glGetShaderInfoLog(shader, glGetShaderi(shader, GL_INFO_LOG_LENGTH)); + } + + // --- [ glGetProgramInfoLog ] --- + + /** + * Unsafe version of: {@link #glGetProgramInfoLog GetProgramInfoLog} + * + * @param maxLength the size of the character buffer for storing the returned information log + */ + public static void nglGetProgramInfoLog(int program, int maxLength, long length, long infoLog) { + GL20C.nglGetProgramInfoLog(program, maxLength, length, infoLog); + } + + /** + * Returns the information log for a program object. + * + * @param program the program object whose information log is to be queried + * @param length the length of the string returned in {@code infoLog} (excluding the null terminator) + * @param infoLog an array of characters that is used to return the information log + * + * @see Reference Page + */ + public static void glGetProgramInfoLog(@NativeType("GLuint") int program, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLchar *") ByteBuffer infoLog) { + GL20C.glGetProgramInfoLog(program, length, infoLog); + } + + /** + * Returns the information log for a program object. + * + * @param program the program object whose information log is to be queried + * @param maxLength the size of the character buffer for storing the returned information log + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetProgramInfoLog(@NativeType("GLuint") int program, @NativeType("GLsizei") int maxLength) { + return GL20C.glGetProgramInfoLog(program, maxLength); + } + + /** + * Returns the information log for a program object. + * + * @param program the program object whose information log is to be queried + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetProgramInfoLog(@NativeType("GLuint") int program) { + return glGetProgramInfoLog(program, glGetProgrami(program, GL_INFO_LOG_LENGTH)); + } + + // --- [ glGetAttachedShaders ] --- + + /** + * Unsafe version of: {@link #glGetAttachedShaders GetAttachedShaders} + * + * @param maxCount the size of the array for storing the returned object names + */ + public static void nglGetAttachedShaders(int program, int maxCount, long count, long shaders) { + GL20C.nglGetAttachedShaders(program, maxCount, count, shaders); + } + + /** + * Returns the shader objects attached to a program object. + * + * @param program the program object to be queried + * @param count the number of names actually returned in {@code shaders} + * @param shaders an array that is used to return the names of attached shader objects + * + * @see Reference Page + */ + public static void glGetAttachedShaders(@NativeType("GLuint") int program, @Nullable @NativeType("GLsizei *") IntBuffer count, @NativeType("GLuint *") IntBuffer shaders) { + GL20C.glGetAttachedShaders(program, count, shaders); + } + + // --- [ glGetUniformLocation ] --- + + /** Unsafe version of: {@link #glGetUniformLocation GetUniformLocation} */ + public static int nglGetUniformLocation(int program, long name) { + return GL20C.nglGetUniformLocation(program, name); + } + + /** + * Returns the location of a uniform variable. + * + * @param program the program object to be queried + * @param name a null terminated string containing the name of the uniform variable whose location is to be queried + * + * @see Reference Page + */ + @NativeType("GLint") + public static int glGetUniformLocation(@NativeType("GLuint") int program, @NativeType("GLchar const *") ByteBuffer name) { + return GL20C.glGetUniformLocation(program, name); + } + + /** + * Returns the location of a uniform variable. + * + * @param program the program object to be queried + * @param name a null terminated string containing the name of the uniform variable whose location is to be queried + * + * @see Reference Page + */ + @NativeType("GLint") + public static int glGetUniformLocation(@NativeType("GLuint") int program, @NativeType("GLchar const *") CharSequence name) { + return GL20C.glGetUniformLocation(program, name); + } + + // --- [ glGetActiveUniform ] --- + + /** + * Unsafe version of: {@link #glGetActiveUniform GetActiveUniform} + * + * @param maxLength the maximum number of characters OpenGL is allowed to write in the character buffer indicated by {@code name} + */ + public static void nglGetActiveUniform(int program, int index, int maxLength, long length, long size, long type, long name) { + GL20C.nglGetActiveUniform(program, index, maxLength, length, size, type, name); + } + + /** + * Returns information about an active uniform variable for the specified program object. + * + * @param program the program object to be queried + * @param index the index of the uniform variable to be queried + * @param length the number of characters actually written by OpenGL in the string indicated by {@code name} (excluding the null terminator) if a value other than NULL is passed + * @param size the size of the uniform variable + * @param type the data type of the uniform variable + * @param name a null terminated string containing the name of the uniform variable + * + * @see Reference Page + */ + public static void glGetActiveUniform(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type, @NativeType("GLchar *") ByteBuffer name) { + GL20C.glGetActiveUniform(program, index, length, size, type, name); + } + + /** + * Returns information about an active uniform variable for the specified program object. + * + * @param program the program object to be queried + * @param index the index of the uniform variable to be queried + * @param maxLength the maximum number of characters OpenGL is allowed to write in the character buffer indicated by {@code name} + * @param size the size of the uniform variable + * @param type the data type of the uniform variable + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetActiveUniform(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @NativeType("GLsizei") int maxLength, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type) { + return GL20C.glGetActiveUniform(program, index, maxLength, size, type); + } + + /** + * Returns information about an active uniform variable for the specified program object. + * + * @param program the program object to be queried + * @param index the index of the uniform variable to be queried + * @param size the size of the uniform variable + * @param type the data type of the uniform variable + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetActiveUniform(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type) { + return glGetActiveUniform(program, index, glGetProgrami(program, GL_ACTIVE_UNIFORM_MAX_LENGTH), size, type); + } + + // --- [ glGetUniformfv ] --- + + /** Unsafe version of: {@link #glGetUniformfv GetUniformfv} */ + public static void nglGetUniformfv(int program, int location, long params) { + GL20C.nglGetUniformfv(program, location, params); + } + + /** + * Returns the float value(s) of a uniform variable. + * + * @param program the program object to be queried + * @param location the location of the uniform variable to be queried + * @param params the value of the specified uniform variable + * + * @see Reference Page + */ + public static void glGetUniformfv(@NativeType("GLuint") int program, @NativeType("GLint") int location, @NativeType("GLfloat *") FloatBuffer params) { + GL20C.glGetUniformfv(program, location, params); + } + + /** + * Returns the float value(s) of a uniform variable. + * + * @param program the program object to be queried + * @param location the location of the uniform variable to be queried + * + * @see Reference Page + */ + @NativeType("void") + public static float glGetUniformf(@NativeType("GLuint") int program, @NativeType("GLint") int location) { + return GL20C.glGetUniformf(program, location); + } + + // --- [ glGetUniformiv ] --- + + /** Unsafe version of: {@link #glGetUniformiv GetUniformiv} */ + public static void nglGetUniformiv(int program, int location, long params) { + GL20C.nglGetUniformiv(program, location, params); + } + + /** + * Returns the int value(s) of a uniform variable. + * + * @param program the program object to be queried + * @param location the location of the uniform variable to be queried + * @param params the value of the specified uniform variable + * + * @see Reference Page + */ + public static void glGetUniformiv(@NativeType("GLuint") int program, @NativeType("GLint") int location, @NativeType("GLint *") IntBuffer params) { + GL20C.glGetUniformiv(program, location, params); + } + + /** + * Returns the int value(s) of a uniform variable. + * + * @param program the program object to be queried + * @param location the location of the uniform variable to be queried + * + * @see Reference Page + */ + @NativeType("void") + public static int glGetUniformi(@NativeType("GLuint") int program, @NativeType("GLint") int location) { + return GL20C.glGetUniformi(program, location); + } + + // --- [ glGetShaderSource ] --- + + /** + * Unsafe version of: {@link #glGetShaderSource GetShaderSource} + * + * @param maxLength the size of the character buffer for storing the returned source code string + */ + public static void nglGetShaderSource(int shader, int maxLength, long length, long source) { + GL20C.nglGetShaderSource(shader, maxLength, length, source); + } + + /** + * Returns the source code string from a shader object. + * + * @param shader the shader object to be queried + * @param length the length of the string returned in source (excluding the null terminator) + * @param source an array of characters that is used to return the source code string + * + * @see Reference Page + */ + public static void glGetShaderSource(@NativeType("GLuint") int shader, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLchar *") ByteBuffer source) { + GL20C.glGetShaderSource(shader, length, source); + } + + /** + * Returns the source code string from a shader object. + * + * @param shader the shader object to be queried + * @param maxLength the size of the character buffer for storing the returned source code string + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetShaderSource(@NativeType("GLuint") int shader, @NativeType("GLsizei") int maxLength) { + return GL20C.glGetShaderSource(shader, maxLength); + } + + /** + * Returns the source code string from a shader object. + * + * @param shader the shader object to be queried + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetShaderSource(@NativeType("GLuint") int shader) { + return glGetShaderSource(shader, glGetShaderi(shader, GL_SHADER_SOURCE_LENGTH)); + } + + // --- [ glVertexAttrib1f ] --- + + /** + * Specifies the value of a generic vertex attribute. The y and z components are implicitly set to 0.0f and w to 1.0f. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * + * @see Reference Page + */ + public static void glVertexAttrib1f(@NativeType("GLuint") int index, @NativeType("GLfloat") float v0) { + GL20C.glVertexAttrib1f(index, v0); + } + + // --- [ glVertexAttrib1s ] --- + + /** + * Short version of {@link #glVertexAttrib1f VertexAttrib1f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * + * @see Reference Page + */ + public static void glVertexAttrib1s(@NativeType("GLuint") int index, @NativeType("GLshort") short v0) { + GL20C.glVertexAttrib1s(index, v0); + } + + // --- [ glVertexAttrib1d ] --- + + /** + * Double version of {@link #glVertexAttrib1f VertexAttrib1f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * + * @see Reference Page + */ + public static void glVertexAttrib1d(@NativeType("GLuint") int index, @NativeType("GLdouble") double v0) { + GL20C.glVertexAttrib1d(index, v0); + } + + // --- [ glVertexAttrib2f ] --- + + /** + * Specifies the value of a generic vertex attribute. The y component is implicitly set to 0.0f and w to 1.0f. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * + * @see Reference Page + */ + public static void glVertexAttrib2f(@NativeType("GLuint") int index, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1) { + GL20C.glVertexAttrib2f(index, v0, v1); + } + + // --- [ glVertexAttrib2s ] --- + + /** + * Short version of {@link #glVertexAttrib2f VertexAttrib2f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * + * @see Reference Page + */ + public static void glVertexAttrib2s(@NativeType("GLuint") int index, @NativeType("GLshort") short v0, @NativeType("GLshort") short v1) { + GL20C.glVertexAttrib2s(index, v0, v1); + } + + // --- [ glVertexAttrib2d ] --- + + /** + * Double version of {@link #glVertexAttrib2f VertexAttrib2f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * + * @see Reference Page + */ + public static void glVertexAttrib2d(@NativeType("GLuint") int index, @NativeType("GLdouble") double v0, @NativeType("GLdouble") double v1) { + GL20C.glVertexAttrib2d(index, v0, v1); + } + + // --- [ glVertexAttrib3f ] --- + + /** + * Specifies the value of a generic vertex attribute. The w is implicitly set to 1.0f. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * @param v2 the vertex attribute z component + * + * @see Reference Page + */ + public static void glVertexAttrib3f(@NativeType("GLuint") int index, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2) { + GL20C.glVertexAttrib3f(index, v0, v1, v2); + } + + // --- [ glVertexAttrib3s ] --- + + /** + * Short version of {@link #glVertexAttrib3f VertexAttrib3f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * @param v2 the vertex attribute z component + * + * @see Reference Page + */ + public static void glVertexAttrib3s(@NativeType("GLuint") int index, @NativeType("GLshort") short v0, @NativeType("GLshort") short v1, @NativeType("GLshort") short v2) { + GL20C.glVertexAttrib3s(index, v0, v1, v2); + } + + // --- [ glVertexAttrib3d ] --- + + /** + * Double version of {@link #glVertexAttrib3f VertexAttrib3f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * @param v2 the vertex attribute z component + * + * @see Reference Page + */ + public static void glVertexAttrib3d(@NativeType("GLuint") int index, @NativeType("GLdouble") double v0, @NativeType("GLdouble") double v1, @NativeType("GLdouble") double v2) { + GL20C.glVertexAttrib3d(index, v0, v1, v2); + } + + // --- [ glVertexAttrib4f ] --- + + /** + * Specifies the value of a generic vertex attribute. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * @param v2 the vertex attribute z component + * @param v3 the vertex attribute w component + * + * @see Reference Page + */ + public static void glVertexAttrib4f(@NativeType("GLuint") int index, @NativeType("GLfloat") float v0, @NativeType("GLfloat") float v1, @NativeType("GLfloat") float v2, @NativeType("GLfloat") float v3) { + GL20C.glVertexAttrib4f(index, v0, v1, v2, v3); + } + + // --- [ glVertexAttrib4s ] --- + + /** + * Short version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * @param v2 the vertex attribute z component + * @param v3 the vertex attribute w component + * + * @see Reference Page + */ + public static void glVertexAttrib4s(@NativeType("GLuint") int index, @NativeType("GLshort") short v0, @NativeType("GLshort") short v1, @NativeType("GLshort") short v2, @NativeType("GLshort") short v3) { + GL20C.glVertexAttrib4s(index, v0, v1, v2, v3); + } + + // --- [ glVertexAttrib4d ] --- + + /** + * Double version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v0 the vertex attribute x component + * @param v1 the vertex attribute y component + * @param v2 the vertex attribute z component + * @param v3 the vertex attribute w component + * + * @see Reference Page + */ + public static void glVertexAttrib4d(@NativeType("GLuint") int index, @NativeType("GLdouble") double v0, @NativeType("GLdouble") double v1, @NativeType("GLdouble") double v2, @NativeType("GLdouble") double v3) { + GL20C.glVertexAttrib4d(index, v0, v1, v2, v3); + } + + // --- [ glVertexAttrib4Nub ] --- + + /** + * Normalized unsigned byte version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param x the vertex attribute x component + * @param y the vertex attribute y component + * @param z the vertex attribute z component + * @param w the vertex attribute w component + * + * @see Reference Page + */ + public static void glVertexAttrib4Nub(@NativeType("GLuint") int index, @NativeType("GLubyte") byte x, @NativeType("GLubyte") byte y, @NativeType("GLubyte") byte z, @NativeType("GLubyte") byte w) { + GL20C.glVertexAttrib4Nub(index, x, y, z, w); + } + + // --- [ glVertexAttrib1fv ] --- + + /** Unsafe version of: {@link #glVertexAttrib1fv VertexAttrib1fv} */ + public static void nglVertexAttrib1fv(int index, long v) { + GL20C.nglVertexAttrib1fv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib1f VertexAttrib1f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib1fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") FloatBuffer v) { + GL20C.glVertexAttrib1fv(index, v); + } + + // --- [ glVertexAttrib1sv ] --- + + /** Unsafe version of: {@link #glVertexAttrib1sv VertexAttrib1sv} */ + public static void nglVertexAttrib1sv(int index, long v) { + GL20C.nglVertexAttrib1sv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib1s VertexAttrib1s}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib1sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") ShortBuffer v) { + GL20C.glVertexAttrib1sv(index, v); + } + + // --- [ glVertexAttrib1dv ] --- + + /** Unsafe version of: {@link #glVertexAttrib1dv VertexAttrib1dv} */ + public static void nglVertexAttrib1dv(int index, long v) { + GL20C.nglVertexAttrib1dv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib1d VertexAttrib1d}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib1dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") DoubleBuffer v) { + GL20C.glVertexAttrib1dv(index, v); + } + + // --- [ glVertexAttrib2fv ] --- + + /** Unsafe version of: {@link #glVertexAttrib2fv VertexAttrib2fv} */ + public static void nglVertexAttrib2fv(int index, long v) { + GL20C.nglVertexAttrib2fv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib2f VertexAttrib2f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib2fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") FloatBuffer v) { + GL20C.glVertexAttrib2fv(index, v); + } + + // --- [ glVertexAttrib2sv ] --- + + /** Unsafe version of: {@link #glVertexAttrib2sv VertexAttrib2sv} */ + public static void nglVertexAttrib2sv(int index, long v) { + GL20C.nglVertexAttrib2sv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib2s VertexAttrib2s}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib2sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") ShortBuffer v) { + GL20C.glVertexAttrib2sv(index, v); + } + + // --- [ glVertexAttrib2dv ] --- + + /** Unsafe version of: {@link #glVertexAttrib2dv VertexAttrib2dv} */ + public static void nglVertexAttrib2dv(int index, long v) { + GL20C.nglVertexAttrib2dv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib2d VertexAttrib2d}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib2dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") DoubleBuffer v) { + GL20C.glVertexAttrib2dv(index, v); + } + + // --- [ glVertexAttrib3fv ] --- + + /** Unsafe version of: {@link #glVertexAttrib3fv VertexAttrib3fv} */ + public static void nglVertexAttrib3fv(int index, long v) { + GL20C.nglVertexAttrib3fv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib3f VertexAttrib3f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib3fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") FloatBuffer v) { + GL20C.glVertexAttrib3fv(index, v); + } + + // --- [ glVertexAttrib3sv ] --- + + /** Unsafe version of: {@link #glVertexAttrib3sv VertexAttrib3sv} */ + public static void nglVertexAttrib3sv(int index, long v) { + GL20C.nglVertexAttrib3sv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib3s VertexAttrib3s}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib3sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") ShortBuffer v) { + GL20C.glVertexAttrib3sv(index, v); + } + + // --- [ glVertexAttrib3dv ] --- + + /** Unsafe version of: {@link #glVertexAttrib3dv VertexAttrib3dv} */ + public static void nglVertexAttrib3dv(int index, long v) { + GL20C.nglVertexAttrib3dv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib3d VertexAttrib3d}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib3dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") DoubleBuffer v) { + GL20C.glVertexAttrib3dv(index, v); + } + + // --- [ glVertexAttrib4fv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4fv VertexAttrib4fv} */ + public static void nglVertexAttrib4fv(int index, long v) { + GL20C.nglVertexAttrib4fv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") FloatBuffer v) { + GL20C.glVertexAttrib4fv(index, v); + } + + // --- [ glVertexAttrib4sv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4sv VertexAttrib4sv} */ + public static void nglVertexAttrib4sv(int index, long v) { + GL20C.nglVertexAttrib4sv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib4s VertexAttrib4s}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") ShortBuffer v) { + GL20C.glVertexAttrib4sv(index, v); + } + + // --- [ glVertexAttrib4dv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4dv VertexAttrib4dv} */ + public static void nglVertexAttrib4dv(int index, long v) { + GL20C.nglVertexAttrib4dv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib4d VertexAttrib4d}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") DoubleBuffer v) { + GL20C.glVertexAttrib4dv(index, v); + } + + // --- [ glVertexAttrib4iv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4iv VertexAttrib4iv} */ + public static void nglVertexAttrib4iv(int index, long v) { + GL20C.nglVertexAttrib4iv(index, v); + } + + /** + * Integer pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4iv(@NativeType("GLuint") int index, @NativeType("GLint const *") IntBuffer v) { + GL20C.glVertexAttrib4iv(index, v); + } + + // --- [ glVertexAttrib4bv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4bv VertexAttrib4bv} */ + public static void nglVertexAttrib4bv(int index, long v) { + GL20C.nglVertexAttrib4bv(index, v); + } + + /** + * Byte pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4bv(@NativeType("GLuint") int index, @NativeType("GLbyte const *") ByteBuffer v) { + GL20C.glVertexAttrib4bv(index, v); + } + + // --- [ glVertexAttrib4ubv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4ubv VertexAttrib4ubv} */ + public static void nglVertexAttrib4ubv(int index, long v) { + GL20C.nglVertexAttrib4ubv(index, v); + } + + /** + * Pointer version of {@link #glVertexAttrib4Nub VertexAttrib4Nub}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4ubv(@NativeType("GLuint") int index, @NativeType("GLubyte const *") ByteBuffer v) { + GL20C.glVertexAttrib4ubv(index, v); + } + + // --- [ glVertexAttrib4usv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4usv VertexAttrib4usv} */ + public static void nglVertexAttrib4usv(int index, long v) { + GL20C.nglVertexAttrib4usv(index, v); + } + + /** + * Unsigned short pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4usv(@NativeType("GLuint") int index, @NativeType("GLushort const *") ShortBuffer v) { + GL20C.glVertexAttrib4usv(index, v); + } + + // --- [ glVertexAttrib4uiv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4uiv VertexAttrib4uiv} */ + public static void nglVertexAttrib4uiv(int index, long v) { + GL20C.nglVertexAttrib4uiv(index, v); + } + + /** + * Unsigned int pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4uiv(@NativeType("GLuint") int index, @NativeType("GLuint const *") IntBuffer v) { + GL20C.glVertexAttrib4uiv(index, v); + } + + // --- [ glVertexAttrib4Nbv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4Nbv VertexAttrib4Nbv} */ + public static void nglVertexAttrib4Nbv(int index, long v) { + GL20C.nglVertexAttrib4Nbv(index, v); + } + + /** + * Normalized byte pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4Nbv(@NativeType("GLuint") int index, @NativeType("GLbyte const *") ByteBuffer v) { + GL20C.glVertexAttrib4Nbv(index, v); + } + + // --- [ glVertexAttrib4Nsv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4Nsv VertexAttrib4Nsv} */ + public static void nglVertexAttrib4Nsv(int index, long v) { + GL20C.nglVertexAttrib4Nsv(index, v); + } + + /** + * Normalized short pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4Nsv(@NativeType("GLuint") int index, @NativeType("GLshort const *") ShortBuffer v) { + GL20C.glVertexAttrib4Nsv(index, v); + } + + // --- [ glVertexAttrib4Niv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4Niv VertexAttrib4Niv} */ + public static void nglVertexAttrib4Niv(int index, long v) { + GL20C.nglVertexAttrib4Niv(index, v); + } + + /** + * Normalized int pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4Niv(@NativeType("GLuint") int index, @NativeType("GLint const *") IntBuffer v) { + GL20C.glVertexAttrib4Niv(index, v); + } + + // --- [ glVertexAttrib4Nubv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4Nubv VertexAttrib4Nubv} */ + public static void nglVertexAttrib4Nubv(int index, long v) { + GL20C.nglVertexAttrib4Nubv(index, v); + } + + /** + * Normalized unsigned byte pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4Nubv(@NativeType("GLuint") int index, @NativeType("GLubyte const *") ByteBuffer v) { + GL20C.glVertexAttrib4Nubv(index, v); + } + + // --- [ glVertexAttrib4Nusv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4Nusv VertexAttrib4Nusv} */ + public static void nglVertexAttrib4Nusv(int index, long v) { + GL20C.nglVertexAttrib4Nusv(index, v); + } + + /** + * Normalized unsigned short pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4Nusv(@NativeType("GLuint") int index, @NativeType("GLushort const *") ShortBuffer v) { + GL20C.glVertexAttrib4Nusv(index, v); + } + + // --- [ glVertexAttrib4Nuiv ] --- + + /** Unsafe version of: {@link #glVertexAttrib4Nuiv VertexAttrib4Nuiv} */ + public static void nglVertexAttrib4Nuiv(int index, long v) { + GL20C.nglVertexAttrib4Nuiv(index, v); + } + + /** + * Normalized unsigned int pointer version of {@link #glVertexAttrib4f VertexAttrib4f}. + * + * @param index the index of the generic vertex attribute to be modified + * @param v the vertex attribute buffer + * + * @see Reference Page + */ + public static void glVertexAttrib4Nuiv(@NativeType("GLuint") int index, @NativeType("GLuint const *") IntBuffer v) { + GL20C.glVertexAttrib4Nuiv(index, v); + } + + // --- [ glVertexAttribPointer ] --- + + /** Unsafe version of: {@link #glVertexAttribPointer VertexAttribPointer} */ + public static void nglVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, long pointer) { + GL20C.nglVertexAttribPointer(index, size, type, normalized, stride, pointer); + } + + /** + * Specifies the location and organization of a vertex attribute array. + * + * @param index the index of the generic vertex attribute to be modified + * @param size the number of values per vertex that are stored in the array. The initial value is 4. One of:
1234{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of each component in the array. The initial value is GL_FLOAT. One of:
{@link GL11#GL_BYTE BYTE}{@link GL11#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11#GL_SHORT SHORT}{@link GL11#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11#GL_INT INT}{@link GL11#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11#GL_FLOAT FLOAT}
{@link GL11#GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}{@link GL41#GL_FIXED FIXED}
+ * @param normalized whether fixed-point data values should be normalized or converted directly as fixed-point values when they are accessed + * @param stride the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in + * the array. The initial value is 0. + * @param pointer the vertex attribute data or the offset of the first component of the first generic vertex attribute in the array in the data store of the buffer + * currently bound to the {@link GL15#GL_ARRAY_BUFFER ARRAY_BUFFER} target. The initial value is 0. + * + * @see Reference Page + */ + public static void glVertexAttribPointer(@NativeType("GLuint") int index, @NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLboolean") boolean normalized, @NativeType("GLsizei") int stride, @NativeType("void const *") ByteBuffer pointer) { + GL20C.glVertexAttribPointer(index, size, type, normalized, stride, pointer); + } + + /** + * Specifies the location and organization of a vertex attribute array. + * + * @param index the index of the generic vertex attribute to be modified + * @param size the number of values per vertex that are stored in the array. The initial value is 4. One of:
1234{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of each component in the array. The initial value is GL_FLOAT. One of:
{@link GL11#GL_BYTE BYTE}{@link GL11#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11#GL_SHORT SHORT}{@link GL11#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11#GL_INT INT}{@link GL11#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11#GL_FLOAT FLOAT}
{@link GL11#GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}{@link GL41#GL_FIXED FIXED}
+ * @param normalized whether fixed-point data values should be normalized or converted directly as fixed-point values when they are accessed + * @param stride the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in + * the array. The initial value is 0. + * @param pointer the vertex attribute data or the offset of the first component of the first generic vertex attribute in the array in the data store of the buffer + * currently bound to the {@link GL15#GL_ARRAY_BUFFER ARRAY_BUFFER} target. The initial value is 0. + * + * @see Reference Page + */ + public static void glVertexAttribPointer(@NativeType("GLuint") int index, @NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLboolean") boolean normalized, @NativeType("GLsizei") int stride, @NativeType("void const *") long pointer) { + GL20C.glVertexAttribPointer(index, size, type, normalized, stride, pointer); + } + + /** + * Specifies the location and organization of a vertex attribute array. + * + * @param index the index of the generic vertex attribute to be modified + * @param size the number of values per vertex that are stored in the array. The initial value is 4. One of:
1234{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of each component in the array. The initial value is GL_FLOAT. One of:
{@link GL11#GL_BYTE BYTE}{@link GL11#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11#GL_SHORT SHORT}{@link GL11#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11#GL_INT INT}{@link GL11#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11#GL_FLOAT FLOAT}
{@link GL11#GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}{@link GL41#GL_FIXED FIXED}
+ * @param normalized whether fixed-point data values should be normalized or converted directly as fixed-point values when they are accessed + * @param stride the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in + * the array. The initial value is 0. + * @param pointer the vertex attribute data or the offset of the first component of the first generic vertex attribute in the array in the data store of the buffer + * currently bound to the {@link GL15#GL_ARRAY_BUFFER ARRAY_BUFFER} target. The initial value is 0. + * + * @see Reference Page + */ + public static void glVertexAttribPointer(@NativeType("GLuint") int index, @NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLboolean") boolean normalized, @NativeType("GLsizei") int stride, @NativeType("void const *") ShortBuffer pointer) { + GL20C.glVertexAttribPointer(index, size, type, normalized, stride, pointer); + } + + /** + * Specifies the location and organization of a vertex attribute array. + * + * @param index the index of the generic vertex attribute to be modified + * @param size the number of values per vertex that are stored in the array. The initial value is 4. One of:
1234{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of each component in the array. The initial value is GL_FLOAT. One of:
{@link GL11#GL_BYTE BYTE}{@link GL11#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11#GL_SHORT SHORT}{@link GL11#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11#GL_INT INT}{@link GL11#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11#GL_FLOAT FLOAT}
{@link GL11#GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}{@link GL41#GL_FIXED FIXED}
+ * @param normalized whether fixed-point data values should be normalized or converted directly as fixed-point values when they are accessed + * @param stride the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in + * the array. The initial value is 0. + * @param pointer the vertex attribute data or the offset of the first component of the first generic vertex attribute in the array in the data store of the buffer + * currently bound to the {@link GL15#GL_ARRAY_BUFFER ARRAY_BUFFER} target. The initial value is 0. + * + * @see Reference Page + */ + public static void glVertexAttribPointer(@NativeType("GLuint") int index, @NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLboolean") boolean normalized, @NativeType("GLsizei") int stride, @NativeType("void const *") IntBuffer pointer) { + GL20C.glVertexAttribPointer(index, size, type, normalized, stride, pointer); + } + + /** + * Specifies the location and organization of a vertex attribute array. + * + * @param index the index of the generic vertex attribute to be modified + * @param size the number of values per vertex that are stored in the array. The initial value is 4. One of:
1234{@link GL12#GL_BGRA BGRA}
+ * @param type the data type of each component in the array. The initial value is GL_FLOAT. One of:
{@link GL11#GL_BYTE BYTE}{@link GL11#GL_UNSIGNED_BYTE UNSIGNED_BYTE}{@link GL11#GL_SHORT SHORT}{@link GL11#GL_UNSIGNED_SHORT UNSIGNED_SHORT}{@link GL11#GL_INT INT}{@link GL11#GL_UNSIGNED_INT UNSIGNED_INT}{@link GL30#GL_HALF_FLOAT HALF_FLOAT}{@link GL11#GL_FLOAT FLOAT}
{@link GL11#GL_DOUBLE DOUBLE}{@link GL12#GL_UNSIGNED_INT_2_10_10_10_REV UNSIGNED_INT_2_10_10_10_REV}{@link GL33#GL_INT_2_10_10_10_REV INT_2_10_10_10_REV}{@link GL41#GL_FIXED FIXED}
+ * @param normalized whether fixed-point data values should be normalized or converted directly as fixed-point values when they are accessed + * @param stride the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in + * the array. The initial value is 0. + * @param pointer the vertex attribute data or the offset of the first component of the first generic vertex attribute in the array in the data store of the buffer + * currently bound to the {@link GL15#GL_ARRAY_BUFFER ARRAY_BUFFER} target. The initial value is 0. + * + * @see Reference Page + */ + public static void glVertexAttribPointer(@NativeType("GLuint") int index, @NativeType("GLint") int size, @NativeType("GLenum") int type, @NativeType("GLboolean") boolean normalized, @NativeType("GLsizei") int stride, @NativeType("void const *") FloatBuffer pointer) { + GL20C.glVertexAttribPointer(index, size, type, normalized, stride, pointer); + } + + // --- [ glEnableVertexAttribArray ] --- + + /** + * Enables a generic vertex attribute array. + * + * @param index the index of the generic vertex attribute to be enabled + * + * @see Reference Page + */ + public static void glEnableVertexAttribArray(@NativeType("GLuint") int index) { + GL20C.glEnableVertexAttribArray(index); + } + + // --- [ glDisableVertexAttribArray ] --- + + /** + * Disables a generic vertex attribute array. + * + * @param index the index of the generic vertex attribute to be disabled + * + * @see Reference Page + */ + public static void glDisableVertexAttribArray(@NativeType("GLuint") int index) { + GL20C.glDisableVertexAttribArray(index); + } + + // --- [ glBindAttribLocation ] --- + + /** Unsafe version of: {@link #glBindAttribLocation BindAttribLocation} */ + public static void nglBindAttribLocation(int program, int index, long name) { + GL20C.nglBindAttribLocation(program, index, name); + } + + /** + * Associates a generic vertex attribute index with a named attribute variable. + * + * @param program the program object in which the association is to be made + * @param index the index of the generic vertex attribute to be bound + * @param name a null terminated string containing the name of the vertex shader attribute variable to which {@code index} is to be bound + * + * @see Reference Page + */ + public static void glBindAttribLocation(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @NativeType("GLchar const *") ByteBuffer name) { + GL20C.glBindAttribLocation(program, index, name); + } + + /** + * Associates a generic vertex attribute index with a named attribute variable. + * + * @param program the program object in which the association is to be made + * @param index the index of the generic vertex attribute to be bound + * @param name a null terminated string containing the name of the vertex shader attribute variable to which {@code index} is to be bound + * + * @see Reference Page + */ + public static void glBindAttribLocation(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @NativeType("GLchar const *") CharSequence name) { + GL20C.glBindAttribLocation(program, index, name); + } + + // --- [ glGetActiveAttrib ] --- + + /** + * Unsafe version of: {@link #glGetActiveAttrib GetActiveAttrib} + * + * @param maxLength the maximum number of characters OpenGL is allowed to write in the character buffer indicated by {@code name} + */ + public static void nglGetActiveAttrib(int program, int index, int maxLength, long length, long size, long type, long name) { + GL20C.nglGetActiveAttrib(program, index, maxLength, length, size, type, name); + } + + /** + * Returns information about an active attribute variable for the specified program object. + * + * @param program the program object to be queried + * @param index the index of the attribute variable to be queried + * @param length the number of characters actually written by OpenGL in the string indicated by {@code name} (excluding the null terminator) if a value other than + * {@code NULL} is passed + * @param size the size of the attribute variable + * @param type the data type of the attribute variable + * @param name a null terminated string containing the name of the attribute variable + * + * @see Reference Page + */ + public static void glGetActiveAttrib(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @Nullable @NativeType("GLsizei *") IntBuffer length, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type, @NativeType("GLchar *") ByteBuffer name) { + GL20C.glGetActiveAttrib(program, index, length, size, type, name); + } + + /** + * Returns information about an active attribute variable for the specified program object. + * + * @param program the program object to be queried + * @param index the index of the attribute variable to be queried + * @param maxLength the maximum number of characters OpenGL is allowed to write in the character buffer indicated by {@code name} + * @param size the size of the attribute variable + * @param type the data type of the attribute variable + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetActiveAttrib(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @NativeType("GLsizei") int maxLength, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type) { + return GL20C.glGetActiveAttrib(program, index, maxLength, size, type); + } + + /** + * Returns information about an active attribute variable for the specified program object. + * + * @param program the program object to be queried + * @param index the index of the attribute variable to be queried + * @param size the size of the attribute variable + * @param type the data type of the attribute variable + * + * @see Reference Page + */ + @NativeType("void") + public static String glGetActiveAttrib(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @NativeType("GLint *") IntBuffer size, @NativeType("GLenum *") IntBuffer type) { + return glGetActiveAttrib(program, index, glGetProgrami(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH), size, type); + } + + // --- [ glGetAttribLocation ] --- + + /** Unsafe version of: {@link #glGetAttribLocation GetAttribLocation} */ + public static int nglGetAttribLocation(int program, long name) { + return GL20C.nglGetAttribLocation(program, name); + } + + /** + * Returns the location of an attribute variable. + * + * @param program the program object to be queried + * @param name a null terminated string containing the name of the attribute variable whose location is to be queried + * + * @see Reference Page + */ + @NativeType("GLint") + public static int glGetAttribLocation(@NativeType("GLuint") int program, @NativeType("GLchar const *") ByteBuffer name) { + return GL20C.glGetAttribLocation(program, name); + } + + /** + * Returns the location of an attribute variable. + * + * @param program the program object to be queried + * @param name a null terminated string containing the name of the attribute variable whose location is to be queried + * + * @see Reference Page + */ + @NativeType("GLint") + public static int glGetAttribLocation(@NativeType("GLuint") int program, @NativeType("GLchar const *") CharSequence name) { + return GL20C.glGetAttribLocation(program, name); + } + + // --- [ glGetVertexAttribiv ] --- + + /** Unsafe version of: {@link #glGetVertexAttribiv GetVertexAttribiv} */ + public static void nglGetVertexAttribiv(int index, int pname, long params) { + GL20C.nglGetVertexAttribiv(index, pname, params); + } + + /** + * Returns the integer value of a generic vertex attribute parameter. + * + * @param index the generic vertex attribute parameter to be queried + * @param pname the symbolic name of the vertex attribute parameter to be queried. One of:
{@link GL15#GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING VERTEX_ATTRIB_ARRAY_BUFFER_BINDING}{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_ENABLED VERTEX_ATTRIB_ARRAY_ENABLED}
{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_SIZE VERTEX_ATTRIB_ARRAY_SIZE}{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_STRIDE VERTEX_ATTRIB_ARRAY_STRIDE}
{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_TYPE VERTEX_ATTRIB_ARRAY_TYPE}{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_NORMALIZED VERTEX_ATTRIB_ARRAY_NORMALIZED}
{@link GL20C#GL_CURRENT_VERTEX_ATTRIB CURRENT_VERTEX_ATTRIB}{@link GL30#GL_VERTEX_ATTRIB_ARRAY_INTEGER VERTEX_ATTRIB_ARRAY_INTEGER}
{@link GL33#GL_VERTEX_ATTRIB_ARRAY_DIVISOR VERTEX_ATTRIB_ARRAY_DIVISOR}
+ * @param params returns the requested data + * + * @see Reference Page + */ + public static void glGetVertexAttribiv(@NativeType("GLuint") int index, @NativeType("GLenum") int pname, @NativeType("GLint *") IntBuffer params) { + GL20C.glGetVertexAttribiv(index, pname, params); + } + + /** + * Returns the integer value of a generic vertex attribute parameter. + * + * @param index the generic vertex attribute parameter to be queried + * @param pname the symbolic name of the vertex attribute parameter to be queried. One of:
{@link GL15#GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING VERTEX_ATTRIB_ARRAY_BUFFER_BINDING}{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_ENABLED VERTEX_ATTRIB_ARRAY_ENABLED}
{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_SIZE VERTEX_ATTRIB_ARRAY_SIZE}{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_STRIDE VERTEX_ATTRIB_ARRAY_STRIDE}
{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_TYPE VERTEX_ATTRIB_ARRAY_TYPE}{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_NORMALIZED VERTEX_ATTRIB_ARRAY_NORMALIZED}
{@link GL20C#GL_CURRENT_VERTEX_ATTRIB CURRENT_VERTEX_ATTRIB}{@link GL30#GL_VERTEX_ATTRIB_ARRAY_INTEGER VERTEX_ATTRIB_ARRAY_INTEGER}
{@link GL33#GL_VERTEX_ATTRIB_ARRAY_DIVISOR VERTEX_ATTRIB_ARRAY_DIVISOR}
+ * + * @see Reference Page + */ + @NativeType("void") + public static int glGetVertexAttribi(@NativeType("GLuint") int index, @NativeType("GLenum") int pname) { + return GL20C.glGetVertexAttribi(index, pname); + } + + // --- [ glGetVertexAttribfv ] --- + + /** Unsafe version of: {@link #glGetVertexAttribfv GetVertexAttribfv} */ + public static void nglGetVertexAttribfv(int index, int pname, long params) { + GL20C.nglGetVertexAttribfv(index, pname, params); + } + + /** + * Float version of {@link #glGetVertexAttribiv GetVertexAttribiv}. + * + * @param index the generic vertex attribute parameter to be queried + * @param pname the symbolic name of the vertex attribute parameter to be queried + * @param params returns the requested data + * + * @see Reference Page + */ + public static void glGetVertexAttribfv(@NativeType("GLuint") int index, @NativeType("GLenum") int pname, @NativeType("GLfloat *") FloatBuffer params) { + GL20C.glGetVertexAttribfv(index, pname, params); + } + + // --- [ glGetVertexAttribdv ] --- + + /** Unsafe version of: {@link #glGetVertexAttribdv GetVertexAttribdv} */ + public static void nglGetVertexAttribdv(int index, int pname, long params) { + GL20C.nglGetVertexAttribdv(index, pname, params); + } + + /** + * Double version of {@link #glGetVertexAttribiv GetVertexAttribiv}. + * + * @param index the generic vertex attribute parameter to be queried + * @param pname the symbolic name of the vertex attribute parameter to be queried + * @param params returns the requested data + * + * @see Reference Page + */ + public static void glGetVertexAttribdv(@NativeType("GLuint") int index, @NativeType("GLenum") int pname, @NativeType("GLdouble *") DoubleBuffer params) { + GL20C.glGetVertexAttribdv(index, pname, params); + } + + // --- [ glGetVertexAttribPointerv ] --- + + /** Unsafe version of: {@link #glGetVertexAttribPointerv GetVertexAttribPointerv} */ + public static void nglGetVertexAttribPointerv(int index, int pname, long pointer) { + GL20C.nglGetVertexAttribPointerv(index, pname, pointer); + } + + /** + * Returns the address of the specified generic vertex attribute pointer. + * + * @param index the generic vertex attribute parameter to be queried + * @param pname the symbolic name of the generic vertex attribute parameter to be returned. Must be:
{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_POINTER VERTEX_ATTRIB_ARRAY_POINTER}
+ * @param pointer the pointer value + * + * @see Reference Page + */ + public static void glGetVertexAttribPointerv(@NativeType("GLuint") int index, @NativeType("GLenum") int pname, @NativeType("void **") PointerBuffer pointer) { + GL20C.glGetVertexAttribPointerv(index, pname, pointer); + } + + /** + * Returns the address of the specified generic vertex attribute pointer. + * + * @param index the generic vertex attribute parameter to be queried + * @param pname the symbolic name of the generic vertex attribute parameter to be returned. Must be:
{@link GL20C#GL_VERTEX_ATTRIB_ARRAY_POINTER VERTEX_ATTRIB_ARRAY_POINTER}
+ * + * @see Reference Page + */ + @NativeType("void") + public static long glGetVertexAttribPointer(@NativeType("GLuint") int index, @NativeType("GLenum") int pname) { + return GL20C.glGetVertexAttribPointer(index, pname); + } + + // --- [ glDrawBuffers ] --- + + /** + * Unsafe version of: {@link #glDrawBuffers DrawBuffers} + * + * @param n the number of buffers in {@code bufs} + */ + public static void nglDrawBuffers(int n, long bufs) { + GL20C.nglDrawBuffers(n, bufs); + } + + /** + * Specifies a list of color buffers to be drawn into. + * + * @param bufs an array of symbolic constants specifying the buffers into which fragment colors or data values will be written. One of:
{@link GL11#GL_NONE NONE}{@link GL11#GL_FRONT_LEFT FRONT_LEFT}{@link GL11#GL_FRONT_RIGHT FRONT_RIGHT}{@link GL11#GL_BACK_LEFT BACK_LEFT}{@link GL11#GL_BACK_RIGHT BACK_RIGHT}{@link GL30#GL_COLOR_ATTACHMENT0 COLOR_ATTACHMENT0}
GL30.GL_COLOR_ATTACHMENT[1-15]
+ * + * @see Reference Page + */ + public static void glDrawBuffers(@NativeType("GLenum const *") IntBuffer bufs) { + GL20C.glDrawBuffers(bufs); + } + + /** + * Specifies a list of color buffers to be drawn into. + * + * @see Reference Page + */ + public static void glDrawBuffers(@NativeType("GLenum const *") int buf) { + GL20C.glDrawBuffers(buf); + } + + // --- [ glBlendEquationSeparate ] --- + + /** + * Sets the RGB blend equation and the alpha blend equation separately. + * + * @param modeRGB the RGB blend equation, how the red, green, and blue components of the source and destination colors are combined. One of:
{@link GL14#GL_FUNC_ADD FUNC_ADD}{@link GL14#GL_FUNC_SUBTRACT FUNC_SUBTRACT}{@link GL14#GL_FUNC_REVERSE_SUBTRACT FUNC_REVERSE_SUBTRACT}{@link GL14#GL_MIN MIN}{@link GL14#GL_MAX MAX}
+ * @param modeAlpha the alpha blend equation, how the alpha component of the source and destination colors are combined + * + * @see Reference Page + */ + public static void glBlendEquationSeparate(@NativeType("GLenum") int modeRGB, @NativeType("GLenum") int modeAlpha) { + GL20C.glBlendEquationSeparate(modeRGB, modeAlpha); + } + + // --- [ glStencilOpSeparate ] --- + + /** + * Sets front and/or back stencil test actions. + * + * @param face whether front and/or back stencil state is updated. One of:
{@link GL11#GL_FRONT FRONT}{@link GL11#GL_BACK BACK}{@link GL11#GL_FRONT_AND_BACK FRONT_AND_BACK}
+ * @param sfail the action to take when the stencil test fails. The initial value is GL_KEEP. One of:
{@link GL11#GL_KEEP KEEP}{@link GL11#GL_ZERO ZERO}{@link GL11#GL_REPLACE REPLACE}{@link GL11#GL_INCR INCR}{@link GL14#GL_INCR_WRAP INCR_WRAP}{@link GL11#GL_DECR DECR}{@link GL14#GL_DECR_WRAP DECR_WRAP}{@link GL11#GL_INVERT INVERT}
+ * @param dpfail the stencil action when the stencil test passes, but the depth test fails. The initial value is GL_KEEP + * @param dppass the stencil action when both the stencil test and the depth test pass, or when the stencil test passes and either there is no depth buffer or depth + * testing is not enabled. The initial value is GL_KEEP + * + * @see Reference Page + */ + public static void glStencilOpSeparate(@NativeType("GLenum") int face, @NativeType("GLenum") int sfail, @NativeType("GLenum") int dpfail, @NativeType("GLenum") int dppass) { + GL20C.glStencilOpSeparate(face, sfail, dpfail, dppass); + } + + // --- [ glStencilFuncSeparate ] --- + + /** + * Sets front and/or back function and reference value for stencil testing. + * + * @param face whether front and/or back stencil state is updated. One of:
{@link GL11#GL_FRONT FRONT}{@link GL11#GL_BACK BACK}{@link GL11#GL_FRONT_AND_BACK FRONT_AND_BACK}
+ * @param func the test function. The initial value is GL_ALWAYS. One of:
{@link GL11#GL_NEVER NEVER}{@link GL11#GL_LESS LESS}{@link GL11#GL_LEQUAL LEQUAL}{@link GL11#GL_GREATER GREATER}{@link GL11#GL_GEQUAL GEQUAL}{@link GL11#GL_EQUAL EQUAL}{@link GL11#GL_NOTEQUAL NOTEQUAL}{@link GL11#GL_ALWAYS ALWAYS}
+ * @param ref the reference value for the stencil test. {@code ref} is clamped to the range [0, 2n – 1], where {@code n} is the number of bitplanes in the stencil + * buffer. The initial value is 0. + * @param mask a mask that is ANDed with both the reference value and the stored stencil value when the test is done. The initial value is all 1's. + * + * @see Reference Page + */ + public static void glStencilFuncSeparate(@NativeType("GLenum") int face, @NativeType("GLenum") int func, @NativeType("GLint") int ref, @NativeType("GLuint") int mask) { + GL20C.glStencilFuncSeparate(face, func, ref, mask); + } + + // --- [ glStencilMaskSeparate ] --- + + /** + * Controls the front and/or back writing of individual bits in the stencil planes. + * + * @param face whether front and/or back stencil writemask is updated. One of:
{@link GL11#GL_FRONT FRONT}{@link GL11#GL_BACK BACK}{@link GL11#GL_FRONT_AND_BACK FRONT_AND_BACK}
+ * @param mask a bit mask to enable and disable writing of individual bits in the stencil planes. Initially, the mask is all 1's. + * + * @see Reference Page + */ + public static void glStencilMaskSeparate(@NativeType("GLenum") int face, @NativeType("GLuint") int mask) { + GL20C.glStencilMaskSeparate(face, mask); + } + + /** + * Array version of: {@link #glShaderSource ShaderSource} + * + * @see Reference Page + */ + public static void glShaderSource(@NativeType("GLuint") int shader, @NativeType("GLchar const **") PointerBuffer strings, @Nullable @NativeType("GLint const *") int[] length) { + GL20C.glShaderSource(shader, strings, length); + } + + /** + * Array version of: {@link #glUniform1fv Uniform1fv} + * + * @see Reference Page + */ + public static void glUniform1fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + GL20C.glUniform1fv(location, value); + } + + /** + * Array version of: {@link #glUniform2fv Uniform2fv} + * + * @see Reference Page + */ + public static void glUniform2fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + GL20C.glUniform2fv(location, value); + } + + /** + * Array version of: {@link #glUniform3fv Uniform3fv} + * + * @see Reference Page + */ + public static void glUniform3fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + GL20C.glUniform3fv(location, value); + } + + /** + * Array version of: {@link #glUniform4fv Uniform4fv} + * + * @see Reference Page + */ + public static void glUniform4fv(@NativeType("GLint") int location, @NativeType("GLfloat const *") float[] value) { + GL20C.glUniform4fv(location, value); + } + + /** + * Array version of: {@link #glUniform1iv Uniform1iv} + * + * @see Reference Page + */ + public static void glUniform1iv(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + GL20C.glUniform1iv(location, value); + } + + /** + * Array version of: {@link #glUniform2iv Uniform2iv} + * + * @see Reference Page + */ + public static void glUniform2iv(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + GL20C.glUniform2iv(location, value); + } + + /** + * Array version of: {@link #glUniform3iv Uniform3iv} + * + * @see Reference Page + */ + public static void glUniform3iv(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + GL20C.glUniform3iv(location, value); + } + + /** + * Array version of: {@link #glUniform4iv Uniform4iv} + * + * @see Reference Page + */ + public static void glUniform4iv(@NativeType("GLint") int location, @NativeType("GLint const *") int[] value) { + GL20C.glUniform4iv(location, value); + } + + /** + * Array version of: {@link #glUniformMatrix2fv UniformMatrix2fv} + * + * @see Reference Page + */ + public static void glUniformMatrix2fv(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") float[] value) { + GL20C.glUniformMatrix2fv(location, transpose, value); + } + + /** + * Array version of: {@link #glUniformMatrix3fv UniformMatrix3fv} + * + * @see Reference Page + */ + public static void glUniformMatrix3fv(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") float[] value) { + GL20C.glUniformMatrix3fv(location, transpose, value); + } + + /** + * Array version of: {@link #glUniformMatrix4fv UniformMatrix4fv} + * + * @see Reference Page + */ + public static void glUniformMatrix4fv(@NativeType("GLint") int location, @NativeType("GLboolean") boolean transpose, @NativeType("GLfloat const *") float[] value) { + GL20C.glUniformMatrix4fv(location, transpose, value); + } + + /** + * Array version of: {@link #glGetShaderiv GetShaderiv} + * + * @see Reference Page + */ + public static void glGetShaderiv(@NativeType("GLuint") int shader, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL20C.glGetShaderiv(shader, pname, params); + } + + /** + * Array version of: {@link #glGetProgramiv GetProgramiv} + * + * @see Reference Page + */ + public static void glGetProgramiv(@NativeType("GLuint") int program, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL20C.glGetProgramiv(program, pname, params); + } + + /** + * Array version of: {@link #glGetShaderInfoLog GetShaderInfoLog} + * + * @see Reference Page + */ + public static void glGetShaderInfoLog(@NativeType("GLuint") int shader, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLchar *") ByteBuffer infoLog) { + GL20C.glGetShaderInfoLog(shader, length, infoLog); + } + + /** + * Array version of: {@link #glGetProgramInfoLog GetProgramInfoLog} + * + * @see Reference Page + */ + public static void glGetProgramInfoLog(@NativeType("GLuint") int program, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLchar *") ByteBuffer infoLog) { + GL20C.glGetProgramInfoLog(program, length, infoLog); + } + + /** + * Array version of: {@link #glGetAttachedShaders GetAttachedShaders} + * + * @see Reference Page + */ + public static void glGetAttachedShaders(@NativeType("GLuint") int program, @Nullable @NativeType("GLsizei *") int[] count, @NativeType("GLuint *") int[] shaders) { + GL20C.glGetAttachedShaders(program, count, shaders); + } + + /** + * Array version of: {@link #glGetActiveUniform GetActiveUniform} + * + * @see Reference Page + */ + public static void glGetActiveUniform(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLint *") int[] size, @NativeType("GLenum *") int[] type, @NativeType("GLchar *") ByteBuffer name) { + GL20C.glGetActiveUniform(program, index, length, size, type, name); + } + + /** + * Array version of: {@link #glGetUniformfv GetUniformfv} + * + * @see Reference Page + */ + public static void glGetUniformfv(@NativeType("GLuint") int program, @NativeType("GLint") int location, @NativeType("GLfloat *") float[] params) { + GL20C.glGetUniformfv(program, location, params); + } + + /** + * Array version of: {@link #glGetUniformiv GetUniformiv} + * + * @see Reference Page + */ + public static void glGetUniformiv(@NativeType("GLuint") int program, @NativeType("GLint") int location, @NativeType("GLint *") int[] params) { + GL20C.glGetUniformiv(program, location, params); + } + + /** + * Array version of: {@link #glGetShaderSource GetShaderSource} + * + * @see Reference Page + */ + public static void glGetShaderSource(@NativeType("GLuint") int shader, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLchar *") ByteBuffer source) { + GL20C.glGetShaderSource(shader, length, source); + } + + /** + * Array version of: {@link #glVertexAttrib1fv VertexAttrib1fv} + * + * @see Reference Page + */ + public static void glVertexAttrib1fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") float[] v) { + GL20C.glVertexAttrib1fv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib1sv VertexAttrib1sv} + * + * @see Reference Page + */ + public static void glVertexAttrib1sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") short[] v) { + GL20C.glVertexAttrib1sv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib1dv VertexAttrib1dv} + * + * @see Reference Page + */ + public static void glVertexAttrib1dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") double[] v) { + GL20C.glVertexAttrib1dv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib2fv VertexAttrib2fv} + * + * @see Reference Page + */ + public static void glVertexAttrib2fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") float[] v) { + GL20C.glVertexAttrib2fv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib2sv VertexAttrib2sv} + * + * @see Reference Page + */ + public static void glVertexAttrib2sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") short[] v) { + GL20C.glVertexAttrib2sv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib2dv VertexAttrib2dv} + * + * @see Reference Page + */ + public static void glVertexAttrib2dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") double[] v) { + GL20C.glVertexAttrib2dv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib3fv VertexAttrib3fv} + * + * @see Reference Page + */ + public static void glVertexAttrib3fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") float[] v) { + GL20C.glVertexAttrib3fv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib3sv VertexAttrib3sv} + * + * @see Reference Page + */ + public static void glVertexAttrib3sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") short[] v) { + GL20C.glVertexAttrib3sv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib3dv VertexAttrib3dv} + * + * @see Reference Page + */ + public static void glVertexAttrib3dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") double[] v) { + GL20C.glVertexAttrib3dv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4fv VertexAttrib4fv} + * + * @see Reference Page + */ + public static void glVertexAttrib4fv(@NativeType("GLuint") int index, @NativeType("GLfloat const *") float[] v) { + GL20C.glVertexAttrib4fv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4sv VertexAttrib4sv} + * + * @see Reference Page + */ + public static void glVertexAttrib4sv(@NativeType("GLuint") int index, @NativeType("GLshort const *") short[] v) { + GL20C.glVertexAttrib4sv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4dv VertexAttrib4dv} + * + * @see Reference Page + */ + public static void glVertexAttrib4dv(@NativeType("GLuint") int index, @NativeType("GLdouble const *") double[] v) { + GL20C.glVertexAttrib4dv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4iv VertexAttrib4iv} + * + * @see Reference Page + */ + public static void glVertexAttrib4iv(@NativeType("GLuint") int index, @NativeType("GLint const *") int[] v) { + GL20C.glVertexAttrib4iv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4usv VertexAttrib4usv} + * + * @see Reference Page + */ + public static void glVertexAttrib4usv(@NativeType("GLuint") int index, @NativeType("GLushort const *") short[] v) { + GL20C.glVertexAttrib4usv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4uiv VertexAttrib4uiv} + * + * @see Reference Page + */ + public static void glVertexAttrib4uiv(@NativeType("GLuint") int index, @NativeType("GLuint const *") int[] v) { + GL20C.glVertexAttrib4uiv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4Nsv VertexAttrib4Nsv} + * + * @see Reference Page + */ + public static void glVertexAttrib4Nsv(@NativeType("GLuint") int index, @NativeType("GLshort const *") short[] v) { + GL20C.glVertexAttrib4Nsv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4Niv VertexAttrib4Niv} + * + * @see Reference Page + */ + public static void glVertexAttrib4Niv(@NativeType("GLuint") int index, @NativeType("GLint const *") int[] v) { + GL20C.glVertexAttrib4Niv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4Nusv VertexAttrib4Nusv} + * + * @see Reference Page + */ + public static void glVertexAttrib4Nusv(@NativeType("GLuint") int index, @NativeType("GLushort const *") short[] v) { + GL20C.glVertexAttrib4Nusv(index, v); + } + + /** + * Array version of: {@link #glVertexAttrib4Nuiv VertexAttrib4Nuiv} + * + * @see Reference Page + */ + public static void glVertexAttrib4Nuiv(@NativeType("GLuint") int index, @NativeType("GLuint const *") int[] v) { + GL20C.glVertexAttrib4Nuiv(index, v); + } + + /** + * Array version of: {@link #glGetActiveAttrib GetActiveAttrib} + * + * @see Reference Page + */ + public static void glGetActiveAttrib(@NativeType("GLuint") int program, @NativeType("GLuint") int index, @Nullable @NativeType("GLsizei *") int[] length, @NativeType("GLint *") int[] size, @NativeType("GLenum *") int[] type, @NativeType("GLchar *") ByteBuffer name) { + GL20C.glGetActiveAttrib(program, index, length, size, type, name); + } + + /** + * Array version of: {@link #glGetVertexAttribiv GetVertexAttribiv} + * + * @see Reference Page + */ + public static void glGetVertexAttribiv(@NativeType("GLuint") int index, @NativeType("GLenum") int pname, @NativeType("GLint *") int[] params) { + GL20C.glGetVertexAttribiv(index, pname, params); + } + + /** + * Array version of: {@link #glGetVertexAttribfv GetVertexAttribfv} + * + * @see Reference Page + */ + public static void glGetVertexAttribfv(@NativeType("GLuint") int index, @NativeType("GLenum") int pname, @NativeType("GLfloat *") float[] params) { + GL20C.glGetVertexAttribfv(index, pname, params); + } + + /** + * Array version of: {@link #glGetVertexAttribdv GetVertexAttribdv} + * + * @see Reference Page + */ + public static void glGetVertexAttribdv(@NativeType("GLuint") int index, @NativeType("GLenum") int pname, @NativeType("GLdouble *") double[] params) { + GL20C.glGetVertexAttribdv(index, pname, params); + } + + /** + * Array version of: {@link #glDrawBuffers DrawBuffers} + * + * @see Reference Page + */ + public static void glDrawBuffers(@NativeType("GLenum const *") int[] bufs) { + GL20C.glDrawBuffers(bufs); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLContext.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLContext.java new file mode 100644 index 000000000..d68aac1ed --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLContext.java @@ -0,0 +1,15 @@ +package org.lwjgl.opengl; + + +public class GLContext { + + private static ContextCapabilities contextCapabilities = new ContextCapabilities(); + + public static GLContext createFromCurrent() { + return new GLContext(); + } + + public static ContextCapabilities getCapabilities() { + return contextCapabilities; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLSync.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLSync.java new file mode 100644 index 000000000..04e11dd20 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLSync.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.PointerWrapperAbstract; + +/** + * This class is a wrapper around a GLsync pointer. + * + * @author spasi + */ +public final class GLSync extends PointerWrapperAbstract { + + GLSync(final long sync) { + super(sync); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GlobalLock.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GlobalLock.java new file mode 100644 index 000000000..0dc7c5eec --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GlobalLock.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * This class contains the global lock that LWJGL will use to + * synchronize access to Display. + */ +final class GlobalLock { + static final Object lock = new Object(); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/InputImplementation.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/InputImplementation.java new file mode 100644 index 000000000..3f7de2c93 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/InputImplementation.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * This is the input implementation interface. Mouse and Keyboard delegates + * to implementors of this interface. There is one InputImplementation + * for each supported platform. + * @author elias_naur + */ + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.LWJGLException; + +public interface InputImplementation { + /* + * Mouse methods + */ + /** Query of wheel support */ + boolean hasWheel(); + + /** Query of button count */ + int getButtonCount(); + + /** + * Method to create the mouse. + */ + void createMouse() throws LWJGLException; + + /** + * Method the destroy the mouse + */ + void destroyMouse(); + + /** + * Method to poll the mouse + */ + void pollMouse(IntBuffer coord_buffer, ByteBuffer buttons); + + /** + * Method to read the keyboard buffer + */ + void readMouse(ByteBuffer buffer); + + void grabMouse(boolean grab); + + /** + * Function to determine native cursor support + */ + int getNativeCursorCapabilities(); + + /** Method to set the native cursor position */ + void setCursorPosition(int x, int y); + + /** Method to set the native cursor */ + void setNativeCursor(Object handle) throws LWJGLException; + + /** Method returning the minimum cursor size */ + int getMinCursorSize(); + + /** Method returning the maximum cursor size */ + int getMaxCursorSize(); + + /* + * Keyboard methods + */ + + /** + * Method to create the keyboard + */ + void createKeyboard() throws LWJGLException; + + /** + * Method to destroy the keyboard + */ + void destroyKeyboard(); + + /** + * Method to poll the keyboard. + * + * @param keyDownBuffer the address of a 256-byte buffer to place + * key states in. + */ + void pollKeyboard(ByteBuffer keyDownBuffer); + + /** + * Method to read the keyboard buffer + */ + void readKeyboard(ByteBuffer buffer); + +// int isStateKeySet(int key); + + /** Native cursor handles */ + Object createCursor(int width, int height, int xHotspot, int yHotspot, int numImages, IntBuffer images, IntBuffer delays) throws LWJGLException; + + void destroyCursor(Object cursor_handle); + + int getWidth(); + + int getHeight(); + + boolean isInsideWindow(); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/OpenGLException.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/OpenGLException.java new file mode 100644 index 000000000..29fec005f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/OpenGLException.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + *

+ * Thrown by the debug build library of the LWJGL if any OpenGL operation causes an error. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ +public class OpenGLException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** Constructor for OpenGLException. */ + public OpenGLException(int gl_error_code) { + this(createErrorMessage(gl_error_code)); + } + + private static String createErrorMessage(int gl_error_code) { + String error_string = Util.translateGLErrorString(gl_error_code); + return error_string + " (" + gl_error_code + ")"; + } + + /** Constructor for OpenGLException. */ + public OpenGLException() { + super(); + } + + /** + * Constructor for OpenGLException. + * + * @param message + */ + public OpenGLException(String message) { + super(message); + } + + /** + * Constructor for OpenGLException. + * + * @param message + * @param cause + */ + public OpenGLException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor for OpenGLException. + * + * @param cause + */ + public OpenGLException(Throwable cause) { + super(cause); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Pbuffer.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Pbuffer.java new file mode 100644 index 000000000..89aa09ed0 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Pbuffer.java @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.Sys; + +/** + *

+ * Pbuffer encapsulates an OpenGL pbuffer. + *

+ * + * This class is thread-safe. + * + * @author elias_naur + * @version $Revision$ + * $Id$ + */ +public final class Pbuffer extends DrawableGL { + /** + * Indicates that Pbuffers can be created. + */ + public static final int PBUFFER_SUPPORTED = 0;// mark as not supported 1 << 0; + + /** + * Indicates that Pbuffers can be used as render-textures. + */ + public static final int RENDER_TEXTURE_SUPPORTED = 1 << 1; + + /** + * Indicates that Pbuffers can be used as non-power-of-two render-textures. + */ + public static final int RENDER_TEXTURE_RECTANGLE_SUPPORTED = 1 << 2; + + /** + * Indicates that Pbuffers can be used as depth render-textures. + */ + public static final int RENDER_DEPTH_TEXTURE_SUPPORTED = 1 << 3; + + /** + * The render-to-texture mipmap level attribute. + */ + public static final int MIPMAP_LEVEL = RenderTexture.WGL_MIPMAP_LEVEL_ARB; + + /** + * The render-to-texture cube map face attribute. + */ + public static final int CUBE_MAP_FACE = RenderTexture.WGL_CUBE_MAP_FACE_ARB; + + /** + * The render-to-texture cube map positive X face value. + */ + public static final int TEXTURE_CUBE_MAP_POSITIVE_X = RenderTexture.WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + + /** + * The render-to-texture cube map negative X face value. + */ + public static final int TEXTURE_CUBE_MAP_NEGATIVE_X = RenderTexture.WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; + + /** + * The render-to-texture cube map positive Y face value. + */ + public static final int TEXTURE_CUBE_MAP_POSITIVE_Y = RenderTexture.WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; + + /** + * The render-to-texture cube map negative Y face value. + */ + public static final int TEXTURE_CUBE_MAP_NEGATIVE_Y = RenderTexture.WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; + + /** + * The render-to-texture cube map positive Z face value. + */ + public static final int TEXTURE_CUBE_MAP_POSITIVE_Z = RenderTexture.WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; + + /** + * The render-to-texture cube map negative Z face value. + */ + public static final int TEXTURE_CUBE_MAP_NEGATIVE_Z = RenderTexture.WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; + + /** + * The Pbuffer front left buffer. + */ + public static final int FRONT_LEFT_BUFFER = RenderTexture.WGL_FRONT_LEFT_ARB; + + /** + * The Pbuffer front right buffer. + */ + public static final int FRONT_RIGHT_BUFFER = RenderTexture.WGL_FRONT_RIGHT_ARB; + + /** + * The Pbuffer back left buffer. + */ + public static final int BACK_LEFT_BUFFER = RenderTexture.WGL_BACK_LEFT_ARB; + + /** + * The Pbuffer back right buffer. + */ + public static final int BACK_RIGHT_BUFFER = RenderTexture.WGL_BACK_RIGHT_ARB; + + /** + * The Pbuffer depth buffer. + */ + public static final int DEPTH_BUFFER = RenderTexture.WGL_DEPTH_COMPONENT_NV; + + /** + * Width + */ + private final int width; + + /** + * Height + */ + private final int height; + + static { + Sys.initialize(); + } + + /** + * Create an instance of a Pbuffer with a unique OpenGL context. The buffer is single-buffered. + *

+ * NOTE: The Pbuffer will have its own context that shares display lists and textures with shared_context, + * or, if shared_context is null, the Display context if it is created. The Pbuffer + * will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa. + *

+ * + * @param width Pbuffer width + * @param height Pbuffer height + * @param pixel_format Minimum Pbuffer context properties + * @param shared_drawable If non-null the Pbuffer will share display lists and textures with it. Otherwise, the Pbuffer will share + * with the Display context (if created). + */ + public Pbuffer(int width, int height, PixelFormat pixel_format, Drawable shared_drawable) throws LWJGLException { + this(width, height, pixel_format, null, shared_drawable); + } + + /** + * Create an instance of a Pbuffer with a unique OpenGL context. The buffer is single-buffered. + *

+ * NOTE: The Pbuffer will have its own context that shares display lists and textures with shared_context, + * or, if shared_context is null, the Display context if it is created. The Pbuffer + * will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa. + *

+ * The renderTexture parameter defines the necessary state for enabling render-to-texture. When this parameter is null, + * render-to-texture is not available. Before using render-to-texture, the Pbuffer capabilities must be queried to ensure that + * it is supported. Currently only windows platform can support this feature, so it is recommended that EXT_framebuffer_object + * or similar is used if available, for maximum portability. + *

+ * + * @param width Pbuffer width + * @param height Pbuffer height + * @param pixel_format Minimum Pbuffer context properties + * @param renderTexture + * @param shared_drawable If non-null the Pbuffer will share display lists and textures with it. Otherwise, the Pbuffer will share + * with the Display context (if created). + */ + public Pbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture, Drawable shared_drawable) throws LWJGLException { + this(width, height, pixel_format, renderTexture, shared_drawable, null); + } + + /** + * Create an instance of a Pbuffer with a unique OpenGL context. The buffer is single-buffered. + *

+ * NOTE: The Pbuffer will have its own context that shares display lists and textures with shared_context, + * or, if shared_context is null, the Display context if it is created. The Pbuffer + * will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa. + *

+ * The renderTexture parameter defines the necessary state for enabling render-to-texture. When this parameter is null, + * render-to-texture is not available. Before using render-to-texture, the Pbuffer capabilities must be queried to ensure that + * it is supported. Currently only windows platform can support this feature, so it is recommended that EXT_framebuffer_object + * or similar is used if available, for maximum portability. + *

+ * + * @param width Pbuffer width + * @param height Pbuffer height + * @param pixel_format Minimum Pbuffer context properties + * @param renderTexture + * @param shared_drawable If non-null the Pbuffer will share display lists and textures with it. Otherwise, the Pbuffer will share + * with the Display context (if created). + * @param attribs The ContextAttribs to use when creating the context. (optional, may be null) + */ + public Pbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture, Drawable shared_drawable, ContextAttribs attribs) throws LWJGLException { + if (pixel_format == null) + throw new NullPointerException("Pixel format must be non-null"); + this.width = width; + this.height = height; + this.peer_info = createPbuffer(width, height, pixel_format, attribs, renderTexture); + Context shared_context = null; + if ( shared_drawable == null ) + shared_drawable = Display.getDrawable(); // May be null + if (shared_drawable != null) + shared_context = ((DrawableLWJGL)shared_drawable).getContext(); + //this.context = new ContextGL(peer_info, attribs, (ContextGL)shared_context); + } + + private static PeerInfo createPbuffer(int width, int height, PixelFormat pixel_format, ContextAttribs attribs, RenderTexture renderTexture) throws LWJGLException { + if ( renderTexture == null ) { + // Though null is a perfectly valid argument, Matrox Parhelia drivers expect + // a 0 terminated list, or else they crash. Supplying NULL or 0, should + // cause the drivers to use default settings + IntBuffer defaultAttribs = BufferUtils.createIntBuffer(1); + return Display.getImplementation().createPbuffer(width, height, pixel_format, attribs, null, defaultAttribs); + } else + return Display.getImplementation().createPbuffer(width, height, pixel_format, attribs, + renderTexture.pixelFormatCaps, + renderTexture.pBufferAttribs); + } + + /** + * Method to test for validity of the buffer. If this function returns true, the buffer contents is lost. The buffer can still + * be used, but the results are undefined. The application is expected to release the buffer if needed, destroy it and recreate + * a new buffer. + * + * @return true if the buffer is lost and destroyed, false if the buffer is valid. + */ + public synchronized boolean isBufferLost() { + checkDestroyed(); + return Display.getImplementation().isBufferLost(peer_info); + } + + /** + * Gets the Pbuffer capabilities. + * + * @return a bitmask of Pbuffer capabilities. + */ + public static int getCapabilities() { + return Display.getImplementation().getPbufferCapabilities(); + } + + // ----------------------------------------------------------------------------------------- + // ------------------------------- Render-to-Texture Methods ------------------------------- + // ----------------------------------------------------------------------------------------- + + /** + * Sets a render-to-texture attribute. + *

+ * The attrib parameter can be one of MIPMAP_LEVEL and CUBE_MAP_FACE. When the attrib parameter is CUBE_MAP_FACE then the value + * parameter can be on of the following: + *

+ * TEXTURE_CUBE_MAP_POSITIVE_X TEXTURE_CUBE_MAP_NEGATIVE_X TEXTURE_CUBE_MAP_POSITIVE_Y TEXTURE_CUBE_MAP_NEGATIVE_Y + * TEXTURE_CUBE_MAP_POSITIVE_Z TEXTURE_CUBE_MAP_NEGATIVE_Z + * + * @param attrib + * @param value + */ + public synchronized void setAttrib(int attrib, int value) { + checkDestroyed(); + Display.getImplementation().setPbufferAttrib(peer_info, attrib, value); + } + + /** + * Binds the currently bound texture to the buffer specified. The buffer can be one of the following: + *

+ * FRONT_LEFT_BUFFER FRONT_RIGHT_BUFFER BACK_LEFT_BUFFER BACK_RIGHT_BUFFER DEPTH_BUFFER + * + * @param buffer + */ + public synchronized void bindTexImage(int buffer) { + checkDestroyed(); + Display.getImplementation().bindTexImageToPbuffer(peer_info, buffer); + } + + /** + * Releases the currently bound texture from the buffer specified. + * + * @param buffer + */ + public synchronized void releaseTexImage(int buffer) { + checkDestroyed(); + Display.getImplementation().releaseTexImageFromPbuffer(peer_info, buffer); + } + + /** + * @return Returns the height. + */ + public synchronized int getHeight() { + checkDestroyed(); + return height; + } + + /** + * @return Returns the width. + */ + public synchronized int getWidth() { + checkDestroyed(); + return width; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PeerInfo.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PeerInfo.java new file mode 100644 index 000000000..95e04fae1 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PeerInfo.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import java.nio.ByteBuffer; + +import org.lwjgl.LWJGLException; +import org.lwjgl.LWJGLUtil; + +/** + * + * @author elias_naur + * @version $Revision$ + * $Id$ + */ +abstract class PeerInfo { + private final ByteBuffer handle; + private Thread locking_thread; // Thread that has locked this PeerInfo + private int lock_count; + + protected PeerInfo(ByteBuffer handle) { + this.handle = handle; + } + + private void lockAndInitHandle() throws LWJGLException { + doLockAndInitHandle(); + } + + public final synchronized void unlock() throws LWJGLException { + if (lock_count <= 0) + throw new IllegalStateException("PeerInfo not locked!"); + if (Thread.currentThread() != locking_thread) + throw new IllegalStateException("PeerInfo already locked by " + locking_thread); + lock_count--; + if (lock_count == 0) { + doUnlock(); + locking_thread = null; + notify(); + } + } + + protected abstract void doLockAndInitHandle() throws LWJGLException; + protected abstract void doUnlock() throws LWJGLException; + + public final synchronized ByteBuffer lockAndGetHandle() throws LWJGLException { + Thread this_thread = Thread.currentThread(); + while (locking_thread != null && locking_thread != this_thread) { + try { + wait(); + } catch (InterruptedException e) { + LWJGLUtil.log("Interrupted while waiting for PeerInfo lock: " + e); + } + } + if (lock_count == 0) { + locking_thread = this_thread; + doLockAndInitHandle(); + } + lock_count++; + return getHandle(); + } + + protected final ByteBuffer getHandle() { + return handle; + } + + public void destroy() { + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormat.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormat.java new file mode 100644 index 000000000..179638e4c --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormat.java @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * This class describes pixel format properties for an OpenGL context. Instances + * of this class is used as arguments to Display.create(), Pbuffer.create() and + * AWTGLCanvas, to indicate minimum required properties. + *

+ * Instants of this class are immutable. An example of the expected way to set + * the PixelFormat property values is the following: + * PixelFormat pf = new PixelFormat().withDepthBits(24).withSamples(4).withSRGB(true); + *

+ * WARNING: Some pixel formats are known to cause troubles on certain buggy drivers. + * Example: Under Windows, specifying samples != 0 will enable the ARB + * pixel format selection path, which could trigger a crash. + * + * @author elias_naur@sourceforge.net + * @version $Revision$ + */ +public final class PixelFormat implements PixelFormatLWJGL { + + /** + * The number of bits per pixel, exluding alpha. + * This parameter is ignored in Display.create(). + */ + private int bpp; + /** The number of alpha bits. */ + private int alpha; + /** The number of depth buffer bits */ + private int depth; + /** The number of stencil bits */ + private int stencil; + /** + * The number of samples to use in anti-aliasing. + * 0 means that anti-aliasing is disabled. + */ + private int samples; + /** + * The number of COLOR_SAMPLES_NV to use for Coverage Sample Anti-aliasing (CSAA). + * When this number is greater than 0, the {@code samples} property will be treated + * as if it were the COVERAGE_SAMPLES_NV property. + *

+ * This property is currently a no-op for the MacOS implementation. + */ + private int colorSamples; + /** The number of auxiliary buffers */ + private int num_aux_buffers; + /** The number of bits per pixel in the accumulation buffer */ + private int accum_bpp; + /** The number of alpha bits in the accumulation buffer */ + private int accum_alpha; + /** Whether this format requires a stereo buffer */ + private boolean stereo; + /** Whether this format specifies a floating point format */ + private boolean floating_point; + /** + * Whether this format specifies a packed floating point format (32 bit unsigned - R11F_G11F_B10F) + * This property is currently a no-op for the MacOS implementation. + */ + private boolean floating_point_packed; + /** + * Whether this format specifies an sRGB format + * This property is currently a no-op for the MacOS implementation. + */ + private boolean sRGB; + + /** + * Default pixel format is minimum 8 bits depth, and no alpha + * nor stencil requirements. + */ + public PixelFormat() { + this(0, 8, 0); + } + + public PixelFormat(int alpha, int depth, int stencil) { + this(alpha, depth, stencil, 0); + } + + public PixelFormat(int alpha, int depth, int stencil, int samples) { + this(0, alpha, depth, stencil, samples); + } + + public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples) { + this(bpp, alpha, depth, stencil, samples, 0, 0, 0, false); + } + + public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo) { + this(bpp, alpha, depth, stencil, samples, num_aux_buffers, accum_bpp, accum_alpha, stereo, false); + } + + public PixelFormat(int bpp, int alpha, int depth, int stencil, int samples, int num_aux_buffers, int accum_bpp, int accum_alpha, boolean stereo, boolean floating_point) { + this.bpp = bpp; + this.alpha = alpha; + this.depth = depth; + this.stencil = stencil; + + this.samples = samples; + + this.num_aux_buffers = num_aux_buffers; + + this.accum_bpp = accum_bpp; + this.accum_alpha = accum_alpha; + + this.stereo = stereo; + + this.floating_point = floating_point; + this.floating_point_packed = false; + this.sRGB = false; + } + + private PixelFormat(final PixelFormat pf) { + this.bpp = pf.bpp; + this.alpha = pf.alpha; + this.depth = pf.depth; + this.stencil = pf.stencil; + + this.samples = pf.samples; + this.colorSamples = pf.colorSamples; + + this.num_aux_buffers = pf.num_aux_buffers; + + this.accum_bpp = pf.accum_bpp; + this.accum_alpha = pf.accum_alpha; + + this.stereo = pf.stereo; + + this.floating_point = pf.floating_point; + this.floating_point_packed = pf.floating_point_packed; + this.sRGB = pf.sRGB; + } + + public int getBitsPerPixel() { + return bpp; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new bits per pixel value. + * + * @param bpp the new bits per pixel value. + * + * @return the new PixelFormat + */ + public PixelFormat withBitsPerPixel(final int bpp) { + if ( bpp < 0 ) + throw new IllegalArgumentException("Invalid number of bits per pixel specified: " + bpp); + + final PixelFormat pf = new PixelFormat(this); + pf.bpp = bpp; + return pf; + } + + public int getAlphaBits() { + return alpha; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new alpha bits value. + * + * @param alpha the new alpha bits value. + * + * @return the new PixelFormat + */ + public PixelFormat withAlphaBits(final int alpha) { + if ( alpha < 0 ) + throw new IllegalArgumentException("Invalid number of alpha bits specified: " + alpha); + + final PixelFormat pf = new PixelFormat(this); + pf.alpha = alpha; + return pf; + } + + public int getDepthBits() { + return depth; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new depth bits value. + * + * @param depth the new depth bits value. + * + * @return the new PixelFormat + */ + public PixelFormat withDepthBits(final int depth) { + if ( depth < 0 ) + throw new IllegalArgumentException("Invalid number of depth bits specified: " + depth); + + final PixelFormat pf = new PixelFormat(this); + pf.depth = depth; + return pf; + } + + public int getStencilBits() { + return stencil; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new stencil bits value. + * + * @param stencil the new stencil bits value. + * + * @return the new PixelFormat + */ + public PixelFormat withStencilBits(final int stencil) { + if ( stencil < 0 ) + throw new IllegalArgumentException("Invalid number of stencil bits specified: " + stencil); + + final PixelFormat pf = new PixelFormat(this); + pf.stencil = stencil; + return pf; + } + + public int getSamples() { + return samples; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new samples value. + * + * @param samples the new samples value. + * + * @return the new PixelFormat + */ + public PixelFormat withSamples(final int samples) { + if ( samples < 0 ) + throw new IllegalArgumentException("Invalid number of samples specified: " + samples); + + final PixelFormat pf = new PixelFormat(this); + pf.samples = samples; + return pf; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new color samples values. + * A value greater than 0 is valid only if the {@code samples} property is also greater than 0. Additionally, the + * color samples value needs to be lower than or equal to the {@code samples} property. + * + * @param colorSamples the new color samples value. + * + * @return the new PixelFormat + */ + public PixelFormat withCoverageSamples(final int colorSamples) { + return withCoverageSamples(colorSamples, samples); + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new color samples + * and coverage samples values. + * + * @param colorSamples the new color samples value. This value must be lower than or equal to the coverage samples value. + * @param coverageSamples the new coverage samples value. + * + * @return the new PixelFormat + */ + public PixelFormat withCoverageSamples(final int colorSamples, final int coverageSamples) { + if ( coverageSamples < 0 || colorSamples < 0 || (coverageSamples == 0 && 0 < colorSamples) || coverageSamples < colorSamples ) + throw new IllegalArgumentException("Invalid number of coverage samples specified: " + coverageSamples + " - " + colorSamples); + + final PixelFormat pf = new PixelFormat(this); + pf.samples = coverageSamples; + pf.colorSamples = colorSamples; + return pf; + } + + public int getAuxBuffers() { + return num_aux_buffers; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new auxiliary buffers value. + * + * @param num_aux_buffers the new auxiliary buffers value. + * + * @return the new PixelFormat + */ + public PixelFormat withAuxBuffers(final int num_aux_buffers) { + if ( num_aux_buffers < 0 ) + throw new IllegalArgumentException("Invalid number of auxiliary buffers specified: " + num_aux_buffers); + + final PixelFormat pf = new PixelFormat(this); + pf.num_aux_buffers = num_aux_buffers; + return pf; + } + + public int getAccumulationBitsPerPixel() { + return accum_bpp; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new bits per pixel in the accumulation buffer value. + * + * @param accum_bpp the new bits per pixel in the accumulation buffer value. + * + * @return the new PixelFormat + */ + public PixelFormat withAccumulationBitsPerPixel(final int accum_bpp) { + if ( accum_bpp < 0 ) + throw new IllegalArgumentException("Invalid number of bits per pixel in the accumulation buffer specified: " + accum_bpp); + + final PixelFormat pf = new PixelFormat(this); + pf.accum_bpp = accum_bpp; + return pf; + } + + public int getAccumulationAlpha() { + return accum_alpha; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new alpha bits in the accumulation buffer value. + * + * @param accum_alpha the new alpha bits in the accumulation buffer value. + * + * @return the new PixelFormat + */ + public PixelFormat withAccumulationAlpha(final int accum_alpha) { + if ( accum_alpha < 0 ) + throw new IllegalArgumentException("Invalid number of alpha bits in the accumulation buffer specified: " + accum_alpha); + + final PixelFormat pf = new PixelFormat(this); + pf.accum_alpha = accum_alpha; + return pf; + } + + public boolean isStereo() { + return stereo; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new stereo value. + * + * @param stereo the new stereo value. + * + * @return the new PixelFormat + */ + public PixelFormat withStereo(final boolean stereo) { + final PixelFormat pf = new PixelFormat(this); + pf.stereo = stereo; + return pf; + } + + public boolean isFloatingPoint() { + return floating_point; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new floating point value. + * If floating_point is true, floating_point_packed will be reset to false. + * + * @param floating_point the new floating point value. + * + * @return the new PixelFormat + */ + public PixelFormat withFloatingPoint(final boolean floating_point) { + final PixelFormat pf = new PixelFormat(this); + pf.floating_point = floating_point; + if ( floating_point ) + pf.floating_point_packed = false; + return pf; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new packed floating point value. + * If floating_point_packed is true, floating_point will be reset to false. + * + * @param floating_point_packed the new packed floating point value. + * + * @return the new PixelFormat + */ + public PixelFormat withFloatingPointPacked(final boolean floating_point_packed) { + final PixelFormat pf = new PixelFormat(this); + pf.floating_point_packed = floating_point_packed; + if ( floating_point_packed ) + pf.floating_point = false; + return pf; + } + + public boolean isSRGB() { + return sRGB; + } + + /** + * Returns a new PixelFormat object with the same properties as this PixelFormat and the new sRGB value. + * + * @param sRGB the new floating point value. + * + * @return the new PixelFormat + */ + public PixelFormat withSRGB(final boolean sRGB) { + final PixelFormat pf = new PixelFormat(this); + pf.sRGB = sRGB; + return pf; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormatLWJGL.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormatLWJGL.java new file mode 100644 index 000000000..a160d0a3c --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PixelFormatLWJGL.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2002-2011 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +/** + * [INTERNAL USE ONLY] + * + * @author Spasi + */ +public interface PixelFormatLWJGL { + // Marker interface +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/RenderTexture.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/RenderTexture.java new file mode 100644 index 000000000..ed8e3f965 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/RenderTexture.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; + +import static org.lwjgl.opengl.GL11.*; + +/** This class represents the state necessary for render-to-texture. */ +public final class RenderTexture { + + // ---------------------------------------------------------------------------------- + // ----------------------------- WGL_ARB_render_texture ----------------------------- + // ---------------------------------------------------------------------------------- + + /* + Accepted by the parameter of wglGetPixelFormatAttribivARB, + wglGetPixelFormatAttribfvARB, and the and + parameters of wglChoosePixelFormatARB: + */ + private static final int WGL_BIND_TO_TEXTURE_RGB_ARB = 0x2070; + private static final int WGL_BIND_TO_TEXTURE_RGBA_ARB = 0x2071; + + /* + Accepted by the parameter of wglCreatePbufferARB and + by the parameter of wglQueryPbufferARB: + */ + private static final int WGL_TEXTURE_FORMAT_ARB = 0x2072; + private static final int WGL_TEXTURE_TARGET_ARB = 0x2073; + private static final int WGL_MIPMAP_TEXTURE_ARB = 0x2074; + + /* + Accepted as a value in the parameter of + wglCreatePbufferARB and returned in the value parameter of + wglQueryPbufferARB when is WGL_TEXTURE_FORMAT_ARB: + */ + private static final int WGL_TEXTURE_RGB_ARB = 0x2075; + private static final int WGL_TEXTURE_RGBA_ARB = 0x2076; + + /* + Accepted as a value in the parameter of + wglCreatePbufferARB and returned in the value parameter of + wglQueryPbufferARB when is WGL_TEXTURE_TARGET_ARB: + */ + private static final int WGL_TEXTURE_CUBE_MAP_ARB = 0x2078; + private static final int WGL_TEXTURE_1D_ARB = 0x2079; + private static final int WGL_TEXTURE_2D_ARB = 0x207A; + private static final int WGL_NO_TEXTURE_ARB = 0x2077; + + /* + Accepted by the parameter of wglSetPbufferAttribARB and + by the parameter of wglQueryPbufferARB: + */ + static final int WGL_MIPMAP_LEVEL_ARB = 0x207B; + static final int WGL_CUBE_MAP_FACE_ARB = 0x207C; + + /* + Accepted as a value in the parameter of + wglSetPbufferAttribARB and returned in the value parameter of + wglQueryPbufferARB when is WGL_CUBE_MAP_FACE_ARB: + */ + static final int WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 0x207D; + static final int WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 0x207E; + static final int WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 0x207F; + static final int WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 0x2080; + static final int WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 0x2081; + static final int WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 0x2082; + + /* + Accepted by the parameter of wglBindTexImageARB and + wglReleaseTexImageARB: + */ + static final int WGL_FRONT_LEFT_ARB = 0x2083; + static final int WGL_FRONT_RIGHT_ARB = 0x2084; + static final int WGL_BACK_LEFT_ARB = 0x2085; + static final int WGL_BACK_RIGHT_ARB = 0x2086; + + /* + private static final int WGL_AUX0_ARB = 0x2087; + private static final int WGL_AUX1_ARB = 0x2088; + private static final int WGL_AUX2_ARB = 0x2089; + private static final int WGL_AUX3_ARB = 0x208A; + private static final int WGL_AUX4_ARB = 0x208B; + private static final int WGL_AUX5_ARB = 0x208C; + private static final int WGL_AUX6_ARB = 0x208D; + private static final int WGL_AUX7_ARB = 0x208E; + private static final int WGL_AUX8_ARB = 0x208F; + private static final int WGL_AUX9_ARB = 0x2090; + */ + + // ------------------------------------------------------------------------------------------- + // ----------------------------- WGL_NV_render_texture_rectangle ----------------------------- + // ------------------------------------------------------------------------------------------- + + /* + Accepted by the parameter of wglGetPixelFormatAttribivARB, + wglGetPixelFormatAttribfvARB, and the and + parameters of wglChoosePixelFormatARB: + */ + private static final int WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = 0x20A0; + private static final int WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = 0x20A1; + + /* + Accepted as a value in the parameter of wglCreatePbufferARB + and returned in the value parameter of wglQueryPbufferARB when + is WGL_TEXTURE_TARGET_ARB: + */ + private static final int WGL_TEXTURE_RECTANGLE_NV = 0x20A2; + + // --------------------------------------------------------------------------------------- + // ----------------------------- WGL_NV_render_depth_texture ----------------------------- + // --------------------------------------------------------------------------------------- + + /* + Accepted by the parameter of wglGetPixelFormatAttribivARB, + wglGetPixelFormatAttribfvARB, and the and + parameters of wglChoosePixelFormatARB: + */ + private static final int WGL_BIND_TO_TEXTURE_DEPTH_NV = 0x20A3; + private static final int WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV = 0x20A4; + + /* + Accepted by the parameter of wglCreatePbufferARB and + by the parameter of wglQueryPbufferARB: + */ + private static final int WGL_DEPTH_TEXTURE_FORMAT_NV = 0x20A5; + + /* + Accepted as a value in the parameter of wglCreatePbufferARB + and returned in the value parameter of wglQueryPbufferARB when + is WGL_DEPTH_TEXTURE_FORMAT_NV: + */ + private static final int WGL_TEXTURE_DEPTH_COMPONENT_NV = 0x20A6; + + /* + Accepted by the parameter of wglBindTexImageARB: + */ + static final int WGL_DEPTH_COMPONENT_NV = 0x20A7; + + /** The TEXTURE_1D target. */ + public static final int RENDER_TEXTURE_1D = WGL_TEXTURE_1D_ARB; + + /** The TEXTURE_2D target. */ + public static final int RENDER_TEXTURE_2D = WGL_TEXTURE_2D_ARB; + + /** The TEXTURE_RECTANGLE target. */ + public static final int RENDER_TEXTURE_RECTANGLE = WGL_TEXTURE_RECTANGLE_NV; + + /** The TEXTURE_CUBE_MAP target. */ + public static final int RENDER_TEXTURE_CUBE_MAP = WGL_TEXTURE_CUBE_MAP_ARB; + + IntBuffer pixelFormatCaps; + IntBuffer pBufferAttribs; + + /** + * Creates a RenderTexture object for enabling render-to-texture on a P-buffer. + *

+ * NOTE: Only one of useRGB and useRGBA can be true at the same time. + *

+ * NOTE: useRGB(A) and useDepth can be true at the same time, thus allowing two different render textures. + *

+ * NOTE: The target parameter can be one of the following: + *

+ * RENDER_TEXTURE_1D RENDER_TEXTURE_2D RENDER_TEXTURE_RECTANGLE RENDER_TEXTURE_CUBE_MAP + * + * @param useRGB - When true the P-buffer can be used as an RGB render texture. + * @param useRGBA - When true the P-buffer can be used as an RGBA render texture. + * @param useDepth - When true the P-buffer can be used as a depth render texture. + * @param isRectangle - When true rectangle textures will be allowed on the P-buffer. + * @param target - The texture target of the render texture. + * @param mipmaps - How many mipmap levels to allocate on the P-buffer. + */ + public RenderTexture(boolean useRGB, boolean useRGBA, boolean useDepth, boolean isRectangle, int target, int mipmaps) { + if ( useRGB && useRGBA ) + throw new IllegalArgumentException("A RenderTexture can't be both RGB and RGBA."); + + if ( mipmaps < 0 ) + throw new IllegalArgumentException("The mipmap levels can't be negative."); + + if ( isRectangle && target != RENDER_TEXTURE_RECTANGLE ) + throw new IllegalArgumentException("When the RenderTexture is rectangle the target must be RENDER_TEXTURE_RECTANGLE."); + + pixelFormatCaps = BufferUtils.createIntBuffer(4); + pBufferAttribs = BufferUtils.createIntBuffer(8); + + if ( useRGB ) { + pixelFormatCaps.put(isRectangle ? WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : WGL_BIND_TO_TEXTURE_RGB_ARB); + pixelFormatCaps.put(GL_TRUE); + + pBufferAttribs.put(WGL_TEXTURE_FORMAT_ARB); + pBufferAttribs.put(WGL_TEXTURE_RGB_ARB); + } else if ( useRGBA ) { + pixelFormatCaps.put(isRectangle ? WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV : WGL_BIND_TO_TEXTURE_RGBA_ARB); + pixelFormatCaps.put(GL_TRUE); + + pBufferAttribs.put(WGL_TEXTURE_FORMAT_ARB); + pBufferAttribs.put(WGL_TEXTURE_RGBA_ARB); + } + + if ( useDepth ) { + pixelFormatCaps.put(isRectangle ? WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV : WGL_BIND_TO_TEXTURE_DEPTH_NV); + pixelFormatCaps.put(GL_TRUE); + + pBufferAttribs.put(WGL_DEPTH_TEXTURE_FORMAT_NV); + pBufferAttribs.put(WGL_TEXTURE_DEPTH_COMPONENT_NV); + } + + pBufferAttribs.put(WGL_TEXTURE_TARGET_ARB); + pBufferAttribs.put(target); + + if ( mipmaps != 0 ) { + pBufferAttribs.put(WGL_MIPMAP_TEXTURE_ARB); + pBufferAttribs.put(mipmaps); + } + + pixelFormatCaps.flip(); + pBufferAttribs.flip(); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/SharedDrawable.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/SharedDrawable.java new file mode 100644 index 000000000..ad80f2d71 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/SharedDrawable.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.LWJGLException; + +/** + * @author Spasi + */ + +/** + * A Drawable implementation that shares its context with another Drawable. This is useful + * for background loading of resources. See org.lwjgl.test.opengl.multithread.BackgroundLoad + * for an example. + * + * @author Spasi + */ +public final class SharedDrawable extends DrawableGL { + + public SharedDrawable(final Drawable drawable) throws LWJGLException { + this.context = (ContextGL)((DrawableLWJGL)drawable).createSharedContext(); + } + + public ContextGL createSharedContext() { + return context; + // throw new UnsupportedOperationException(); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Sync.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Sync.java new file mode 100644 index 000000000..f8f7b075e --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Sync.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2002-2012 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import org.lwjgl.Sys; + +/** + * A highly accurate sync method that continually adapts to the system it runs + * on to provide reliable results. + * + * @author Riven + * @author kappaOne + */ +class Sync { + + /** number of nano seconds in a second */ + private static final long NANOS_IN_SECOND = 1000L * 1000L * 1000L; + + /** The time to sleep/yield until the next frame */ + private static long nextFrame = 0; + + /** whether the initialisation code has run */ + private static boolean initialised = false; + + /** + * for calculating the averages the previous sleep/yield times are stored + */ + private static RunningAvg sleepDurations = new RunningAvg(10); + private static RunningAvg yieldDurations = new RunningAvg(10); + + /** + * An accurate sync method that will attempt to run at a constant frame + * rate. It should be called once every frame. + * + * @param fps + * - the desired frame rate, in frames per second + */ + public static void sync(int fps) { + if (fps <= 0) + return; + if (!initialised) + initialise(); + + try { + // sleep until the average sleep time is greater than the time + // remaining till nextFrame + for (long t0 = getTime(), t1; (nextFrame - t0) > sleepDurations.avg(); t0 = t1) { + Thread.sleep(1); + sleepDurations.add((t1 = getTime()) - t0); // update average + // sleep time + } + + // slowly dampen sleep average if too high to avoid yielding too + // much + sleepDurations.dampenForLowResTicker(); + + // yield until the average yield time is greater than the time + // remaining till nextFrame + for (long t0 = getTime(), t1; (nextFrame - t0) > yieldDurations.avg(); t0 = t1) { + Thread.yield(); + yieldDurations.add((t1 = getTime()) - t0); // update average + // yield time + } + } catch (InterruptedException e) { + + } + + // schedule next frame, drop frame(s) if already too late for next frame + nextFrame = Math.max(nextFrame + NANOS_IN_SECOND / fps, getTime()); + } + + /** + * This method will initialise the sync method by setting initial values for + * sleepDurations/yieldDurations and nextFrame. + * + * If running on windows it will start the sleep timer fix. + */ + private static void initialise() { + initialised = true; + + sleepDurations.init(1000 * 1000); + yieldDurations.init((int) (-(getTime() - getTime()) * 1.333)); + + nextFrame = getTime(); + + String osName = System.getProperty("os.name"); + + if (osName.startsWith("Win")) { + // On windows the sleep functions can be highly inaccurate by + // over 10ms making in unusable. However it can be forced to + // be a bit more accurate by running a separate sleeping daemon + // thread. + Thread timerAccuracyThread = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(Long.MAX_VALUE); + } catch (Exception e) { + } + } + }); + + timerAccuracyThread.setName("LWJGL Timer"); + timerAccuracyThread.setDaemon(true); + timerAccuracyThread.start(); + } + } + + /** + * Get the system time in nano seconds + * + * @return will return the current time in nano's + */ + private static long getTime() { + return (Sys.getTime() * NANOS_IN_SECOND) / Sys.getTimerResolution(); + } + + private static class RunningAvg { + private final long[] slots; + private int offset; + + private static final long DAMPEN_THRESHOLD = 10 * 1000L * 1000L; // 10ms + private static final float DAMPEN_FACTOR = 0.9f; // don't change: 0.9f + // is exactly right! + + public RunningAvg(int slotCount) { + this.slots = new long[slotCount]; + this.offset = 0; + } + + public void init(long value) { + while (this.offset < this.slots.length) { + this.slots[this.offset++] = value; + } + } + + public void add(long value) { + this.slots[this.offset++ % this.slots.length] = value; + this.offset %= this.slots.length; + } + + public long avg() { + long sum = 0; + for (int i = 0; i < this.slots.length; i++) { + sum += this.slots[i]; + } + return sum / this.slots.length; + } + + public void dampenForLowResTicker() { + if (this.avg() > DAMPEN_THRESHOLD) { + for (int i = 0; i < this.slots.length; i++) { + this.slots[i] *= DAMPEN_FACTOR; + } + } + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Util.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Util.java new file mode 100644 index 000000000..cc2df2a7d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/Util.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.opengl; + +import static org.lwjgl.opengl.ARBImaging.*; +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL30.*; + +/** + * Simple utility class. + * + * @author cix_foo + * @version $Revision$ + */ + +public final class Util { + + /** No c'tor */ + private Util() { + } + + /** + * Throws OpenGLException if glGetError() returns anything else than + * GL_NO_ERROR + * + */ + public static void checkGLError() throws OpenGLException { + int err = glGetError(); + if (err != GL_NO_ERROR) { + throw new OpenGLException(err); + } + } + + /** + * Translate a GL error code to a String describing the error + */ + public static String translateGLErrorString(int error_code) { + switch (error_code) { + case GL_NO_ERROR: + return "No error"; + case GL_INVALID_ENUM: + return "Invalid enum"; + case GL_INVALID_VALUE: + return "Invalid value"; + case GL_INVALID_OPERATION: + return "Invalid operation"; + case GL_STACK_OVERFLOW: + return "Stack overflow"; + case GL_STACK_UNDERFLOW: + return "Stack underflow"; + case GL_OUT_OF_MEMORY: + return "Out of memory"; + case GL_TABLE_TOO_LARGE: + return "Table too large"; + case GL_INVALID_FRAMEBUFFER_OPERATION: + return "Invalid framebuffer operation"; + default: + return null; + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Color.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Color.java new file mode 100644 index 000000000..8e03aaf09 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Color.java @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; +import java.io.Serializable; +import java.nio.ByteBuffer; + +/** + * A mutable Color class + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public final class Color implements ReadableColor, Serializable, WritableColor { + + static final long serialVersionUID = 1L; + + /** Color components, publicly accessible */ + private byte red, green, blue, alpha; + + /** + * Constructor for Color. + */ + public Color() { + this(0, 0, 0, 255); + } + + /** + * Constructor for Color. Alpha defaults to 255. + */ + public Color(int r, int g, int b) { + this(r, g, b, 255); + } + + /** + * Constructor for Color. Alpha defaults to 255. + */ + public Color(byte r, byte g, byte b) { + this(r, g, b, (byte) 255); + } + + /** + * Constructor for Color. + */ + public Color(int r, int g, int b, int a) { + set(r, g, b, a); + } + + /** + * Constructor for Color. + */ + public Color(byte r, byte g, byte b, byte a) { + set(r, g, b, a); + } + + /** + * Constructor for Color + */ + public Color(ReadableColor c) { + setColor(c); + } + + /** + * Set a color + */ + public void set(int r, int g, int b, int a) { + red = (byte) r; + green = (byte) g; + blue = (byte) b; + alpha = (byte) a; + } + + /** + * Set a color + */ + public void set(byte r, byte g, byte b, byte a) { + this.red = r; + this.green = g; + this.blue = b; + this.alpha = a; + } + + /** + * Set a color + */ + public void set(int r, int g, int b) { + set(r, g, b, 255); + } + + /** + * Set a color + */ + public void set(byte r, byte g, byte b) { + set(r, g, b, (byte) 255); + } + + /** + * Accessor + */ + public int getRed() { + return red & 0xFF; + } + + /** + * Accessor + */ + public int getGreen() { + return green & 0xFF; + } + + /** + * Accessor + */ + public int getBlue() { + return blue & 0xFF; + } + + /** + * Accessor + */ + public int getAlpha() { + return alpha & 0xFF; + } + + /** + * Set the Red component + */ + public void setRed(int red) { + this.red = (byte) red; + } + + /** + * Set the Green component + */ + public void setGreen(int green) { + this.green = (byte) green; + } + + /** + * Set the Blue component + */ + public void setBlue(int blue) { + this.blue = (byte) blue; + } + + /** + * Set the Alpha component + */ + public void setAlpha(int alpha) { + this.alpha = (byte) alpha; + } + + /** + * Set the Red component + */ + public void setRed(byte red) { + this.red = red; + } + + /** + * Set the Green component + */ + public void setGreen(byte green) { + this.green = green; + } + + /** + * Set the Blue component + */ + public void setBlue(byte blue) { + this.blue = blue; + } + + /** + * Set the Alpha component + */ + public void setAlpha(byte alpha) { + this.alpha = alpha; + } + + /** + * Stringify + */ + public String toString() { + return "Color [" + getRed() + ", " + getGreen() + ", " + getBlue() + ", " + getAlpha() + "]"; + } + + /** + * Equals + */ + public boolean equals(Object o) { + return (o != null) + && (o instanceof ReadableColor) + && (((ReadableColor) o).getRed() == this.getRed()) + && (((ReadableColor) o).getGreen() == this.getGreen()) + && (((ReadableColor) o).getBlue() == this.getBlue()) + && (((ReadableColor) o).getAlpha() == this.getAlpha()); + } + + /** + * Hashcode + */ + public int hashCode() { + return (red << 24) | (green << 16) | (blue << 8) | alpha; + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#getAlphaByte() + */ + public byte getAlphaByte() { + return alpha; + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#getBlueByte() + */ + public byte getBlueByte() { + return blue; + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#getGreenByte() + */ + public byte getGreenByte() { + return green; + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#getRedByte() + */ + public byte getRedByte() { + return red; + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#writeRGBA(java.nio.ByteBuffer) + */ + public void writeRGBA(ByteBuffer dest) { + dest.put(red); + dest.put(green); + dest.put(blue); + dest.put(alpha); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#writeRGB(java.nio.ByteBuffer) + */ + public void writeRGB(ByteBuffer dest) { + dest.put(red); + dest.put(green); + dest.put(blue); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#writeABGR(java.nio.ByteBuffer) + */ + public void writeABGR(ByteBuffer dest) { + dest.put(alpha); + dest.put(blue); + dest.put(green); + dest.put(red); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#writeARGB(java.nio.ByteBuffer) + */ + public void writeARGB(ByteBuffer dest) { + dest.put(alpha); + dest.put(red); + dest.put(green); + dest.put(blue); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#writeBGR(java.nio.ByteBuffer) + */ + public void writeBGR(ByteBuffer dest) { + dest.put(blue); + dest.put(green); + dest.put(red); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableColor#writeBGRA(java.nio.ByteBuffer) + */ + public void writeBGRA(ByteBuffer dest) { + dest.put(blue); + dest.put(green); + dest.put(red); + dest.put(alpha); + } + + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + public void readRGBA(ByteBuffer src) { + red = src.get(); + green = src.get(); + blue = src.get(); + alpha = src.get(); + } + + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + public void readRGB(ByteBuffer src) { + red = src.get(); + green = src.get(); + blue = src.get(); + } + + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + public void readARGB(ByteBuffer src) { + alpha = src.get(); + red = src.get(); + green = src.get(); + blue = src.get(); + } + + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + public void readBGRA(ByteBuffer src) { + blue = src.get(); + green = src.get(); + red = src.get(); + alpha = src.get(); + } + + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + public void readBGR(ByteBuffer src) { + blue = src.get(); + green = src.get(); + red = src.get(); + } + + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + public void readABGR(ByteBuffer src) { + alpha = src.get(); + blue = src.get(); + green = src.get(); + red = src.get(); + } + + /** + * Set this color's color by copying another color + * @param src The source color + */ + public void setColor(ReadableColor src) { + red = src.getRedByte(); + green = src.getGreenByte(); + blue = src.getBlueByte(); + alpha = src.getAlphaByte(); + } + + /** + * HSB to RGB conversion, pinched from java.awt.Color. + * @param hue (0..1.0f) + * @param saturation (0..1.0f) + * @param brightness (0..1.0f) + */ + public void fromHSB(float hue, float saturation, float brightness) { + if (saturation == 0.0F) { + red = green = blue = (byte) (brightness * 255F + 0.5F); + } else { + float f3 = (hue - (float) Math.floor(hue)) * 6F; + float f4 = f3 - (float) Math.floor(f3); + float f5 = brightness * (1.0F - saturation); + float f6 = brightness * (1.0F - saturation * f4); + float f7 = brightness * (1.0F - saturation * (1.0F - f4)); + switch ((int) f3) { + case 0 : + red = (byte) (brightness * 255F + 0.5F); + green = (byte) (f7 * 255F + 0.5F); + blue = (byte) (f5 * 255F + 0.5F); + break; + case 1 : + red = (byte) (f6 * 255F + 0.5F); + green = (byte) (brightness * 255F + 0.5F); + blue = (byte) (f5 * 255F + 0.5F); + break; + case 2 : + red = (byte) (f5 * 255F + 0.5F); + green = (byte) (brightness * 255F + 0.5F); + blue = (byte) (f7 * 255F + 0.5F); + break; + case 3 : + red = (byte) (f5 * 255F + 0.5F); + green = (byte) (f6 * 255F + 0.5F); + blue = (byte) (brightness * 255F + 0.5F); + break; + case 4 : + red = (byte) (f7 * 255F + 0.5F); + green = (byte) (f5 * 255F + 0.5F); + blue = (byte) (brightness * 255F + 0.5F); + break; + case 5 : + red = (byte) (brightness * 255F + 0.5F); + green = (byte) (f5 * 255F + 0.5F); + blue = (byte) (f6 * 255F + 0.5F); + break; + } + } + } + + /** + * RGB to HSB conversion, pinched from java.awt.Color. + * The HSB value is returned in dest[] if dest[] is supplied. + * Values range from 0..1 + * @param dest Destination floats, or null + * @return dest, or a new float array + */ + public float[] toHSB(float dest[]) { + int r = getRed(); + int g = getGreen(); + int b = getBlue(); + if (dest == null) + dest = new float[3]; + int l = r <= g ? g : r; + if (b > l) + l = b; + int i1 = r >= g ? g : r; + if (b < i1) + i1 = b; + float brightness = l / 255F; + float saturation; + if (l != 0) + saturation = (float) (l - i1) / (float) l; + else + saturation = 0.0F; + float hue; + if (saturation == 0.0F) { + hue = 0.0F; + } else { + float f3 = (float) (l - r) / (float) (l - i1); + float f4 = (float) (l - g) / (float) (l - i1); + float f5 = (float) (l - b) / (float) (l - i1); + if (r == l) + hue = f5 - f4; + else if (g == l) + hue = (2.0F + f3) - f5; + else + hue = (4F + f4) - f3; + hue /= 6F; + if (hue < 0.0F) + hue++; + } + dest[0] = hue; + dest[1] = saturation; + dest[2] = brightness; + return dest; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Dimension.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Dimension.java new file mode 100644 index 000000000..1b8ae7c32 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Dimension.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.io.Serializable; + +/** + * A 2D integer Dimension class, which looks remarkably like an AWT one. + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public final class Dimension implements Serializable, ReadableDimension, WritableDimension { + + static final long serialVersionUID = 1L; + + /** The dimensions! */ + private int width, height; + + /** + * Constructor for Dimension. + */ + public Dimension() { + super(); + } + + /** + * Constructor for Dimension. + */ + public Dimension(int w, int h) { + this.width = w; + this.height = h; + } + + /** + * Constructor for Dimension. + */ + public Dimension(ReadableDimension d) { + setSize(d); + } + + public void setSize(int w, int h) { + this.width = w; + this.height = h; + } + + public void setSize(ReadableDimension d) { + this.width = d.getWidth(); + this.height = d.getHeight(); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableDimension#getSize(com.shavenpuppy.jglib.Dimension) + */ + public void getSize(WritableDimension dest) { + dest.setSize(this); + } + + /** + * Checks whether two dimension objects have equal values. + */ + public boolean equals(Object obj) { + if (obj instanceof ReadableDimension) { + ReadableDimension d = (ReadableDimension) obj; + return (width == d.getWidth()) && (height == d.getHeight()); + } + return false; + } + + /** + * Returns the hash code for this Dimension. + * + * @return a hash code for this Dimension + */ + public int hashCode() { + int sum = width + height; + return sum * (sum + 1) / 2 + width; + } + + /** + * Returns a string representation of the values of this + * Dimension object's height and + * width fields. This method is intended to be used only + * for debugging purposes, and the content and format of the returned + * string may vary between implementations. The returned string may be + * empty but may not be null. + * + * @return a string representation of this Dimension + * object + */ + public String toString() { + return getClass().getName() + "[width=" + width + ",height=" + height + "]"; + } + + /** + * Gets the height. + * @return Returns a int + */ + public int getHeight() { + return height; + } + + /** + * Sets the height. + * @param height The height to set + */ + public void setHeight(int height) { + this.height = height; + } + + /** + * Gets the width. + * @return Returns a int + */ + public int getWidth() { + return width; + } + + /** + * Sets the width. + * @param width The width to set + */ + public void setWidth(int width) { + this.width = width; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Display.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Display.java new file mode 100644 index 000000000..00eef0dbf --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Display.java @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +import org.lwjgl.LWJGLException; +import org.lwjgl.LWJGLUtil; +import org.lwjgl.opengl.DisplayMode; + +/** + * Display initialization utility, that can be used to find display modes and pick + * one for you based on your criteria. + * @author $Author: spasi $ + * @version $Revision: 3418 $ + * $Id: Display.java 3418 2010-09-28 21:11:35Z spasi $ + */ +public final class Display { + + private static final boolean DEBUG = false; + + /** + * Determine the available display modes that match the specified minimum and maximum criteria. + * If any given criterium is specified as -1 then it is ignored. + * + * @param minWidth the minimum display resolution in pixels + * @param minHeight the minimum display resolution in pixels + * @param maxWidth the maximum display resolution in pixels + * @param maxHeight the maximum display resolution in pixels + * @param minBPP the minimum bit depth per pixel + * @param maxBPP the maximum bit depth per pixel + * @param minFreq the minimum display frequency in Hz + * @param maxFreq the maximum display frequency in Hz + * @return an array of matching display modes + */ + public static DisplayMode[] getAvailableDisplayModes(int minWidth, int minHeight, int maxWidth, int maxHeight, int minBPP, int maxBPP, + int minFreq, int maxFreq) throws LWJGLException + { + // First get the available display modes + DisplayMode[] modes = org.lwjgl.opengl.Display.getAvailableDisplayModes(); + + if (LWJGLUtil.DEBUG || DEBUG) { + System.out.println("Available screen modes:"); + for ( DisplayMode mode : modes ) { + System.out.println(mode); + } + } + + ArrayList matches = new ArrayList(modes.length); + + for (int i = 0; i < modes.length; i ++) { + assert modes[i] != null : ""+i+" "+modes.length; + if (minWidth != -1 && modes[i].getWidth() < minWidth) + continue; + if (maxWidth != -1 && modes[i].getWidth() > maxWidth) + continue; + if (minHeight != -1 && modes[i].getHeight() < minHeight) + continue; + if (maxHeight != -1 && modes[i].getHeight() > maxHeight) + continue; + if (minBPP != -1 && modes[i].getBitsPerPixel() < minBPP) + continue; + if (maxBPP != -1 && modes[i].getBitsPerPixel() > maxBPP) + continue; + //if (modes[i].bpp == 24) + // continue; + if (modes[i].getFrequency() != 0) { + if (minFreq != -1 && modes[i].getFrequency() < minFreq) + continue; + if (maxFreq != -1 && modes[i].getFrequency() > maxFreq) + continue; + } + matches.add(modes[i]); + } + + DisplayMode[] ret = new DisplayMode[matches.size()]; + matches.toArray(ret); + if (LWJGLUtil.DEBUG && DEBUG) { + System.out.println("Filtered screen modes:"); + for ( DisplayMode mode : ret ) { + System.out.println(mode); + } + } + + return ret; + } + + /** + * Create the display by choosing from a list of display modes based on an order of preference. + * You must supply a list of allowable display modes, probably by calling getAvailableDisplayModes(), + * and an array with the order in which you would like them sorted in descending order. + * This method attempts to create the topmost display mode; if that fails, it will try the next one, + * and so on, until there are no modes left. If no mode is set at the end, an exception is thrown. + * @param dm a list of display modes to choose from + * @param param the names of the DisplayMode fields in the order in which you would like them sorted. + * @return the chosen display mode + * @throws NoSuchFieldException if one of the params is not a field in DisplayMode + * @throws Exception if no display mode could be set + * @see org.lwjgl.opengl.DisplayMode + */ + public static DisplayMode setDisplayMode(DisplayMode[] dm, final String[] param) throws Exception { + + class FieldAccessor { + final String fieldName; + final int order; + final int preferred; + final boolean usePreferred; + FieldAccessor(String fieldName, int order, int preferred, boolean usePreferred) { + this.fieldName = fieldName; + this.order = order; + this.preferred = preferred; + this.usePreferred = usePreferred; + } + int getInt(DisplayMode mode) { + if ("width".equals(fieldName)) { + return mode.getWidth(); + } + if ("height".equals(fieldName)) { + return mode.getHeight(); + } + if ("freq".equals(fieldName)) { + return mode.getFrequency(); + } + if ("bpp".equals(fieldName)) { + return mode.getBitsPerPixel(); + } + throw new IllegalArgumentException("Unknown field "+fieldName); + } + } + + class Sorter implements Comparator { + + final FieldAccessor[] accessors; + + Sorter() { + accessors = new FieldAccessor[param.length]; + for (int i = 0; i < accessors.length; i ++) { + int idx = param[i].indexOf('='); + if (idx > 0) { + accessors[i] = new FieldAccessor(param[i].substring(0, idx), 0, Integer.parseInt(param[i].substring(idx + 1, param[i].length())), true); + } else if (param[i].charAt(0) == '-') { + accessors[i] = new FieldAccessor(param[i].substring(1), -1, 0, false); + } else { + accessors[i] = new FieldAccessor(param[i], 1, 0, false); + } + } + } + + /** + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(DisplayMode dm1, DisplayMode dm2) { + for ( FieldAccessor accessor : accessors ) { + int f1 = accessor.getInt(dm1); + int f2 = accessor.getInt(dm2); + + if ( accessor.usePreferred && f1 != f2 ) { + if ( f1 == accessor.preferred ) + return -1; + else if ( f2 == accessor.preferred ) + return 1; + else { + // Score according to the difference between the values + int absf1 = Math.abs(f1 - accessor.preferred); + int absf2 = Math.abs(f2 - accessor.preferred); + if ( absf1 < absf2 ) + return -1; + else if ( absf1 > absf2 ) + return 1; + else + continue; + } + } else if ( f1 < f2 ) + return accessor.order; + else if ( f1 == f2 ) + continue; + else + return -accessor.order; + } + + return 0; + } + } + + // Sort the display modes + Arrays.sort(dm, new Sorter()); + + // Try them out in the appropriate order + if (LWJGLUtil.DEBUG || DEBUG) { + System.out.println("Sorted display modes:"); + for ( DisplayMode aDm : dm ) { + System.out.println(aDm); + } + } + for ( DisplayMode aDm : dm ) { + try { + if ( LWJGLUtil.DEBUG || DEBUG ) + System.out.println("Attempting to set displaymode: " + aDm); + org.lwjgl.opengl.Display.setDisplayMode(aDm); + return aDm; + } catch (Exception e) { + if ( LWJGLUtil.DEBUG || DEBUG ) { + System.out.println("Failed to set display mode to " + aDm); + e.printStackTrace(); + } + } + } + + throw new Exception("Failed to set display mode."); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Point.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Point.java new file mode 100644 index 000000000..5d17362e4 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Point.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.io.Serializable; + +/** + * A 2D integer point class, which looks remarkably like an AWT one. + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public final class Point implements ReadablePoint, WritablePoint, Serializable { + + static final long serialVersionUID = 1L; + + /** The location */ + private int x, y; + + /** + * Constructor for Point. + */ + public Point() { + super(); + } + + /** + * Constructor for Point. + */ + public Point(int x, int y) { + setLocation(x, y); + } + + /** + * Constructor for Point. + */ + public Point(ReadablePoint p) { + setLocation(p); + } + + public void setLocation(int x, int y) { + this.x = x; + this.y = y; + } + + public void setLocation(ReadablePoint p) { + this.x = p.getX(); + this.y = p.getY(); + } + + public void setX(int x) { + this.x = x; + } + + public void setY(int y) { + this.y = y; + } + + /** + * Translate a point. + * @param dx The translation to apply + * @param dy The translation to apply + */ + public void translate(int dx, int dy) { + this.x += dx; + this.y += dy; + } + + /** + * Translate a point. + * @param p The translation to apply + */ + public void translate(ReadablePoint p) { + this.x += p.getX(); + this.y += p.getY(); + } + + /** + * Un-translate a point. + * @param p The translation to apply + */ + public void untranslate(ReadablePoint p) { + this.x -= p.getX(); + this.y -= p.getY(); + } + + /** + * Determines whether an instance of Point2D is equal + * to this point. Two instances of Point2D are equal if + * the values of their x and y member + * fields, representing their position in the coordinate space, are + * the same. + * @param obj an object to be compared with this point + * @return true if the object to be compared is + * an instance of Point and has + * the same values; false otherwise + */ + public boolean equals(Object obj) { + if (obj instanceof Point) { + Point pt = (Point) obj; + return (x == pt.x) && (y == pt.y); + } + return super.equals(obj); + } + + /** + * Returns a string representation of this point and its location + * in the (xy) coordinate space. This method is + * intended to be used only for debugging purposes, and the content + * and format of the returned string may vary between implementations. + * The returned string may be empty but may not be null. + * + * @return a string representation of this point + */ + public String toString() { + return getClass().getName() + "[x=" + x + ",y=" + y + "]"; + } + + /** + * Returns the hash code for this Point. + * + * @return a hash code for this Point + */ + public int hashCode() { + int sum = x + y; + return sum * (sum + 1) / 2 + x; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public void getLocation(WritablePoint dest) { + dest.setLocation(x, y); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableColor.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableColor.java new file mode 100644 index 000000000..9371cc87e --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableColor.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.nio.ByteBuffer; + +/** + * Readonly interface for Colors + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface ReadableColor { + + /** + * Return the red component (0..255) + * @return int + */ + int getRed(); + + /** + * Return the red component (0..255) + * @return int + */ + int getGreen(); + + /** + * Return the red component (0..255) + * @return int + */ + int getBlue(); + + /** + * Return the red component (0..255) + * @return int + */ + int getAlpha(); + + /** + * Return the red component + * @return int + */ + byte getRedByte(); + + /** + * Return the red component + * @return int + */ + byte getGreenByte(); + + /** + * Return the red component + * @return int + */ + byte getBlueByte(); + + /** + * Return the red component + * @return int + */ + byte getAlphaByte(); + + /** + * Write the RGBA color directly out to a ByteBuffer + * @param dest the buffer to write to + */ + void writeRGBA(ByteBuffer dest); + + /** + * Write the RGB color directly out to a ByteBuffer + * @param dest the buffer to write to + */ + void writeRGB(ByteBuffer dest); + + /** + * Write the ABGR color directly out to a ByteBuffer + * @param dest the buffer to write to + */ + void writeABGR(ByteBuffer dest); + + /** + * Write the BGR color directly out to a ByteBuffer + * @param dest the buffer to write to + */ + void writeBGR(ByteBuffer dest); + + /** + * Write the BGRA color directly out to a ByteBuffer + * @param dest the buffer to write to + */ + void writeBGRA(ByteBuffer dest); + + /** + * Write the ARGB color directly out to a ByteBuffer + * @param dest the buffer to write to + */ + void writeARGB(ByteBuffer dest); + + /* + * Some standard colors + */ + ReadableColor RED = new Color(255, 0, 0); + ReadableColor ORANGE = new Color(255, 128, 0); + ReadableColor YELLOW = new Color(255, 255, 0); + ReadableColor GREEN = new Color(0, 255, 0); + ReadableColor CYAN = new Color(0, 255, 255); + ReadableColor BLUE = new Color(0, 0, 255); + ReadableColor PURPLE = new Color(255, 0, 255); + ReadableColor WHITE = new Color(255, 255, 255); + ReadableColor BLACK = new Color(0, 0, 0); + ReadableColor LTGREY = new Color(192, 192, 192); + ReadableColor DKGREY = new Color(64, 64, 64); + ReadableColor GREY = new Color(128, 128, 128); + + + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableDimension.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableDimension.java new file mode 100644 index 000000000..cb38a0a95 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableDimension.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +/** + * Readonly interface for Dimensions + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface ReadableDimension { + + /** + * Get the width + * @return int + */ + int getWidth(); + + /** + * Get the height + * @return int + */ + int getHeight(); + + /** + * Copy this ReadableDimension into a destination Dimension + * @param dest The destination + */ + void getSize(WritableDimension dest); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadablePoint.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadablePoint.java new file mode 100644 index 000000000..a256459dd --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadablePoint.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +/** + * Readonly interface for Points + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface ReadablePoint { + + /** + * @return int + */ + int getX(); + + /** + * @return int + */ + int getY(); + + /** + * Copy this ReadablePoint into a destination Point + * @param dest The destination Point, or null, to create a new Point + */ + void getLocation(WritablePoint dest); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableRectangle.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableRectangle.java new file mode 100644 index 000000000..cced54f21 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/ReadableRectangle.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +/** + * Readonly interface for Rectangles + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface ReadableRectangle extends ReadableDimension, ReadablePoint { + + /** + * Copy this readable rectangle's bounds into a destination Rectangle + * @param dest The destination Rectangle, or null, to create a new Rectangle + */ + void getBounds(WritableRectangle dest); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Rectangle.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Rectangle.java new file mode 100644 index 000000000..88d233489 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Rectangle.java @@ -0,0 +1,581 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.io.Serializable; + +/** + * A 2D integer Rectangle class which looks remarkably like an AWT one. + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public final class Rectangle implements ReadableRectangle, WritableRectangle, Serializable { + + static final long serialVersionUID = 1L; + + /** Rectangle's bounds */ + private int x, y, width, height; + + /** + * Constructor for Rectangle. + */ + public Rectangle() { + super(); + } + /** + * Constructor for Rectangle. + */ + public Rectangle(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.width = w; + this.height = h; + } + /** + * Constructor for Rectangle. + */ + public Rectangle(ReadablePoint p, ReadableDimension d) { + x = p.getX(); + y = p.getY(); + width = d.getWidth(); + height = d.getHeight(); + } + /** + * Constructor for Rectangle. + */ + public Rectangle(ReadableRectangle r) { + x = r.getX(); + y = r.getY(); + width = r.getWidth(); + height = r.getHeight(); + } + + public void setLocation(int x, int y) { + this.x = x; + this.y = y; + } + + public void setLocation(ReadablePoint p) { + this.x = p.getX(); + this.y = p.getY(); + } + + public void setSize(int w, int h) { + this.width = w; + this.height = h; + } + + public void setSize(ReadableDimension d) { + this.width = d.getWidth(); + this.height = d.getHeight(); + } + + public void setBounds(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.width = w; + this.height = h; + } + + public void setBounds(ReadablePoint p, ReadableDimension d) { + x = p.getX(); + y = p.getY(); + width = d.getWidth(); + height = d.getHeight(); + } + + public void setBounds(ReadableRectangle r) { + x = r.getX(); + y = r.getY(); + width = r.getWidth(); + height = r.getHeight(); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableRectangle#getBounds(com.shavenpuppy.jglib.Rectangle) + */ + public void getBounds(WritableRectangle dest) { + dest.setBounds(x, y, width, height); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadablePoint#getLocation(com.shavenpuppy.jglib.Point) + */ + public void getLocation(WritablePoint dest) { + dest.setLocation(x, y); + } + + /* (Overrides) + * @see com.shavenpuppy.jglib.ReadableDimension#getSize(com.shavenpuppy.jglib.Dimension) + */ + public void getSize(WritableDimension dest) { + dest.setSize(width, height); + } + + /** + * Translate the rectangle by an amount. + * @param x The translation amount on the x axis + * @param y The translation amount on the y axis + */ + public void translate(int x, int y) { + this.x += x; + this.y += y; + } + + /** + * Translate the rectangle by an amount. + * @param point The translation amount + */ + public void translate(ReadablePoint point) { + this.x += point.getX(); + this.y += point.getY(); + } + + /** + * Un-translate the rectangle by an amount. + * @param point The translation amount + */ + public void untranslate(ReadablePoint point) { + this.x -= point.getX(); + this.y -= point.getY(); + } + + /** + * Checks whether or not this Rectangle contains the + * specified Point. + * @param p the Point to test + * @return true if the Point + * (xy) is inside this + * Rectangle; + * false otherwise. + */ + public boolean contains(ReadablePoint p) { + return contains(p.getX(), p.getY()); + } + + /** + * Checks whether or not this Rectangle contains the + * point at the specified location + * (xy). + * @param X the specified x coordinate + * @param Y the specified y coordinate + * @return true if the point + * (xy) is inside this + * Rectangle; + * false otherwise. + */ + public boolean contains(int X, int Y) { + int w = this.width; + int h = this.height; + if ((w | h) < 0) { + // At least one of the dimensions is negative... + return false; + } + // Note: if either dimension is zero, tests below must return false... + int x = this.x; + int y = this.y; + if (X < x || Y < y) { + return false; + } + w += x; + h += y; + // overflow || intersect + return ((w < x || w > X) && (h < y || h > Y)); + } + + /** + * Checks whether or not this Rectangle entirely contains + * the specified Rectangle. + * @param r the specified Rectangle + * @return true if the Rectangle + * is contained entirely inside this Rectangle; + * false otherwise. + */ + public boolean contains(ReadableRectangle r) { + return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + + /** + * Checks whether this Rectangle entirely contains + * the Rectangle + * at the specified location (XY) with the + * specified dimensions (WH). + * @param X the specified x coordinate + * @param Y the specified y coordinate + * @param W the width of the Rectangle + * @param H the height of the Rectangle + * @return true if the Rectangle specified by + * (XYWH) + * is entirely enclosed inside this Rectangle; + * false otherwise. + */ + public boolean contains(int X, int Y, int W, int H) { + int w = this.width; + int h = this.height; + if ((w | h | W | H) < 0) { + // At least one of the dimensions is negative... + return false; + } + // Note: if any dimension is zero, tests below must return false... + int x = this.x; + int y = this.y; + if (X < x || Y < y) { + return false; + } + w += x; + W += X; + if (W <= X) { + // X+W overflowed or W was zero, return false if... + // either original w or W was zero or + // x+w did not overflow or + // the overflowed x+w is smaller than the overflowed X+W + if (w >= x || W > w) + return false; + } else { + // X+W did not overflow and W was not zero, return false if... + // original w was zero or + // x+w did not overflow and x+w is smaller than X+W + if (w >= x && W > w) + return false; + } + h += y; + H += Y; + if (H <= Y) { + if (h >= y || H > h) + return false; + } else { + if (h >= y && H > h) + return false; + } + return true; + } + + /** + * Determines whether or not this Rectangle and the specified + * Rectangle intersect. Two rectangles intersect if + * their intersection is nonempty. + * + * @param r the specified Rectangle + * @return true if the specified Rectangle + * and this Rectangle intersect; + * false otherwise. + */ + public boolean intersects(ReadableRectangle r) { + int tw = this.width; + int th = this.height; + int rw = r.getWidth(); + int rh = r.getHeight(); + if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) { + return false; + } + int tx = this.x; + int ty = this.y; + int rx = r.getX(); + int ry = r.getY(); + rw += rx; + rh += ry; + tw += tx; + th += ty; + // overflow || intersect + return ((rw < rx || rw > tx) && (rh < ry || rh > ty) && (tw < tx || tw > rx) && (th < ty || th > ry)); + } + + /** + * Computes the intersection of this Rectangle with the + * specified Rectangle. Returns a new Rectangle + * that represents the intersection of the two rectangles. + * If the two rectangles do not intersect, the result will be + * an empty rectangle. + * + * @param r the specified Rectangle + * @return the largest Rectangle contained in both the + * specified Rectangle and in + * this Rectangle; or if the rectangles + * do not intersect, an empty rectangle. + */ + public Rectangle intersection(ReadableRectangle r, Rectangle dest) { + int tx1 = this.x; + int ty1 = this.y; + int rx1 = r.getX(); + int ry1 = r.getY(); + long tx2 = tx1; + tx2 += this.width; + long ty2 = ty1; + ty2 += this.height; + long rx2 = rx1; + rx2 += r.getWidth(); + long ry2 = ry1; + ry2 += r.getHeight(); + if (tx1 < rx1) + tx1 = rx1; + if (ty1 < ry1) + ty1 = ry1; + if (tx2 > rx2) + tx2 = rx2; + if (ty2 > ry2) + ty2 = ry2; + tx2 -= tx1; + ty2 -= ty1; + // tx2,ty2 will never overflow (they will never be + // larger than the smallest of the two source w,h) + // they might underflow, though... + if (tx2 < Integer.MIN_VALUE) + tx2 = Integer.MIN_VALUE; + if (ty2 < Integer.MIN_VALUE) + ty2 = Integer.MIN_VALUE; + if (dest == null) + dest = new Rectangle(tx1, ty1, (int) tx2, (int) ty2); + else + dest.setBounds(tx1, ty1, (int) tx2, (int) ty2); + return dest; + + } + + /** + * Computes the union of this Rectangle with the + * specified Rectangle. Returns a new + * Rectangle that + * represents the union of the two rectangles + * @param r the specified Rectangle + * @return the smallest Rectangle containing both + * the specified Rectangle and this + * Rectangle. + */ + public WritableRectangle union(ReadableRectangle r, WritableRectangle dest) { + int x1 = Math.min(x, r.getX()); + int x2 = Math.max(x + width, r.getX() + r.getWidth()); + int y1 = Math.min(y, r.getY()); + int y2 = Math.max(y + height, r.getY() + r.getHeight()); + dest.setBounds(x1, y1, x2 - x1, y2 - y1); + return dest; + } + + /** + * Adds a point, specified by the integer arguments newx + * and newy, to this Rectangle. The + * resulting Rectangle is + * the smallest Rectangle that contains both the + * original Rectangle and the specified point. + *

+ * After adding a point, a call to contains with the + * added point as an argument does not necessarily return + * true. The contains method does not + * return true for points on the right or bottom + * edges of a Rectangle. Therefore, if the added point + * falls on the right or bottom edge of the enlarged + * Rectangle, contains returns + * false for that point. + * @param newx the x coordinates of the new point + * @param newy the y coordinates of the new point + */ + public void add(int newx, int newy) { + int x1 = Math.min(x, newx); + int x2 = Math.max(x + width, newx); + int y1 = Math.min(y, newy); + int y2 = Math.max(y + height, newy); + x = x1; + y = y1; + width = x2 - x1; + height = y2 - y1; + } + + /** + * Adds the specified Point to this + * Rectangle. The resulting Rectangle + * is the smallest Rectangle that contains both the + * original Rectangle and the specified + * Point. + *

+ * After adding a Point, a call to contains + * with the added Point as an argument does not + * necessarily return true. The contains + * method does not return true for points on the right + * or bottom edges of a Rectangle. Therefore if the added + * Point falls on the right or bottom edge of the + * enlarged Rectangle, contains returns + * false for that Point. + * @param pt the new Point to add to this + * Rectangle + */ + public void add(ReadablePoint pt) { + add(pt.getX(), pt.getY()); + } + + /** + * Adds a Rectangle to this Rectangle. + * The resulting Rectangle is the union of the two + * rectangles. + * @param r the specified Rectangle + */ + public void add(ReadableRectangle r) { + int x1 = Math.min(x, r.getX()); + int x2 = Math.max(x + width, r.getX() + r.getWidth()); + int y1 = Math.min(y, r.getY()); + int y2 = Math.max(y + height, r.getY() + r.getHeight()); + x = x1; + y = y1; + width = x2 - x1; + height = y2 - y1; + } + + /** + * Resizes the Rectangle both horizontally and vertically. + *

+ * This method modifies the Rectangle so that it is + * h units larger on both the left and right side, + * and v units larger at both the top and bottom. + *

+ * The new Rectangle has (x - h, + * y - v) as its top-left corner, a + * width of + * width + 2h, + * and a height of + * height + 2v. + *

+ * If negative values are supplied for h and + * v, the size of the Rectangle + * decreases accordingly. + * The grow method does not check whether the resulting + * values of width and height are + * non-negative. + * @param h the horizontal expansion + * @param v the vertical expansion + */ + public void grow(int h, int v) { + x -= h; + y -= v; + width += h * 2; + height += v * 2; + } + + /** + * Determines whether or not this Rectangle is empty. A + * Rectangle is empty if its width or its height is less + * than or equal to zero. + * @return true if this Rectangle is empty; + * false otherwise. + */ + public boolean isEmpty() { + return (width <= 0) || (height <= 0); + } + /** + * Checks whether two rectangles are equal. + *

+ * The result is true if and only if the argument is not + * null and is a Rectangle object that has the + * same top-left corner, width, and height as this Rectangle. + * @param obj the Object to compare with + * this Rectangle + * @return true if the objects are equal; + * false otherwise. + */ + public boolean equals(Object obj) { + if (obj instanceof Rectangle) { + Rectangle r = (Rectangle) obj; + return ((x == r.x) && (y == r.y) && (width == r.width) && (height == r.height)); + } + return super.equals(obj); + } + + /** + * Debugging + * @return a String + */ + public String toString() { + return getClass().getName() + "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; + } + /** + * Gets the height. + * @return Returns a int + */ + public int getHeight() { + return height; + } + + /** + * Sets the height. + * @param height The height to set + */ + public void setHeight(int height) { + this.height = height; + } + + /** + * Gets the width. + * @return Returns a int + */ + public int getWidth() { + return width; + } + + /** + * Sets the width. + * @param width The width to set + */ + public void setWidth(int width) { + this.width = width; + } + + /** + * Gets the x. + * @return Returns a int + */ + public int getX() { + return x; + } + + /** + * Sets the x. + * @param x The x to set + */ + public void setX(int x) { + this.x = x; + } + + /** + * Gets the y. + * @return Returns a int + */ + public int getY() { + return y; + } + + /** + * Sets the y. + * @param y The y to set + */ + public void setY(int y) { + this.y = y; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Renderable.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Renderable.java new file mode 100644 index 000000000..fcb73ea7f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Renderable.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +/** + * + * Simple interface to things that can be Rendered. + * + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface Renderable { + + /** + * "Render" this thing. This will involve calls to the GL. + */ + void render(); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Timer.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Timer.java new file mode 100644 index 000000000..df148e91d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/Timer.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import org.lwjgl.Sys; + +/** + * + * A hires timer. This measures time in seconds as floating point values. + * All Timers created are updated simultaneously by calling the static method + * tick(). This ensures that within a single iteration of a game loop that + * all timers are updated consistently with each other. + * + * @author cix_foo + * @version $Revision$ + * $Id$ + */ +public class Timer { + + // Record the timer resolution on classload + private static long resolution = Sys.getTimerResolution(); + + // Every so often we will re-query the timer resolution + private static final int QUERY_INTERVAL = 50; // in calls to tick() + private static int queryCount; + + // Globally keeps track of time for all instances of Timer + private static long currentTime; + + // When the timer was started + private long startTime; + + // The last time recorded by getTime() + private long lastTime; + + // Whether the timer is paused + private boolean paused; + + static { + tick(); + } + + /** + * Constructs a timer. The timer will be reset to 0.0 and resumed immediately. + */ + public Timer() { + reset(); + resume(); + } + + /** + * @return the time in seconds, as a float + */ + public float getTime() { + if (!paused) { + lastTime = currentTime - startTime; + } + + return (float) ((double) lastTime / (double) resolution); + } + /** + * @return whether this timer is paused + */ + public boolean isPaused() { + return paused; + } + + /** + * Pause the timer. Whilst paused the time will not change for this timer + * when tick() is called. + * + * @see #resume() + */ + public void pause() { + paused = true; + } + + /** + * Reset the timer. Equivalent to set(0.0f); + * @see #set(float) + */ + public void reset() { + set(0.0f); + } + + /** + * Resume the timer. + * @see #pause() + */ + public void resume() { + paused = false; + startTime = currentTime - lastTime; + } + + /** + * Set the time of this timer + * @param newTime the new time, in seconds + */ + public void set(float newTime) { + long newTimeInTicks = (long) ((double) newTime * (double) resolution); + startTime = currentTime - newTimeInTicks; + lastTime = newTimeInTicks; + } + + /** + * Get the next time update from the system's hires timer. This method should + * be called once per main loop iteration; all timers are updated simultaneously + * from it. + */ + public static void tick() { + currentTime = Sys.getTime(); + + // Periodically refresh the timer resolution: + queryCount ++; + if (queryCount > QUERY_INTERVAL) { + queryCount = 0; + resolution = Sys.getTimerResolution(); + } + } + + /** + * Debug output. + */ + public String toString() { + return "Timer[Time=" + getTime() + ", Paused=" + paused + "]"; + } +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WaveData.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WaveData.java new file mode 100644 index 000000000..d0f00813c --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WaveData.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ShortBuffer; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; + +import org.lwjgl.openal.AL10; + + +/** + * + * Utility class for loading wavefiles. + * + * @author Brian Matzon + * @version $Revision$ + * $Id$ + */ +public class WaveData { + /** actual wave data */ + public final ByteBuffer data; + + /** format type of data */ + public final int format; + + /** sample rate of data */ + public final int samplerate; + + /** + * Creates a new WaveData + * + * @param data actual wavedata + * @param format format of wave data + * @param samplerate sample rate of data + */ + private WaveData(ByteBuffer data, int format, int samplerate) { + this.data = data; + this.format = format; + this.samplerate = samplerate; + } + + /** + * Disposes the wavedata + */ + public void dispose() { + data.clear(); + } + + /** + * Creates a WaveData container from the specified url + * + * @param path URL to file + * @return WaveData containing data, or null if a failure occured + */ + public static WaveData create(URL path) { + try { + // due to an issue with AudioSystem.getAudioInputStream + // and mixing unsigned and signed code + // we will use the reader directly + return create(AudioSystem.getAudioInputStream(path)); + //WaveFileReader wfr = new WaveFileReader(); + //return create(wfr.getAudioInputStream(new BufferedInputStream(path.openStream()))); + } catch (Exception e) { + org.lwjgl.system.APIUtil.apiLog("Unable to create from: " + path + ", " + e.getMessage()); + return null; + } + } + + /** + * Creates a WaveData container from the specified in the classpath + * + * @param path path to file (relative, and in classpath) + * @return WaveData containing data, or null if a failure occured + */ + public static WaveData create(String path) { + return create(Thread.currentThread().getContextClassLoader().getResource(path)); + } + + /** + * Creates a WaveData container from the specified inputstream + * + * @param is InputStream to read from + * @return WaveData containing data, or null if a failure occured + */ + public static WaveData create(InputStream is) { + try { + return create( + AudioSystem.getAudioInputStream(is)); + } catch (Exception e) { + org.lwjgl.system.APIUtil.apiLog("Unable to create from inputstream, " + e.getMessage()); + return null; + } + } + + /** + * Creates a WaveData container from the specified bytes + * + * @param buffer array of bytes containing the complete wave file + * @return WaveData containing data, or null if a failure occured + */ + public static WaveData create(byte[] buffer) { + try { + return create( + AudioSystem.getAudioInputStream( + new BufferedInputStream(new ByteArrayInputStream(buffer)))); + } catch (Exception e) { + org.lwjgl.system.APIUtil.apiLog("Unable to create from byte array, " + e.getMessage()); + return null; + } + } + + /** + * Creates a WaveData container from the specified ByetBuffer. + * If the buffer is backed by an array, it will be used directly, + * else the contents of the buffer will be copied using get(byte[]). + * + * @param buffer ByteBuffer containing sound file + * @return WaveData containing data, or null if a failure occured + */ + public static WaveData create(ByteBuffer buffer) { + try { + byte[] bytes = null; + + if(buffer.hasArray()) { + bytes = buffer.array(); + } else { + bytes = new byte[buffer.capacity()]; + buffer.get(bytes); + } + return create(bytes); + } catch (Exception e) { + org.lwjgl.system.APIUtil.apiLog("Unable to create from ByteBuffer, " + e.getMessage()); + return null; + } + } + + /** + * Creates a WaveData container from the specified stream + * + * @param ais AudioInputStream to read from + * @return WaveData containing data, or null if a failure occured + */ + public static WaveData create(AudioInputStream ais) { + //get format of data + AudioFormat audioformat = ais.getFormat(); + + // get channels + int channels = 0; + if (audioformat.getChannels() == 1) { + if (audioformat.getSampleSizeInBits() == 8) { + channels = AL10.AL_FORMAT_MONO8; + } else if (audioformat.getSampleSizeInBits() == 16) { + channels = AL10.AL_FORMAT_MONO16; + } else { + assert false : "Illegal sample size"; + } + } else if (audioformat.getChannels() == 2) { + if (audioformat.getSampleSizeInBits() == 8) { + channels = AL10.AL_FORMAT_STEREO8; + } else if (audioformat.getSampleSizeInBits() == 16) { + channels = AL10.AL_FORMAT_STEREO16; + } else { + assert false : "Illegal sample size"; + } + } else { + assert false : "Only mono or stereo is supported"; + } + + //read data into buffer + ByteBuffer buffer = null; + try { + int available = ais.available(); + if(available <= 0) { + available = ais.getFormat().getChannels() * (int) ais.getFrameLength() * ais.getFormat().getSampleSizeInBits() / 8; + } + byte[] buf = new byte[ais.available()]; + int read = 0, total = 0; + while ((read = ais.read(buf, total, buf.length - total)) != -1 + && total < buf.length) { + total += read; + } + buffer = convertAudioBytes(buf, audioformat.getSampleSizeInBits() == 16, audioformat.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); + } catch (IOException ioe) { + return null; + } + + + //create our result + WaveData wavedata = + new WaveData(buffer, channels, (int) audioformat.getSampleRate()); + + //close stream + try { + ais.close(); + } catch (IOException ioe) { + } + + return wavedata; + } + + private static ByteBuffer convertAudioBytes(byte[] audio_bytes, boolean two_bytes_data, ByteOrder order) { + ByteBuffer dest = ByteBuffer.allocateDirect(audio_bytes.length); + dest.order(ByteOrder.nativeOrder()); + ByteBuffer src = ByteBuffer.wrap(audio_bytes); + src.order(order); + if (two_bytes_data) { + ShortBuffer dest_short = dest.asShortBuffer(); + ShortBuffer src_short = src.asShortBuffer(); + while (src_short.hasRemaining()) + dest_short.put(src_short.get()); + } else { + while (src.hasRemaining()) + dest.put(src.get()); + } + dest.rewind(); + return dest; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableColor.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableColor.java new file mode 100644 index 000000000..a1fb49cac --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableColor.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.nio.ByteBuffer; + +/** + * Write interface for Colors + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface WritableColor { + /** + * Set a color + */ + void set(int r, int g, int b, int a); + /** + * Set a color + */ + void set(byte r, byte g, byte b, byte a); + /** + * Set a color + */ + void set(int r, int g, int b); + /** + * Set a color + */ + void set(byte r, byte g, byte b); + /** + * Set the Red component + */ + void setRed(int red); + /** + * Set the Green component + */ + void setGreen(int green); + /** + * Set the Blue component + */ + void setBlue(int blue); + /** + * Set the Alpha component + */ + void setAlpha(int alpha); + /** + * Set the Red component + */ + void setRed(byte red); + /** + * Set the Green component + */ + void setGreen(byte green); + /** + * Set the Blue component + */ + void setBlue(byte blue); + /** + * Set the Alpha component + */ + void setAlpha(byte alpha); + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + void readRGBA(ByteBuffer src); + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + void readRGB(ByteBuffer src); + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + void readARGB(ByteBuffer src); + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + void readBGRA(ByteBuffer src); + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + void readBGR(ByteBuffer src); + /** + * Read a color from a byte buffer + * @param src The source buffer + */ + void readABGR(ByteBuffer src); + /** + * Set this color's color by copying another color + * @param src The source color + */ + void setColor(ReadableColor src); +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableDimension.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableDimension.java new file mode 100644 index 000000000..5e0497691 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableDimension.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +/** + * Write interface for Dimensions + * @author $Author$ + * @version $Revision$ + * $Id$ + + */ +public interface WritableDimension { + void setSize(int w, int h); + void setSize(ReadableDimension d); + /** + * Sets the height. + * @param height The height to set + */ + void setHeight(int height); + /** + * Sets the width. + * @param width The width to set + */ + void setWidth(int width); +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritablePoint.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritablePoint.java new file mode 100644 index 000000000..6a398cb08 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritablePoint.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +/** + * Write interface for Points + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface WritablePoint { + void setLocation(int x, int y); + void setLocation(ReadablePoint p); + void setX(int x); + void setY(int y); +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableRectangle.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableRectangle.java new file mode 100644 index 000000000..2b1da1681 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/WritableRectangle.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +/** + * Write interface for Rectangles + * @author $Author$ + * @version $Revision$ + * $Id$ + */ +public interface WritableRectangle extends WritablePoint, WritableDimension { + + /** + * Sets the bounds of the rectangle + * @param x Position of rectangle on x axis + * @param y Position of rectangle on y axis + * @param width Width of rectangle + * @param height Height of rectangle + */ + void setBounds(int x, int y, int width, int height); + + /** + * Sets the bounds of the rectangle + * @param location + * @param size + */ + void setBounds(ReadablePoint location, ReadableDimension size); + + /** + * Sets the bounds of the rectangle + * @param src + */ + void setBounds(ReadableRectangle src); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/XPMFile.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/XPMFile.java new file mode 100644 index 000000000..9b71de0d4 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/XPMFile.java @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.util.HashMap; +import java.util.StringTokenizer; + +/** + *

+ * NOTE: This simple XPM reader does not support extensions nor hotspots + *

+ * + * @author Brian Matzon + * @author Jos Hirth + * @version $Revision$ + * $Id$ + */ + +public class XPMFile { + + /** Array of bytes (RGBA) */ + private byte bytes[]; + + private static final int WIDTH = 0; + + private static final int HEIGHT = 1; + + private static final int NUMBER_OF_COLORS = 2; + + private static final int CHARACTERS_PER_PIXEL = 3; + + private static int[] format = new int[4]; + + /* + * Private constructor, use load(String filename) + */ + private XPMFile() { + } + + /** + * Loads the XPM file + * + * @param file + * path to file + * @return XPMFile loaded, or exception + * @throws IOException + * If any IO exceptions occurs while reading file + */ + public static XPMFile load(String file) throws IOException { + return load(new FileInputStream(new File(file))); + } + + /** + * Loads the XPM file + * + * @param is + * InputStream to read file from + * @return XPMFile loaded, or exception + */ + public static XPMFile load(InputStream is) { + XPMFile xFile = new XPMFile(); + xFile.readImage(is); + return xFile; + } + + /** + * @return the height of the image. + */ + public int getHeight() { + return format[HEIGHT]; + } + + /** + * @return the width of the image. + */ + public int getWidth() { + return format[WIDTH]; + } + + /** + * @return The data of the image. + */ + public byte[] getBytes() { + return bytes; + } + + /** + * Read the image from the specified file. + */ + private void readImage(InputStream is) { + try { + LineNumberReader reader = new LineNumberReader( + new InputStreamReader(is)); + HashMap colors = new HashMap(); + + format = parseFormat(nextLineOfInterest(reader)); + + // setup color mapping + for (int i = 0; i < format[NUMBER_OF_COLORS]; i++) { + Object[] colorDefinition = parseColor(nextLineOfInterest(reader)); + colors.put((String)colorDefinition[0], (Integer)colorDefinition[1]); + } + + // read actual image (convert to RGBA) + bytes = new byte[format[WIDTH] * format[HEIGHT] * 4]; + for (int i = 0; i < format[HEIGHT]; i++) { + parseImageLine(nextLineOfInterest(reader), format, colors, i); + } + } catch (Exception e) { + e.printStackTrace(); + throw new IllegalArgumentException("Unable to parse XPM File"); + } + } + + /** + * Finds the next interesting line of text. + * + * @param reader + * The LineNumberReader to read from + * @return The next interesting String (with stripped quotes) + * @throws IOException + * If any IO exceptions occurs while reading file + */ + private static String nextLineOfInterest(LineNumberReader reader) + throws IOException { + String ret; + do { + ret = reader.readLine(); + } while (!ret.startsWith("\"")); + // lacks sanity check + return ret.substring(1, ret.lastIndexOf('\"')); + } + + /** + * Parses the format of the xpm file given a format string + * + * @param format + * String to parse + * @return Array specifying width, height, colors, characters per pixel + */ + private static int[] parseFormat(String format) { + // format should look like this: + // 16 16 122 2 + + // tokenize it + StringTokenizer st = new StringTokenizer(format); + + return new int[] { Integer.parseInt(st.nextToken()), /* width */ + Integer.parseInt(st.nextToken()), /* height */ + Integer.parseInt(st.nextToken()), /* colors */ + Integer.parseInt(st.nextToken()) /* chars per pixel */ + }; + } + + /** + * Given a line defining a color/pixel, parses this into an array containing + * a key and a color + * + * @param line + * Line to parse + * @return Array containing a key (String) and a color (Integer) + */ + private static Object[] parseColor(String line) { + // line should look like this: + // # c #0A0A0A + + // NOTE: will break if the color is something like "black" or "gray50" + // etc (instead of #rrggbb). + + String key = line.substring(0, format[CHARACTERS_PER_PIXEL]); + // since we always assume color as type we dont need to read it + // String type = line.substring(format[CHARACTERS_PER_PIXEL] + 1, + // format[CHARACTERS_PER_PIXEL] + 2); + String color = line.substring(format[CHARACTERS_PER_PIXEL] + 4); + + // we always assume type is color, and supplied as # + return new Object[] { key, Integer.parseInt(color, 16) }; + } + + /** + * Parses an Image line into its byte values + * + * @param line + * Line of chars to parse + * @param format + * Format to expext it in + * @param colors + * Colors to lookup + * @param index + * current index into lines, we've reached + */ + private void parseImageLine(String line, int[] format, HashMap colors, + int index) { + // offset for next line + int offset = index * 4 * format[WIDTH]; + + // read characters times, + // each iteration equals one pixel + for (int i = 0; i < format[WIDTH]; i++) { + String key = line + .substring( + i * format[CHARACTERS_PER_PIXEL], + (i * format[CHARACTERS_PER_PIXEL] + format[CHARACTERS_PER_PIXEL])); + int color = colors.get(key); + bytes[offset + (i * 4)] = (byte) ((color & 0x00ff0000) >> 16); + bytes[offset + ((i * 4) + 1)] = (byte) ((color & 0x0000ff00) >> 8); + bytes[offset + ((i * 4) + 2)] = (byte) ((color & 0x000000ff) >> 0); // looks + // better + // :) + bytes[offset + ((i * 4) + 3)] = (byte) 0xff; // always 0xff alpha + } + } + + /** + * @param args + */ + public static void main(String[] args) { + if (args.length != 1) { + System.out.println("usage:\nXPMFile "); + } + + try { + String out = args[0].substring(0, args[0].indexOf(".")) + ".raw"; + XPMFile file = XPMFile.load(args[0]); + BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(new File(out))); + bos.write(file.getBytes()); + bos.close(); + + // showResult(file.getBytes()); + } catch (Exception e) { + e.printStackTrace(); + } + } + /* + private static void showResult(byte[] bytes) { + final BufferedImage i = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB); + int c = 0; + for (int y = 0; y < 16; y++) { + for (int x = 0; x < 16; x++) { + i.setRGB(x, y, (bytes[c] << 16) + (bytes[c + 1] << 8) + (bytes[c + 2] << 0) + (bytes[c + 3] << 24));//+(128<<24));// + c += 4; + } + } + + final Frame frame = new Frame("XPM Result"); + frame.add(new Canvas() { + + public void paint(Graphics g) { + g.drawImage(i, 0, 0, frame); + } + }); + + frame.addWindowListener(new WindowAdapter() { + + public void windowClosing(WindowEvent e) { + frame.dispose(); + } + + }); + + frame.setSize(100, 100); + frame.setVisible(true); + }*/ +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Cylinder.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Cylinder.java new file mode 100644 index 000000000..f720092aa --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Cylinder.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.util.glu.GLU.*; + +/** + * Cylinder.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class Cylinder extends Quadric { + + /** + * Constructor for Cylinder. + */ + public Cylinder() { + super(); + } + + /** + * draws a cylinder oriented along the z axis. The base of the + * cylinder is placed at z = 0, and the top at z=height. Like a sphere, a + * cylinder is subdivided around the z axis into slices, and along the z axis + * into stacks. + * + * Note that if topRadius is set to zero, then this routine will generate a + * cone. + * + * If the orientation is set to GLU.OUTSIDE (with glu.quadricOrientation), then + * any generated normals point away from the z axis. Otherwise, they point + * toward the z axis. + * + * If texturing is turned on (with glu.quadricTexture), then texture + * coordinates are generated so that t ranges linearly from 0.0 at z = 0 to + * 1.0 at z = height, and s ranges from 0.0 at the +y axis, to 0.25 at the +x + * axis, to 0.5 at the -y axis, to 0.75 at the -x axis, and back to 1.0 at the + * +y axis. + * + * @param baseRadius Specifies the radius of the cylinder at z = 0. + * @param topRadius Specifies the radius of the cylinder at z = height. + * @param height Specifies the height of the cylinder. + * @param slices Specifies the number of subdivisions around the z axis. + * @param stacks Specifies the number of subdivisions along the z axis. + */ + public void draw(float baseRadius, float topRadius, float height, int slices, int stacks) { + + float da, r, dr, dz; + float x, y, z, nz, nsign; + int i, j; + + if (super.orientation == GLU_INSIDE) { + nsign = -1.0f; + } else { + nsign = 1.0f; + } + + da = 2.0f * PI / slices; + dr = (topRadius - baseRadius) / stacks; + dz = height / stacks; + nz = (baseRadius - topRadius) / height; + // Z component of normal vectors + + if (super.drawStyle == GLU_POINT) { + glBegin(GL_POINTS); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + + z = 0.0f; + r = baseRadius; + for (j = 0; j <= stacks; j++) { + glVertex3f((x * r), (y * r), z); + z += dz; + r += dr; + } + } + glEnd(); + } else if (super.drawStyle == GLU_LINE || super.drawStyle == GLU_SILHOUETTE) { + // Draw rings + if (super.drawStyle == GLU_LINE) { + z = 0.0f; + r = baseRadius; + for (j = 0; j <= stacks; j++) { + glBegin(GL_LINE_LOOP); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + glVertex3f((x * r), (y * r), z); + } + glEnd(); + z += dz; + r += dr; + } + } else { + // draw one ring at each end + if (baseRadius != 0.0) { + glBegin(GL_LINE_LOOP); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + glVertex3f((x * baseRadius), (y * baseRadius), 0.0f); + } + glEnd(); + glBegin(GL_LINE_LOOP); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + glVertex3f((x * topRadius), (y * topRadius), height); + } + glEnd(); + } + } + // draw length lines + glBegin(GL_LINES); + for (i = 0; i < slices; i++) { + x = cos((i * da)); + y = sin((i * da)); + normal3f(x * nsign, y * nsign, nz * nsign); + glVertex3f((x * baseRadius), (y * baseRadius), 0.0f); + glVertex3f((x * topRadius), (y * topRadius), (height)); + } + glEnd(); + } else if (super.drawStyle == GLU_FILL) { + float ds = 1.0f / slices; + float dt = 1.0f / stacks; + float t = 0.0f; + z = 0.0f; + r = baseRadius; + for (j = 0; j < stacks; j++) { + float s = 0.0f; + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= slices; i++) { + if (i == slices) { + x = sin(0.0f); + y = cos(0.0f); + } else { + x = sin((i * da)); + y = cos((i * da)); + } + if (nsign == 1.0f) { + normal3f((x * nsign), (y * nsign), (nz * nsign)); + TXTR_COORD(s, t); + glVertex3f((x * r), (y * r), z); + normal3f((x * nsign), (y * nsign), (nz * nsign)); + TXTR_COORD(s, t + dt); + glVertex3f((x * (r + dr)), (y * (r + dr)), (z + dz)); + } else { + normal3f(x * nsign, y * nsign, nz * nsign); + TXTR_COORD(s, t); + glVertex3f((x * r), (y * r), z); + normal3f(x * nsign, y * nsign, nz * nsign); + TXTR_COORD(s, t + dt); + glVertex3f((x * (r + dr)), (y * (r + dr)), (z + dz)); + } + s += ds; + } // for slices + glEnd(); + r += dr; + t += dt; + z += dz; + } // for stacks + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Disk.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Disk.java new file mode 100644 index 000000000..18a2b9df1 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Disk.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.util.glu.GLU.*; + +/** + * Disk.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class Disk extends Quadric { + + /** + * Constructor for Disk. + */ + public Disk() { + super(); + } + + /** + * renders a disk on the z = 0 plane. The disk has a radius of + * outerRadius, and contains a concentric circular hole with a radius of + * innerRadius. If innerRadius is 0, then no hole is generated. The disk is + * subdivided around the z axis into slices (like pizza slices), and also + * about the z axis into rings (as specified by slices and loops, + * respectively). + * + * With respect to orientation, the +z side of the disk is considered to be + * "outside" (see glu.quadricOrientation). This means that if the orientation + * is set to GLU.OUTSIDE, then any normals generated point along the +z axis. + * Otherwise, they point along the -z axis. + * + * If texturing is turned on (with glu.quadricTexture), texture coordinates are + * generated linearly such that where r=outerRadius, the value at (r, 0, 0) is + * (1, 0.5), at (0, r, 0) it is (0.5, 1), at (-r, 0, 0) it is (0, 0.5), and at + * (0, -r, 0) it is (0.5, 0). + */ + public void draw(float innerRadius, float outerRadius, int slices, int loops) + { + float da, dr; + + /* Normal vectors */ + if (super.normals != GLU_NONE) { + if (super.orientation == GLU_OUTSIDE) { + glNormal3f(0.0f, 0.0f, +1.0f); + } + else { + glNormal3f(0.0f, 0.0f, -1.0f); + } + } + + da = 2.0f * PI / slices; + dr = (outerRadius - innerRadius) / loops; + + switch (super.drawStyle) { + case GLU_FILL: + { + /* texture of a gluDisk is a cut out of the texture unit square + * x, y in [-outerRadius, +outerRadius]; s, t in [0, 1] + * (linear mapping) + */ + float dtc = 2.0f * outerRadius; + float sa, ca; + float r1 = innerRadius; + int l; + for (l = 0; l < loops; l++) { + float r2 = r1 + dr; + if (super.orientation == GLU_OUTSIDE) { + int s; + glBegin(GL_QUAD_STRIP); + for (s = 0; s <= slices; s++) { + float a; + if (s == slices) + a = 0.0f; + else + a = s * da; + sa = sin(a); + ca = cos(a); + TXTR_COORD(0.5f + sa * r2 / dtc, 0.5f + ca * r2 / dtc); + glVertex2f(r2 * sa, r2 * ca); + TXTR_COORD(0.5f + sa * r1 / dtc, 0.5f + ca * r1 / dtc); + glVertex2f(r1 * sa, r1 * ca); + } + glEnd(); + } + else { + int s; + glBegin(GL_QUAD_STRIP); + for (s = slices; s >= 0; s--) { + float a; + if (s == slices) + a = 0.0f; + else + a = s * da; + sa = sin(a); + ca = cos(a); + TXTR_COORD(0.5f - sa * r2 / dtc, 0.5f + ca * r2 / dtc); + glVertex2f(r2 * sa, r2 * ca); + TXTR_COORD(0.5f - sa * r1 / dtc, 0.5f + ca * r1 / dtc); + glVertex2f(r1 * sa, r1 * ca); + } + glEnd(); + } + r1 = r2; + } + break; + } + case GLU_LINE: + { + int l, s; + /* draw loops */ + for (l = 0; l <= loops; l++) { + float r = innerRadius + l * dr; + glBegin(GL_LINE_LOOP); + for (s = 0; s < slices; s++) { + float a = s * da; + glVertex2f(r * sin(a), r * cos(a)); + } + glEnd(); + } + /* draw spokes */ + for (s = 0; s < slices; s++) { + float a = s * da; + float x = sin(a); + float y = cos(a); + glBegin(GL_LINE_STRIP); + for (l = 0; l <= loops; l++) { + float r = innerRadius + l * dr; + glVertex2f(r * x, r * y); + } + glEnd(); + } + break; + } + case GLU_POINT: + { + int s; + glBegin(GL_POINTS); + for (s = 0; s < slices; s++) { + float a = s * da; + float x = sin(a); + float y = cos(a); + int l; + for (l = 0; l <= loops; l++) { + float r = innerRadius * l * dr; + glVertex2f(r * x, r * y); + } + } + glEnd(); + break; + } + case GLU_SILHOUETTE: + { + if (innerRadius != 0.0) { + float a; + glBegin(GL_LINE_LOOP); + for (a = 0.0f; a < 2.0 * PI; a += da) { + float x = innerRadius * sin(a); + float y = innerRadius * cos(a); + glVertex2f(x, y); + } + glEnd(); + } + { + float a; + glBegin(GL_LINE_LOOP); + for (a = 0; a < 2.0f * PI; a += da) { + float x = outerRadius * sin(a); + float y = outerRadius * cos(a); + glVertex2f(x, y); + } + glEnd(); + } + break; + } + default: + return; + } + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLU.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLU.java new file mode 100644 index 000000000..ba99ed1b9 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLU.java @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.util.glu.tessellation.GLUtessellatorImpl; +import org.lwjgl.opengl.Util; + +import static org.lwjgl.opengl.GL11.*; + +/** + * GLU.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class GLU { + static final float PI = (float)Math.PI; + + /* Errors: (return value 0 = no error) */ + public static final int GLU_INVALID_ENUM = 100900; + public static final int GLU_INVALID_VALUE = 100901; + public static final int GLU_OUT_OF_MEMORY = 100902; + public static final int GLU_INCOMPATIBLE_GL_VERSION = 100903; + + /* StringName */ + public static final int GLU_VERSION = 100800; + public static final int GLU_EXTENSIONS = 100801; + + /* Boolean */ + public static final boolean GLU_TRUE = true; + public static final boolean GLU_FALSE = false; + + + /**** Quadric constants ****/ + + /* QuadricNormal */ + public static final int GLU_SMOOTH = 100000; + public static final int GLU_FLAT = 100001; + public static final int GLU_NONE = 100002; + + /* QuadricDrawStyle */ + public static final int GLU_POINT = 100010; + public static final int GLU_LINE = 100011; + public static final int GLU_FILL = 100012; + public static final int GLU_SILHOUETTE = 100013; + + /* QuadricOrientation */ + public static final int GLU_OUTSIDE = 100020; + public static final int GLU_INSIDE = 100021; + + /* Callback types: */ + /* ERROR = 100103 */ + + + /**** Tesselation constants ****/ + + public static final double GLU_TESS_MAX_COORD = 1.0e150; + public static final double TESS_MAX_COORD = 1.0e150; + + /* TessProperty */ + public static final int GLU_TESS_WINDING_RULE = 100140; + public static final int GLU_TESS_BOUNDARY_ONLY = 100141; + public static final int GLU_TESS_TOLERANCE = 100142; + + /* TessWinding */ + public static final int GLU_TESS_WINDING_ODD = 100130; + public static final int GLU_TESS_WINDING_NONZERO = 100131; + public static final int GLU_TESS_WINDING_POSITIVE = 100132; + public static final int GLU_TESS_WINDING_NEGATIVE = 100133; + public static final int GLU_TESS_WINDING_ABS_GEQ_TWO = 100134; + + /* TessCallback */ + public static final int GLU_TESS_BEGIN = 100100; /* void (CALLBACK*)(GLenum type) */ + public static final int GLU_TESS_VERTEX = 100101; /* void (CALLBACK*)(void *data) */ + public static final int GLU_TESS_END = 100102; /* void (CALLBACK*)(void) */ + public static final int GLU_TESS_ERROR = 100103; /* void (CALLBACK*)(GLenum errno) */ + public static final int GLU_TESS_EDGE_FLAG = 100104; /* void (CALLBACK*)(GLboolean boundaryEdge) */ + public static final int GLU_TESS_COMBINE = 100105; /* void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut) */ + public static final int GLU_TESS_BEGIN_DATA = 100106; /* void (CALLBACK*)(GLenum type, + void *polygon_data) */ + public static final int GLU_TESS_VERTEX_DATA = 100107; /* void (CALLBACK*)(void *data, + void *polygon_data) */ + public static final int GLU_TESS_END_DATA = 100108; /* void (CALLBACK*)(void *polygon_data) */ + public static final int GLU_TESS_ERROR_DATA = 100109; /* void (CALLBACK*)(GLenum errno, + void *polygon_data) */ + public static final int GLU_TESS_EDGE_FLAG_DATA = 100110; /* void (CALLBACK*)(GLboolean boundaryEdge, + void *polygon_data) */ + public static final int GLU_TESS_COMBINE_DATA = 100111; /* void (CALLBACK*)(GLdouble coords[3], + void *data[4], + GLfloat weight[4], + void **dataOut, + void *polygon_data) */ + + /* TessError */ + public static final int GLU_TESS_ERROR1 = 100151; + public static final int GLU_TESS_ERROR2 = 100152; + public static final int GLU_TESS_ERROR3 = 100153; + public static final int GLU_TESS_ERROR4 = 100154; + public static final int GLU_TESS_ERROR5 = 100155; + public static final int GLU_TESS_ERROR6 = 100156; + public static final int GLU_TESS_ERROR7 = 100157; + public static final int GLU_TESS_ERROR8 = 100158; + + public static final int GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1; + public static final int GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2; + public static final int GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3; + public static final int GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4; + public static final int GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5; + public static final int GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6; + + /**** NURBS constants ****/ + + /* NurbsProperty */ + public static final int GLU_AUTO_LOAD_MATRIX = 100200; + public static final int GLU_CULLING = 100201; + public static final int GLU_SAMPLING_TOLERANCE = 100203; + public static final int GLU_DISPLAY_MODE = 100204; + public static final int GLU_PARAMETRIC_TOLERANCE = 100202; + public static final int GLU_SAMPLING_METHOD = 100205; + public static final int GLU_U_STEP = 100206; + public static final int GLU_V_STEP = 100207; + + /* NurbsSampling */ + public static final int GLU_PATH_LENGTH = 100215; + public static final int GLU_PARAMETRIC_ERROR = 100216; + public static final int GLU_DOMAIN_DISTANCE = 100217; + + + /* NurbsTrim */ + public static final int GLU_MAP1_TRIM_2 = 100210; + public static final int GLU_MAP1_TRIM_3 = 100211; + + /* NurbsDisplay */ + /* FILL = 100012 */ + public static final int GLU_OUTLINE_POLYGON = 100240; + public static final int GLU_OUTLINE_PATCH = 100241; + + /* NurbsCallback */ + /* ERROR = 100103 */ + + /* NurbsErrors */ + public static final int GLU_NURBS_ERROR1 = 100251; + public static final int GLU_NURBS_ERROR2 = 100252; + public static final int GLU_NURBS_ERROR3 = 100253; + public static final int GLU_NURBS_ERROR4 = 100254; + public static final int GLU_NURBS_ERROR5 = 100255; + public static final int GLU_NURBS_ERROR6 = 100256; + public static final int GLU_NURBS_ERROR7 = 100257; + public static final int GLU_NURBS_ERROR8 = 100258; + public static final int GLU_NURBS_ERROR9 = 100259; + public static final int GLU_NURBS_ERROR10 = 100260; + public static final int GLU_NURBS_ERROR11 = 100261; + public static final int GLU_NURBS_ERROR12 = 100262; + public static final int GLU_NURBS_ERROR13 = 100263; + public static final int GLU_NURBS_ERROR14 = 100264; + public static final int GLU_NURBS_ERROR15 = 100265; + public static final int GLU_NURBS_ERROR16 = 100266; + public static final int GLU_NURBS_ERROR17 = 100267; + public static final int GLU_NURBS_ERROR18 = 100268; + public static final int GLU_NURBS_ERROR19 = 100269; + public static final int GLU_NURBS_ERROR20 = 100270; + public static final int GLU_NURBS_ERROR21 = 100271; + public static final int GLU_NURBS_ERROR22 = 100272; + public static final int GLU_NURBS_ERROR23 = 100273; + public static final int GLU_NURBS_ERROR24 = 100274; + public static final int GLU_NURBS_ERROR25 = 100275; + public static final int GLU_NURBS_ERROR26 = 100276; + public static final int GLU_NURBS_ERROR27 = 100277; + public static final int GLU_NURBS_ERROR28 = 100278; + public static final int GLU_NURBS_ERROR29 = 100279; + public static final int GLU_NURBS_ERROR30 = 100280; + public static final int GLU_NURBS_ERROR31 = 100281; + public static final int GLU_NURBS_ERROR32 = 100282; + public static final int GLU_NURBS_ERROR33 = 100283; + public static final int GLU_NURBS_ERROR34 = 100284; + public static final int GLU_NURBS_ERROR35 = 100285; + public static final int GLU_NURBS_ERROR36 = 100286; + public static final int GLU_NURBS_ERROR37 = 100287; + + /* Contours types -- obsolete! */ + public static final int GLU_CW = 100120; + public static final int GLU_CCW = 100121; + public static final int GLU_INTERIOR = 100122; + public static final int GLU_EXTERIOR = 100123; + public static final int GLU_UNKNOWN = 100124; + + /* Names without "TESS_" prefix */ + public static final int GLU_BEGIN = GLU_TESS_BEGIN; + public static final int GLU_VERTEX = GLU_TESS_VERTEX; + public static final int GLU_END = GLU_TESS_END; + public static final int GLU_ERROR = GLU_TESS_ERROR; + public static final int GLU_EDGE_FLAG = GLU_TESS_EDGE_FLAG; + + /** + * Method gluLookAt + * @param eyex + * @param eyey + * @param eyez + * @param centerx + * @param centery + * @param centerz + * @param upx + * @param upy + * @param upz + */ + public static void gluLookAt( + float eyex, + float eyey, + float eyez, + float centerx, + float centery, + float centerz, + float upx, + float upy, + float upz) { + + Project.gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz); + } + + /** + * Method gluOrtho2D + * @param left + * @param right + * @param bottom + * @param top + */ + public static void gluOrtho2D( + float left, + float right, + float bottom, + float top) { + + glOrtho(left, right, bottom, top, -1.0, 1.0); + } + + /** + * Method gluPerspective + * @param fovy + * @param aspect + * @param zNear + * @param zFar + */ + public static void gluPerspective( + float fovy, + float aspect, + float zNear, + float zFar) { + + Project.gluPerspective(fovy, aspect, zNear, zFar); + } + + /** + * Method gluProject + * @param objx + * @param objy + * @param objz + * @param modelMatrix + * @param projMatrix + * @param viewport + * @param win_pos + */ + public static boolean gluProject(float objx, float objy, float objz, + FloatBuffer modelMatrix, + FloatBuffer projMatrix, + IntBuffer viewport, + FloatBuffer win_pos) + { + return Project.gluProject(objx, objy, objz, modelMatrix, projMatrix, viewport, win_pos); + } + + /** + * Method gluUnproject + * @param winx + * @param winy + * @param winz + * @param modelMatrix + * @param projMatrix + * @param viewport + * @param obj_pos + */ + public static boolean gluUnProject(float winx, float winy, float winz, + FloatBuffer modelMatrix, + FloatBuffer projMatrix, + IntBuffer viewport, + FloatBuffer obj_pos) + { + return Project.gluUnProject(winx, winy, winz, modelMatrix, projMatrix, viewport, obj_pos); + } + + /** + * Method gluPickMatrix + * @param x + * @param y + * @param width + * @param height + * @param viewport + */ + public static void gluPickMatrix( + float x, + float y, + float width, + float height, + IntBuffer viewport) { + + Project.gluPickMatrix(x, y, width, height, viewport); + } + + /** + * Method gluGetString. + * @param name + * @return String + */ + public static String gluGetString(int name) { + return Registry.gluGetString(name); + } + + /** + * Method gluCheckExtension. + * @param extName + * @param extString + * @return boolean + */ + public static boolean gluCheckExtension(String extName, String extString) { + return Registry.gluCheckExtension(extName, extString); + } + + /** + * Method gluBuild2DMipmaps + * @param target + * @param components + * @param width + * @param height + * @param format + * @param type + * @param data + * @return int + */ + public static int gluBuild2DMipmaps( + int target, + int components, + int width, + int height, + int format, + int type, + ByteBuffer data) { + + return MipMap.gluBuild2DMipmaps(target, components, width, height, format, type, data); + } + + /** + * Method gluScaleImage. + * @param format + * @param widthIn + * @param heightIn + * @param typeIn + * @param dataIn + * @param widthOut + * @param heightOut + * @param typeOut + * @param dataOut + * @return int + */ + public static int gluScaleImage( + int format, + int widthIn, + int heightIn, + int typeIn, + ByteBuffer dataIn, + int widthOut, + int heightOut, + int typeOut, + ByteBuffer dataOut) { + + return MipMap.gluScaleImage(format, widthIn, heightIn, typeIn, dataIn, widthOut, heightOut, typeOut, dataOut); + } + + public static String gluErrorString(int error_code) { + switch (error_code) { + case GLU_INVALID_ENUM: + return "Invalid enum (glu)"; + case GLU_INVALID_VALUE: + return "Invalid value (glu)"; + case GLU_OUT_OF_MEMORY: + return "Out of memory (glu)"; + default: + return Util.translateGLErrorString(error_code); + } + } + + public static GLUtessellator gluNewTess() { + return new GLUtessellatorImpl(); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellator.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellator.java new file mode 100644 index 000000000..90c07ff9a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellator.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.lwjgl.util.glu; + +public interface GLUtessellator { + + void gluDeleteTess(); + + void gluTessProperty(int which, double value); + + /* Returns tessellator property */ + void gluGetTessProperty(int which, double[] value, + int value_offset); /* gluGetTessProperty() */ + + void gluTessNormal(double x, double y, double z); + + void gluTessCallback(int which, + GLUtessellatorCallback aCallback); + + void gluTessVertex(double[] coords, int coords_offset, + Object vertexData); + + void gluTessBeginPolygon(Object data); + + void gluTessBeginContour(); + + void gluTessEndContour(); + + void gluTessEndPolygon(); + + /*******************************************************/ + + /* Obsolete calls -- for backward compatibility */ + + void gluBeginPolygon(); + + /*ARGSUSED*/ + void gluNextContour(int type); + + void gluEndPolygon(); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallback.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallback.java new file mode 100644 index 000000000..0f913f778 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallback.java @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu; + +/** + * GLUtessellatorCallback interface provides methods that the user will + * override to define the callbacks for a tessellation object. + * + * @author Eric Veach, July 1994 + * @author Java Port: Pepijn Van Eeckhoudt, July 2003 + * @author Java Port: Nathan Parker Burg, August 2003 + */ +public interface GLUtessellatorCallback { + /** + * The begin callback method is invoked like + * {@link javax.media.opengl.GL#glBegin glBegin} to indicate the start of a + * (triangle) primitive. The method takes a single argument of type int. If + * the GLU_TESS_BOUNDARY_ONLY property is set to GL_FALSE, then + * the argument is set to either GL_TRIANGLE_FAN, + * GL_TRIANGLE_STRIP, or GL_TRIANGLES. If the + * GLU_TESS_BOUNDARY_ONLY property is set to GL_TRUE, then the + * argument will be set to GL_LINE_LOOP. + * + * @param type + * Specifics the type of begin/end pair being defined. The following + * values are valid: GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, + * GL_TRIANGLES or GL_LINE_LOOP. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #end end + * @see #begin begin + */ + void begin(int type); + + /** + * The same as the {@link #begin begin} callback method except that + * it takes an additional reference argument. This reference is + * identical to the opaque reference provided when {@link + * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param type + * Specifics the type of begin/end pair being defined. The following + * values are valid: GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, + * GL_TRIANGLES or GL_LINE_LOOP. + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #endData endData + * @see #begin begin + */ + void beginData(int type, Object polygonData); + + + /** + * The edgeFlag callback method is similar to + * {@link javax.media.opengl.GL#glEdgeFlag glEdgeFlag}. The method takes + * a single boolean boundaryEdge that indicates which edges lie on the + * polygon boundary. If the boundaryEdge is GL_TRUE, then each vertex + * that follows begins an edge that lies on the polygon boundary, that is, + * an edge that separates an interior region from an exterior one. If the + * boundaryEdge is GL_FALSE, then each vertex that follows begins an + * edge that lies in the polygon interior. The edge flag callback (if + * defined) is invoked before the first vertex callback.

+ * + * Since triangle fans and triangle strips do not support edge flags, the + * begin callback is not called with GL_TRIANGLE_FAN or + * GL_TRIANGLE_STRIP if a non-null edge flag callback is provided. + * (If the callback is initialized to null, there is no impact on + * performance). Instead, the fans and strips are converted to independent + * triangles. + * + * @param boundaryEdge + * Specifics which edges lie on the polygon boundary. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #edgeFlagData edgeFlagData + */ + void edgeFlag(boolean boundaryEdge); + + + /** + * The same as the {@link #edgeFlag edgeFlage} callback method + * except that it takes an additional reference argument. This + * reference is identical to the opaque reference provided when + * {@link GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param boundaryEdge + * Specifics which edges lie on the polygon boundary. + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #edgeFlag edgeFlag + */ + void edgeFlagData(boolean boundaryEdge, Object polygonData); + + + /** + * The vertex callback method is invoked between the {@link + * #begin begin} and {@link #end end} callback methods. It is + * similar to {@link javax.media.opengl.GL#glVertex3f glVertex3f}, + * and it defines the vertices of the triangles created by the + * tessellation process. The method takes a reference as its only + * argument. This reference is identical to the opaque reference + * provided by the user when the vertex was described (see {@link + * GLU#gluTessVertex gluTessVertex}). + * + * @param vertexData + * Specifics a reference to the vertices of the triangles created + * byt the tessellatin process. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #vertexData vertexData + */ + void vertex(Object vertexData); + + + /** + * The same as the {@link #vertex vertex} callback method except + * that it takes an additional reference argument. This reference is + * identical to the opaque reference provided when {@link + * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param vertexData + * Specifics a reference to the vertices of the triangles created + * byt the tessellatin process. + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #vertex vertex + */ + void vertexData(Object vertexData, Object polygonData); + + + /** + * The end callback serves the same purpose as + * {@link javax.media.opengl.GL#glEnd glEnd}. It indicates the end of a + * primitive and it takes no arguments. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #begin begin + * @see #endData endData + */ + void end(); + + + /** + * The same as the {@link #end end} callback method except that it + * takes an additional reference argument. This reference is + * identical to the opaque reference provided when {@link + * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #beginData beginData + * @see #end end + */ + void endData(Object polygonData); + + + /** + * The combine callback method is called to create a new vertex when + * the tessellation detects an intersection, or wishes to merge features. The + * method takes four arguments: an array of three elements each of type + * double, an array of four references, an array of four elements each of + * type float, and a reference to a reference.

+ * + * The vertex is defined as a linear combination of up to four existing + * vertices, stored in data. The coefficients of the linear combination + * are given by weight; these weights always add up to 1. All vertex + * pointers are valid even when some of the weights are 0. coords gives + * the location of the new vertex.

+ * + * The user must allocate another vertex, interpolate parameters using + * data and weight, and return the new vertex pointer in + * outData. This handle is supplied during rendering callbacks. The + * user is responsible for freeing the memory some time after + * {@link GLU#gluTessEndPolygon gluTessEndPolygon} is + * called.

+ * + * For example, if the polygon lies in an arbitrary plane in 3-space, and a + * color is associated with each vertex, the GLU_TESS_COMBINE + * callback might look like this: + * + *

+   *         void myCombine(double[] coords, Object[] data,
+   *                        float[] weight, Object[] outData)
+   *         {
+   *            MyVertex newVertex = new MyVertex();
+   *
+   *            newVertex.x = coords[0];
+   *            newVertex.y = coords[1];
+   *            newVertex.z = coords[2];
+   *            newVertex.r = weight[0]*data[0].r +
+   *                          weight[1]*data[1].r +
+   *                          weight[2]*data[2].r +
+   *                          weight[3]*data[3].r;
+   *            newVertex.g = weight[0]*data[0].g +
+   *                          weight[1]*data[1].g +
+   *                          weight[2]*data[2].g +
+   *                          weight[3]*data[3].g;
+   *            newVertex.b = weight[0]*data[0].b +
+   *                          weight[1]*data[1].b +
+   *                          weight[2]*data[2].b +
+   *                          weight[3]*data[3].b;
+   *            newVertex.a = weight[0]*data[0].a +
+   *                          weight[1]*data[1].a +
+   *                          weight[2]*data[2].a +
+   *                          weight[3]*data[3].a;
+   *            outData = newVertex;
+   *         }
+ * + * @param coords + * Specifics the location of the new vertex. + * @param data + * Specifics the vertices used to create the new vertex. + * @param weight + * Specifics the weights used to create the new vertex. + * @param outData + * Reference user the put the coodinates of the new vertex. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #combineData combineData + */ + void combine(double[] coords, Object[] data, + float[] weight, Object[] outData); + + + /** + * The same as the {@link #combine combine} callback method except + * that it takes an additional reference argument. This reference is + * identical to the opaque reference provided when {@link + * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param coords + * Specifics the location of the new vertex. + * @param data + * Specifics the vertices used to create the new vertex. + * @param weight + * Specifics the weights used to create the new vertex. + * @param outData + * Reference user the put the coodinates of the new vertex. + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #combine combine + */ + void combineData(double[] coords, Object[] data, + float[] weight, Object[] outData, + Object polygonData); + + + /** + * The error callback method is called when an error is encountered. + * The one argument is of type int; it indicates the specific error that + * occurred and will be set to one of GLU_TESS_MISSING_BEGIN_POLYGON, + * GLU_TESS_MISSING_END_POLYGON, GLU_TESS_MISSING_BEGIN_CONTOUR, + * GLU_TESS_MISSING_END_CONTOUR, GLU_TESS_COORD_TOO_LARGE, + * GLU_TESS_NEED_COMBINE_CALLBACK or GLU_OUT_OF_MEMORY. + * Character strings describing these errors can be retrieved with the + * {@link GLU#gluErrorString gluErrorString} call.

+ * + * The GLU library will recover from the first four errors by inserting the + * missing call(s). GLU_TESS_COORD_TOO_LARGE indicates that some + * vertex coordinate exceeded the predefined constant + * GLU_TESS_MAX_COORD in absolute value, and that the value has been + * clamped. (Coordinate values must be small enough so that two can be + * multiplied together without overflow.) + * GLU_TESS_NEED_COMBINE_CALLBACK indicates that the tessellation + * detected an intersection between two edges in the input data, and the + * GLU_TESS_COMBINE or GLU_TESS_COMBINE_DATA callback was not + * provided. No output is generated. GLU_OUT_OF_MEMORY indicates that + * there is not enough memory so no output is generated. + * + * @param errnum + * Specifics the error number code. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #errorData errorData + */ + void error(int errnum); + + + /** + * The same as the {@link #error error} callback method except that + * it takes an additional reference argument. This reference is + * identical to the opaque reference provided when {@link + * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param errnum + * Specifics the error number code. + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #error error + */ + void errorData(int errnum, Object polygonData); + + //void mesh(com.sun.opengl.impl.tessellator.GLUmesh mesh); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallbackAdapter.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallbackAdapter.java new file mode 100644 index 000000000..742529b47 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/GLUtessellatorCallbackAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu; + +/** + * The GLUtessellatorCallbackAdapter provides a default implementation of + * {@link GLUtessellatorCallback GLUtessellatorCallback} + * with empty callback methods. This class can be extended to provide user + * defined callback methods. + * + * @author Eric Veach, July 1994 + * @author Java Port: Pepijn Van Eechhoudt, July 2003 + * @author Java Port: Nathan Parker Burg, August 2003 + */ + +public class GLUtessellatorCallbackAdapter implements GLUtessellatorCallback { + public void begin(int type) {} + public void edgeFlag(boolean boundaryEdge) {} + public void vertex(Object vertexData) {} + public void end() {} +// public void mesh(com.sun.opengl.impl.tessellator.GLUmesh mesh) {} + public void error(int errnum) {} + public void combine(double[] coords, Object[] data, + float[] weight, Object[] outData) {} + public void beginData(int type, Object polygonData) {} + public void edgeFlagData(boolean boundaryEdge, + Object polygonData) {} + public void vertexData(Object vertexData, Object polygonData) {} + public void endData(Object polygonData) {} + public void errorData(int errnum, Object polygonData) {} + public void combineData(double[] coords, Object[] data, + float[] weight, Object[] outData, + Object polygonData) {} +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/MipMap.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/MipMap.java new file mode 100644 index 000000000..d3ba8ef73 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/MipMap.java @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import java.nio.ByteBuffer; + +import org.lwjgl.BufferUtils; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.util.glu.GLU.*; + +/** + * MipMap.java + * + * + * Created 11-jan-2004 + * @author Erik Duijs + */ +public class MipMap extends Util { + + /** + * Method gluBuild2DMipmaps + * + * @param target + * @param components + * @param width + * @param height + * @param format + * @param type + * @param data + * @return int + */ + public static int gluBuild2DMipmaps(final int target, + final int components, final int width, final int height, + final int format, final int type, final ByteBuffer data) { + if ( width < 1 || height < 1 ) return GLU_INVALID_VALUE; + + final int bpp = bytesPerPixel(format, type); + if ( bpp == 0 ) + return GLU_INVALID_ENUM; + + final int maxSize = glGetInteger(GL_MAX_TEXTURE_SIZE); + + int w = nearestPower(width); + if ( w > maxSize ) + w = maxSize; + + int h = nearestPower(height); + if ( h > maxSize ) + h = maxSize; + + // Get current glPixelStore state + PixelStoreState pss = new PixelStoreState(); + + // set pixel packing + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + + ByteBuffer image; + int retVal = 0; + boolean done = false; + + if ( w != width || h != height ) { + // must rescale image to get "top" mipmap texture image + image = BufferUtils.createByteBuffer((w + 4) * h * bpp); + int error = gluScaleImage(format, width, height, type, data, w, h, type, image); + if ( error != 0 ) { + retVal = error; + done = true; + } + + /* set pixel unpacking */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + } else { + image = data; + } + + ByteBuffer bufferA = null; + ByteBuffer bufferB = null; + + int level = 0; + while ( !done ) { + if (image != data) { + /* set pixel unpacking */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + } + + glTexImage2D(target, level, components, w, h, 0, format, type, image); + + if ( w == 1 && h == 1 ) + break; + + final int newW = (w < 2) ? 1 : w >> 1; + final int newH = (h < 2) ? 1 : h >> 1; + + final ByteBuffer newImage; + + if ( bufferA == null ) + newImage = (bufferA = BufferUtils.createByteBuffer((newW + 4) * newH * bpp)); + else if ( bufferB == null ) + newImage = (bufferB = BufferUtils.createByteBuffer((newW + 4) * newH * bpp)); + else + newImage = bufferB; + + int error = gluScaleImage(format, w, h, type, image, newW, newH, type, newImage); + if ( error != 0 ) { + retVal = error; + done = true; + } + + image = newImage; + if ( bufferB != null ) + bufferB = bufferA; + + w = newW; + h = newH; + level++; + } + + // Restore original glPixelStore state + pss.save(); + + return retVal; + } + + /** + * Method gluScaleImage. + * @param format + * @param widthIn + * @param heightIn + * @param typein + * @param dataIn + * @param widthOut + * @param heightOut + * @param typeOut + * @param dataOut + * @return int + */ + public static int gluScaleImage(int format, + int widthIn, int heightIn, int typein, ByteBuffer dataIn, + int widthOut, int heightOut, int typeOut, ByteBuffer dataOut) { + + final int components = compPerPix(format); + if ( components == -1 ) + return GLU_INVALID_ENUM; + + int i, j, k; + float[] tempIn, tempOut; + float sx, sy; + int sizein, sizeout; + int rowstride, rowlen; + + // temp image data + tempIn = new float[widthIn * heightIn * components]; + tempOut = new float[widthOut * heightOut * components]; + + // Determine bytes per input type + switch ( typein ) { + case GL_UNSIGNED_BYTE: + sizein = 1; + break; + case GL_FLOAT: + sizein = 4; + break; + default: + return GL_INVALID_ENUM; + } + + // Determine bytes per output type + switch ( typeOut ) { + case GL_UNSIGNED_BYTE: + sizeout = 1; + break; + case GL_FLOAT: + sizeout = 4; + break; + default: + return GL_INVALID_ENUM; + } + + // Get glPixelStore state + PixelStoreState pss = new PixelStoreState(); + + //Unpack the pixel data and convert to floating point + if ( pss.unpackRowLength > 0 ) + rowlen = pss.unpackRowLength; + else + rowlen = widthIn; + + if ( sizein >= pss.unpackAlignment ) + rowstride = components * rowlen; + else + rowstride = pss.unpackAlignment / sizein * ceil(components * rowlen * sizein, pss.unpackAlignment); + + switch ( typein ) { + case GL_UNSIGNED_BYTE: + k = 0; + dataIn.rewind(); + for ( i = 0; i < heightIn; i++ ) { + int ubptr = i * rowstride + pss.unpackSkipRows * rowstride + pss.unpackSkipPixels * components; + for ( j = 0; j < widthIn * components; j++ ) { + tempIn[k++] = dataIn.get(ubptr++) & 0xff; + } + } + break; + case GL_FLOAT: + k = 0; + dataIn.rewind(); + for ( i = 0; i < heightIn; i++ ) + { + int fptr = 4 * (i * rowstride + pss.unpackSkipRows * rowstride + pss.unpackSkipPixels * components); + for ( j = 0; j < widthIn * components; j++ ) + { + tempIn[k++] = dataIn.getFloat(fptr); + fptr += 4; + } + } + break; + default: + return GLU_INVALID_ENUM; + } + + // Do scaling + sx = (float)widthIn / (float)widthOut; + sy = (float)heightIn / (float)heightOut; + + float[] c = new float[components]; + int src, dst; + + for ( int iy = 0; iy < heightOut; iy++ ) { + for ( int ix = 0; ix < widthOut; ix++ ) { + int x0 = (int)(ix * sx); + int x1 = (int)((ix + 1) * sx); + int y0 = (int)(iy * sy); + int y1 = (int)((iy + 1) * sy); + + int readPix = 0; + + // reset weighted pixel + for ( int ic = 0; ic < components; ic++ ) { + c[ic] = 0; + } + + // create weighted pixel + for ( int ix0 = x0; ix0 < x1; ix0++ ) { + for ( int iy0 = y0; iy0 < y1; iy0++ ) { + + src = (iy0 * widthIn + ix0) * components; + + for ( int ic = 0; ic < components; ic++ ) { + c[ic] += tempIn[src + ic]; + } + + readPix++; + } + } + + // store weighted pixel + dst = (iy * widthOut + ix) * components; + + if ( readPix == 0 ) { + // Image is sized up, caused by non power of two texture as input + src = (y0 * widthIn + x0) * components; + for ( int ic = 0; ic < components; ic++ ) { + tempOut[dst++] = tempIn[src + ic]; + } + } else { + // sized down + for ( k = 0; k < components; k++ ) { + tempOut[dst++] = c[k] / readPix; + } + } + } + } + + + // Convert temp output + if ( pss.packRowLength > 0 ) + rowlen = pss.packRowLength; + else + rowlen = widthOut; + + if ( sizeout >= pss.packAlignment ) + rowstride = components * rowlen; + else + rowstride = pss.packAlignment / sizeout * ceil(components * rowlen * sizeout, pss.packAlignment); + + switch ( typeOut ) { + case GL_UNSIGNED_BYTE: + k = 0; + for ( i = 0; i < heightOut; i++ ) { + int ubptr = i * rowstride + pss.packSkipRows * rowstride + pss.packSkipPixels * components; + + for ( j = 0; j < widthOut * components; j++ ) { + dataOut.put(ubptr++, (byte)tempOut[k++]); + } + } + break; + case GL_FLOAT: + k = 0; + for ( i = 0; i < heightOut; i++ ) { + int fptr = 4 * (i * rowstride + pss.unpackSkipRows * rowstride + pss.unpackSkipPixels * components); + + for ( j = 0; j < widthOut * components; j++ ) { + dataOut.putFloat(fptr, tempOut[k++]); + fptr += 4; + } + } + break; + default: + return GLU_INVALID_ENUM; + } + + return 0; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PartialDisk.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PartialDisk.java new file mode 100644 index 000000000..e811436e8 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PartialDisk.java @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.util.glu.GLU.*; + +/** + * PartialDisk.java + * + * + * Created 23-dec-2003 + * + * @author Erik Duijs + */ +public class PartialDisk extends Quadric { + + private static final int CACHE_SIZE = 240; + + /** + * Constructor for PartialDisk. + */ + public PartialDisk() { + super(); + } + + /** + * renders a partial disk on the z=0 plane. A partial disk is similar to a + * full disk, except that only the subset of the disk from startAngle + * through startAngle + sweepAngle is included (where 0 degrees is along + * the +y axis, 90 degrees along the +x axis, 180 along the -y axis, and + * 270 along the -x axis). + * + * The partial disk has a radius of outerRadius, and contains a concentric + * circular hole with a radius of innerRadius. If innerRadius is zero, then + * no hole is generated. The partial disk is subdivided around the z axis + * into slices (like pizza slices), and also about the z axis into rings + * (as specified by slices and loops, respectively). + * + * With respect to orientation, the +z side of the partial disk is + * considered to be outside (see gluQuadricOrientation). This means that if + * the orientation is set to GLU.GLU_OUTSIDE, then any normals generated point + * along the +z axis. Otherwise, they point along the -z axis. + * + * If texturing is turned on (with gluQuadricTexture), texture coordinates + * are generated linearly such that where r=outerRadius, the value at (r, 0, 0) + * is (1, 0.5), at (0, r, 0) it is (0.5, 1), at (-r, 0, 0) it is (0, 0.5), + * and at (0, -r, 0) it is (0.5, 0). + */ + public void draw( + float innerRadius, + float outerRadius, + int slices, + int loops, + float startAngle, + float sweepAngle) { + + int i, j; + float[] sinCache = new float[CACHE_SIZE]; + float[] cosCache = new float[CACHE_SIZE]; + float angle; + float sintemp, costemp; + float deltaRadius; + float radiusLow, radiusHigh; + float texLow = 0, texHigh = 0; + float angleOffset; + int slices2; + int finish; + + if (slices >= CACHE_SIZE) + slices = CACHE_SIZE - 1; + if (slices < 2 + || loops < 1 + || outerRadius <= 0.0f + || innerRadius < 0.0f + || innerRadius > outerRadius) { + //gluQuadricError(qobj, GLU.GLU_INVALID_VALUE); + System.err.println("PartialDisk: GLU_INVALID_VALUE"); + return; + } + + if (sweepAngle < -360.0f) + sweepAngle = 360.0f; + if (sweepAngle > 360.0f) + sweepAngle = 360.0f; + if (sweepAngle < 0) { + startAngle += sweepAngle; + sweepAngle = -sweepAngle; + } + + if (sweepAngle == 360.0f) { + slices2 = slices; + } else { + slices2 = slices + 1; + } + + /* Compute length (needed for normal calculations) */ + deltaRadius = outerRadius - innerRadius; + + /* Cache is the vertex locations cache */ + + angleOffset = startAngle / 180.0f * PI; + for (i = 0; i <= slices; i++) { + angle = angleOffset + ((PI * sweepAngle) / 180.0f) * i / slices; + sinCache[i] = sin(angle); + cosCache[i] = cos(angle); + } + + if (sweepAngle == 360.0f) { + sinCache[slices] = sinCache[0]; + cosCache[slices] = cosCache[0]; + } + + switch (super.normals) { + case GLU_FLAT : + case GLU_SMOOTH : + if (super.orientation == GLU_OUTSIDE) { + glNormal3f(0.0f, 0.0f, 1.0f); + } else { + glNormal3f(0.0f, 0.0f, -1.0f); + } + break; + default : + case GLU_NONE : + break; + } + + switch (super.drawStyle) { + case GLU_FILL : + if (innerRadius == .0f) { + finish = loops - 1; + /* Triangle strip for inner polygons */ + glBegin(GL_TRIANGLE_FAN); + if (super.textureFlag) { + glTexCoord2f(0.5f, 0.5f); + } + glVertex3f(0.0f, 0.0f, 0.0f); + radiusLow = outerRadius - deltaRadius * ((float) (loops - 1) / loops); + if (super.textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + if (super.orientation == GLU_OUTSIDE) { + for (i = slices; i >= 0; i--) { + if (super.textureFlag) { + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + } else { + for (i = 0; i <= slices; i++) { + if (super.textureFlag) { + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + } + glEnd(); + } else { + finish = loops; + } + for (j = 0; j < finish; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + radiusHigh = outerRadius - deltaRadius * ((float) (j + 1) / loops); + if (super.textureFlag) { + texLow = radiusLow / outerRadius / 2; + texHigh = radiusHigh / outerRadius / 2; + } + + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= slices; i++) { + if (super.orientation == GLU_OUTSIDE) { + if (super.textureFlag) { + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + + if (super.textureFlag) { + glTexCoord2f( + texHigh * sinCache[i] + 0.5f, + texHigh * cosCache[i] + 0.5f); + } + glVertex3f( + radiusHigh * sinCache[i], + radiusHigh * cosCache[i], + 0.0f); + } else { + if (super.textureFlag) { + glTexCoord2f( + texHigh * sinCache[i] + 0.5f, + texHigh * cosCache[i] + 0.5f); + } + glVertex3f( + radiusHigh * sinCache[i], + radiusHigh * cosCache[i], + 0.0f); + + if (super.textureFlag) { + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + } + glEnd(); + } + break; + case GLU_POINT : + glBegin(GL_POINTS); + for (i = 0; i < slices2; i++) { + sintemp = sinCache[i]; + costemp = cosCache[i]; + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + + if (super.textureFlag) { + texLow = radiusLow / outerRadius / 2; + + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f); + } + } + glEnd(); + break; + case GLU_LINE : + if (innerRadius == outerRadius) { + glBegin(GL_LINE_STRIP); + + for (i = 0; i <= slices; i++) { + if (super.textureFlag) { + glTexCoord2f(sinCache[i] / 2 + 0.5f, cosCache[i] / 2 + 0.5f); + } + glVertex3f(innerRadius * sinCache[i], innerRadius * cosCache[i], 0.0f); + } + glEnd(); + break; + } + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + if (super.textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + glBegin(GL_LINE_STRIP); + for (i = 0; i <= slices; i++) { + if (super.textureFlag) { + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + glEnd(); + } + for (i = 0; i < slices2; i++) { + sintemp = sinCache[i]; + costemp = cosCache[i]; + glBegin(GL_LINE_STRIP); + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + if (super.textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + if (super.textureFlag) { + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f); + } + glEnd(); + } + break; + case GLU_SILHOUETTE : + if (sweepAngle < 360.0f) { + for (i = 0; i <= slices; i += slices) { + sintemp = sinCache[i]; + costemp = cosCache[i]; + glBegin(GL_LINE_STRIP); + for (j = 0; j <= loops; j++) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + + if (super.textureFlag) { + texLow = radiusLow / outerRadius / 2; + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0f); + } + glEnd(); + } + } + for (j = 0; j <= loops; j += loops) { + radiusLow = outerRadius - deltaRadius * ((float) j / loops); + if (super.textureFlag) { + texLow = radiusLow / outerRadius / 2; + } + + glBegin(GL_LINE_STRIP); + for (i = 0; i <= slices; i++) { + if (super.textureFlag) { + glTexCoord2f( + texLow * sinCache[i] + 0.5f, + texLow * cosCache[i] + 0.5f); + } + glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i], 0.0f); + } + glEnd(); + if (innerRadius == outerRadius) + break; + } + break; + default : + break; + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PixelStoreState.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PixelStoreState.java new file mode 100644 index 000000000..2e75e363b --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/PixelStoreState.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.opengl.GL11.*; + +/** + * PixelStoreState.java + * + * + * Created 11-jan-2004 + * @author Erik Duijs + */ +class PixelStoreState extends Util { + + public int unpackRowLength; + public int unpackAlignment; + public int unpackSkipRows; + public int unpackSkipPixels; + public int packRowLength; + public int packAlignment; + public int packSkipRows; + public int packSkipPixels; + + /** + * Constructor for PixelStoreState. + */ + PixelStoreState() { + super(); + load(); + } + + public void load() { + unpackRowLength = glGetInteger(GL_UNPACK_ROW_LENGTH); + unpackAlignment = glGetInteger(GL_UNPACK_ALIGNMENT); + unpackSkipRows = glGetInteger(GL_UNPACK_SKIP_ROWS); + unpackSkipPixels = glGetInteger(GL_UNPACK_SKIP_PIXELS); + packRowLength = glGetInteger(GL_PACK_ROW_LENGTH); + packAlignment = glGetInteger(GL_PACK_ALIGNMENT); + packSkipRows = glGetInteger(GL_PACK_SKIP_ROWS); + packSkipPixels = glGetInteger(GL_PACK_SKIP_PIXELS); + } + + public void save() { + glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength); + glPixelStorei(GL_UNPACK_ALIGNMENT, unpackAlignment); + glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackSkipRows); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels); + glPixelStorei(GL_PACK_ROW_LENGTH, packRowLength); + glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); + glPixelStorei(GL_PACK_SKIP_ROWS, packSkipRows); + glPixelStorei(GL_PACK_SKIP_PIXELS, packSkipPixels); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Project.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Project.java new file mode 100644 index 000000000..a4a999e6d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Project.java @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import org.lwjgl.BufferUtils; + +import static org.lwjgl.opengl.GL11.*; + +/** + * Project.java + *

+ *

+ * Created 11-jan-2004 + * + * @author Erik Duijs + */ +public class Project extends Util { + + private static final float[] IDENTITY_MATRIX = + new float[] { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f }; + + private static final FloatBuffer matrix = BufferUtils.createFloatBuffer(16); + private static final FloatBuffer finalMatrix = BufferUtils.createFloatBuffer(16); + + private static final FloatBuffer tempMatrix = BufferUtils.createFloatBuffer(16); + private static final float[] in = new float[4]; + private static final float[] out = new float[4]; + + private static final float[] forward = new float[3]; + private static final float[] side = new float[3]; + private static final float[] up = new float[3]; + + /** + * Make matrix an identity matrix + */ + private static void __gluMakeIdentityf(FloatBuffer m) { + int oldPos = m.position(); + m.put(IDENTITY_MATRIX); + m.position(oldPos); + } + + /** + * Method __gluMultMatrixVecf + * + * @param finalMatrix + * @param in + * @param out + */ + private static void __gluMultMatrixVecf(FloatBuffer m, float[] in, float[] out) { + for (int i = 0; i < 4; i++) { + out[i] = + in[0] * m.get(m.position() + 0*4 + i) + + in[1] * m.get(m.position() + 1*4 + i) + + in[2] * m.get(m.position() + 2*4 + i) + + in[3] * m.get(m.position() + 3*4 + i); + + } + } + + /** + * @param src + * @param inverse + * + * @return + */ + private static boolean __gluInvertMatrixf(FloatBuffer src, FloatBuffer inverse) { + int i, j, k, swap; + float t; + FloatBuffer temp = Project.tempMatrix; + + + for (i = 0; i < 16; i++) { + temp.put(i, src.get(i + src.position())); + } + __gluMakeIdentityf(inverse); + + for (i = 0; i < 4; i++) { + /* + * * Look for largest element in column + */ + swap = i; + for (j = i + 1; j < 4; j++) { + /* + * if (fabs(temp[j][i]) > fabs(temp[i][i])) { swap = j; + */ + if (Math.abs(temp.get(j*4 + i)) > Math.abs(temp.get(i* 4 + i))) { + swap = j; + } + } + + if (swap != i) { + /* + * * Swap rows. + */ + for (k = 0; k < 4; k++) { + t = temp.get(i*4 + k); + temp.put(i*4 + k, temp.get(swap*4 + k)); + temp.put(swap*4 + k, t); + + t = inverse.get(i*4 + k); + inverse.put(i*4 + k, inverse.get(swap*4 + k)); + //inverse.put((i << 2) + k, inverse.get((swap << 2) + k)); + inverse.put(swap*4 + k, t); + //inverse.put((swap << 2) + k, t); + } + } + + if (temp.get(i*4 + i) == 0) { + /* + * * No non-zero pivot. The matrix is singular, which shouldn't * + * happen. This means the user gave us a bad matrix. + */ + return false; + } + + t = temp.get(i*4 + i); + for (k = 0; k < 4; k++) { + temp.put(i*4 + k, temp.get(i*4 + k)/t); + inverse.put(i*4 + k, inverse.get(i*4 + k)/t); + } + for (j = 0; j < 4; j++) { + if (j != i) { + t = temp.get(j*4 + i); + for (k = 0; k < 4; k++) { + temp.put(j*4 + k, temp.get(j*4 + k) - temp.get(i*4 + k) * t); + inverse.put(j*4 + k, inverse.get(j*4 + k) - inverse.get(i*4 + k) * t); + /*inverse.put( + (j << 2) + k, + inverse.get((j << 2) + k) - inverse.get((i << 2) + k) * t);*/ + } + } + } + } + return true; + } + + /** + * @param a + * @param b + * @param r + */ + private static void __gluMultMatricesf(FloatBuffer a, FloatBuffer b, FloatBuffer r) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + r.put(r.position() + i*4 + j, + a.get(a.position() + i*4 + 0) * b.get(b.position() + 0*4 + j) + a.get(a.position() + i*4 + 1) * b.get(b.position() + 1*4 + j) + a.get(a.position() + i*4 + 2) * b.get(b.position() + 2*4 + j) + a.get(a.position() + i*4 + 3) * b.get(b.position() + 3*4 + j)); + } + } + } + + /** + * Method gluPerspective. + * + * @param fovy + * @param aspect + * @param zNear + * @param zFar + */ + public static void gluPerspective(float fovy, float aspect, float zNear, float zFar) { + float sine, cotangent, deltaZ; + float radians = fovy / 2 * GLU.PI / 180; + + deltaZ = zFar - zNear; + sine = (float) Math.sin(radians); + + if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { + return; + } + + cotangent = (float) Math.cos(radians) / sine; + + __gluMakeIdentityf(matrix); + + matrix.put(0 * 4 + 0, cotangent / aspect); + matrix.put(1 * 4 + 1, cotangent); + matrix.put(2 * 4 + 2, - (zFar + zNear) / deltaZ); + matrix.put(2 * 4 + 3, -1); + matrix.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ); + matrix.put(3 * 4 + 3, 0); + + glMultMatrixf(matrix); + } + + /** + * Method gluLookAt + * + * @param eyex + * @param eyey + * @param eyez + * @param centerx + * @param centery + * @param centerz + * @param upx + * @param upy + * @param upz + */ + public static void gluLookAt( + float eyex, + float eyey, + float eyez, + float centerx, + float centery, + float centerz, + float upx, + float upy, + float upz) { + float[] forward = Project.forward; + float[] side = Project.side; + float[] up = Project.up; + + forward[0] = centerx - eyex; + forward[1] = centery - eyey; + forward[2] = centerz - eyez; + + up[0] = upx; + up[1] = upy; + up[2] = upz; + + normalize(forward); + + /* Side = forward x up */ + cross(forward, up, side); + normalize(side); + + /* Recompute up as: up = side x forward */ + cross(side, forward, up); + + __gluMakeIdentityf(matrix); + matrix.put(0 * 4 + 0, side[0]); + matrix.put(1 * 4 + 0, side[1]); + matrix.put(2 * 4 + 0, side[2]); + + matrix.put(0 * 4 + 1, up[0]); + matrix.put(1 * 4 + 1, up[1]); + matrix.put(2 * 4 + 1, up[2]); + + matrix.put(0 * 4 + 2, -forward[0]); + matrix.put(1 * 4 + 2, -forward[1]); + matrix.put(2 * 4 + 2, -forward[2]); + + glMultMatrixf(matrix); + glTranslatef(-eyex, -eyey, -eyez); + } + + /** + * Method gluProject + * + * @param objx + * @param objy + * @param objz + * @param modelMatrix + * @param projMatrix + * @param viewport + * @param win_pos + */ + public static boolean gluProject( + float objx, + float objy, + float objz, + FloatBuffer modelMatrix, + FloatBuffer projMatrix, + IntBuffer viewport, + FloatBuffer win_pos) { + + float[] in = Project.in; + float[] out = Project.out; + + in[0] = objx; + in[1] = objy; + in[2] = objz; + in[3] = 1.0f; + + __gluMultMatrixVecf(modelMatrix, in, out); + __gluMultMatrixVecf(projMatrix, out, in); + + if (in[3] == 0.0) + return false; + + in[3] = (1.0f / in[3]) * 0.5f; + + // Map x, y and z to range 0-1 + in[0] = in[0] * in[3] + 0.5f; + in[1] = in[1] * in[3] + 0.5f; + in[2] = in[2] * in[3] + 0.5f; + + // Map x,y to viewport + win_pos.put(0, in[0] * viewport.get(viewport.position() + 2) + viewport.get(viewport.position() + 0)); + win_pos.put(1, in[1] * viewport.get(viewport.position() + 3) + viewport.get(viewport.position() + 1)); + win_pos.put(2, in[2]); + + return true; + } + + /** + * Method gluUnproject + * + * @param winx + * @param winy + * @param winz + * @param modelMatrix + * @param projMatrix + * @param viewport + * @param obj_pos + */ + public static boolean gluUnProject( + float winx, + float winy, + float winz, + FloatBuffer modelMatrix, + FloatBuffer projMatrix, + IntBuffer viewport, + FloatBuffer obj_pos) { + float[] in = Project.in; + float[] out = Project.out; + + __gluMultMatricesf(modelMatrix, projMatrix, finalMatrix); + + if (!__gluInvertMatrixf(finalMatrix, finalMatrix)) + return false; + + in[0] = winx; + in[1] = winy; + in[2] = winz; + in[3] = 1.0f; + + // Map x and y from window coordinates + in[0] = (in[0] - viewport.get(viewport.position() + 0)) / viewport.get(viewport.position() + 2); + in[1] = (in[1] - viewport.get(viewport.position() + 1)) / viewport.get(viewport.position() + 3); + + // Map to range -1 to 1 + in[0] = in[0] * 2 - 1; + in[1] = in[1] * 2 - 1; + in[2] = in[2] * 2 - 1; + + __gluMultMatrixVecf(finalMatrix, in, out); + + if (out[3] == 0.0) + return false; + + out[3] = 1.0f / out[3]; + + obj_pos.put(obj_pos.position() + 0, out[0] * out[3]); + obj_pos.put(obj_pos.position() + 1, out[1] * out[3]); + obj_pos.put(obj_pos.position() + 2, out[2] * out[3]); + + return true; + } + + /** + * Method gluPickMatrix + * + * @param x + * @param y + * @param deltaX + * @param deltaY + * @param viewport + */ + public static void gluPickMatrix( + float x, + float y, + float deltaX, + float deltaY, + IntBuffer viewport) { + if (deltaX <= 0 || deltaY <= 0) { + return; + } + + /* Translate and scale the picked region to the entire window */ + glTranslatef( + (viewport.get(viewport.position() + 2) - 2 * (x - viewport.get(viewport.position() + 0))) / deltaX, + (viewport.get(viewport.position() + 3) - 2 * (y - viewport.get(viewport.position() + 1))) / deltaY, + 0); + glScalef(viewport.get(viewport.position() + 2) / deltaX, viewport.get(viewport.position() + 3) / deltaY, 1.0f); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Quadric.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Quadric.java new file mode 100644 index 000000000..3bbbf6e08 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Quadric.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.util.glu.GLU.*; + +/** + * Quadric.java + * + * + * Created 22-dec-2003 + * @author Erik Duijs + */ +public class Quadric { + + protected int drawStyle; + protected int orientation; + protected boolean textureFlag; + protected int normals; + + /** + * Constructor for Quadric. + */ + public Quadric() { + super(); + + drawStyle = GLU_FILL; + orientation = GLU_OUTSIDE; + textureFlag = false; + normals = GLU_SMOOTH; + } + + /** + * Call glNormal3f after scaling normal to unit length. + * + * @param x + * @param y + * @param z + */ + protected void normal3f(float x, float y, float z) { + float mag; + + mag = (float)Math.sqrt(x * x + y * y + z * z); + if (mag > 0.00001F) { + x /= mag; + y /= mag; + z /= mag; + } + glNormal3f(x, y, z); + } + + /** + * specifies the draw style for quadrics. + * + * The legal values are as follows: + * + * GLU.FILL: Quadrics are rendered with polygon primitives. The polygons + * are drawn in a counterclockwise fashion with respect to + * their normals (as defined with glu.quadricOrientation). + * + * GLU.LINE: Quadrics are rendered as a set of lines. + * + * GLU.SILHOUETTE: Quadrics are rendered as a set of lines, except that edges + * separating coplanar faces will not be drawn. + * + * GLU.POINT: Quadrics are rendered as a set of points. + * + * @param drawStyle The drawStyle to set + */ + public void setDrawStyle(int drawStyle) { + this.drawStyle = drawStyle; + } + + /** + * specifies what kind of normals are desired for quadrics. + * The legal values are as follows: + * + * GLU.NONE: No normals are generated. + * + * GLU.FLAT: One normal is generated for every facet of a quadric. + * + * GLU.SMOOTH: One normal is generated for every vertex of a quadric. This + * is the default. + * + * @param normals The normals to set + */ + public void setNormals(int normals) { + this.normals = normals; + } + + /** + * specifies what kind of orientation is desired for. + * The orientation values are as follows: + * + * GLU.OUTSIDE: Quadrics are drawn with normals pointing outward. + * + * GLU.INSIDE: Normals point inward. The default is GLU.OUTSIDE. + * + * Note that the interpretation of outward and inward depends on the quadric + * being drawn. + * + * @param orientation The orientation to set + */ + public void setOrientation(int orientation) { + this.orientation = orientation; + } + + /** + * specifies if texture coordinates should be generated for + * quadrics rendered with qobj. If the value of textureCoords is true, + * then texture coordinates are generated, and if textureCoords is false, + * they are not.. The default is false. + * + * The manner in which texture coordinates are generated depends upon the + * specific quadric rendered. + * + * @param textureFlag The textureFlag to set + */ + public void setTextureFlag(boolean textureFlag) { + this.textureFlag = textureFlag; + } + + + /** + * Returns the drawStyle. + * @return int + */ + public int getDrawStyle() { + return drawStyle; + } + + /** + * Returns the normals. + * @return int + */ + public int getNormals() { + return normals; + } + + /** + * Returns the orientation. + * @return int + */ + public int getOrientation() { + return orientation; + } + + /** + * Returns the textureFlag. + * @return boolean + */ + public boolean getTextureFlag() { + return textureFlag; + } + + protected void TXTR_COORD(float x, float y) { + if (textureFlag) glTexCoord2f(x,y); + } + + + protected float sin(float r) { + return (float)Math.sin(r); + } + + protected float cos(float r) { + return (float)Math.cos(r); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Registry.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Registry.java new file mode 100644 index 000000000..41505673d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Registry.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.util.glu.GLU.*; + +/** + * Registry.java + * + * + * Created 11-jan-2004 + * @author Erik Duijs + */ +public class Registry extends Util { + + private static final String versionString = "1.3"; + private static final String extensionString = + "GLU_EXT_nurbs_tessellator " + "GLU_EXT_object_space_tess "; + + /** + * Method gluGetString + * @param name + * @return String + */ + public static String gluGetString(int name) { + + if (name == GLU_VERSION) { + return versionString; + } else if (name == GLU_EXTENSIONS) { + return extensionString; + } + return null; + } + + /** + * Method gluCheckExtension + * + * @param extName is an extension name. + * @param extString is a string of extensions separated by blank(s). There may or + * may not be leading or trailing blank(s) in extString. + * This works in cases of extensions being prefixes of another like + * GL_EXT_texture and GL_EXT_texture3D. + * @return boolean true if extName is found otherwise it returns false. + */ + public static boolean gluCheckExtension(String extName, String extString) { + if (extString == null || extName == null) + return false; + + return extString.indexOf(extName) != -1; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Sphere.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Sphere.java new file mode 100644 index 000000000..4e3351679 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Sphere.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.util.glu.GLU.*; + +/** + * Sphere.java + * + * + * Created 23-dec-2003 + * @author Erik Duijs + */ +public class Sphere extends Quadric { + + /** + * Constructor + */ + public Sphere() { + super(); + } + + /** + * draws a sphere of the given radius centered around the origin. + * The sphere is subdivided around the z axis into slices and along the z axis + * into stacks (similar to lines of longitude and latitude). + * + * If the orientation is set to GLU.OUTSIDE (with glu.quadricOrientation), then + * any normals generated point away from the center of the sphere. Otherwise, + * they point toward the center of the sphere. + + * If texturing is turned on (with glu.quadricTexture), then texture + * coordinates are generated so that t ranges from 0.0 at z=-radius to 1.0 at + * z=radius (t increases linearly along longitudinal lines), and s ranges from + * 0.0 at the +y axis, to 0.25 at the +x axis, to 0.5 at the -y axis, to 0.75 + * at the -x axis, and back to 1.0 at the +y axis. + */ + public void draw(float radius, int slices, int stacks) { + // TODO + + float rho, drho, theta, dtheta; + float x, y, z; + float s, t, ds, dt; + int i, j, imin, imax; + boolean normals; + float nsign; + + normals = super.normals != GLU_NONE; + + if (super.orientation == GLU_INSIDE) { + nsign = -1.0f; + } else { + nsign = 1.0f; + } + + drho = PI / stacks; + dtheta = 2.0f * PI / slices; + + if (super.drawStyle == GLU_FILL) { + if (!super.textureFlag) { + // draw +Z end as a triangle fan + glBegin(GL_TRIANGLE_FAN); + glNormal3f(0.0f, 0.0f, 1.0f); + glVertex3f(0.0f, 0.0f, nsign * radius); + for (j = 0; j <= slices; j++) { + theta = (j == slices) ? 0.0f : j * dtheta; + x = -sin(theta) * sin(drho); + y = cos(theta) * sin(drho); + z = nsign * cos(drho); + if (normals) { + glNormal3f(x * nsign, y * nsign, z * nsign); + } + glVertex3f(x * radius, y * radius, z * radius); + } + glEnd(); + } + + ds = 1.0f / slices; + dt = 1.0f / stacks; + t = 1.0f; // because loop now runs from 0 + if (super.textureFlag) { + imin = 0; + imax = stacks; + } else { + imin = 1; + imax = stacks - 1; + } + + // draw intermediate stacks as quad strips + for (i = imin; i < imax; i++) { + rho = i * drho; + glBegin(GL_QUAD_STRIP); + s = 0.0f; + for (j = 0; j <= slices; j++) { + theta = (j == slices) ? 0.0f : j * dtheta; + x = -sin(theta) * sin(rho); + y = cos(theta) * sin(rho); + z = nsign * cos(rho); + if (normals) { + glNormal3f(x * nsign, y * nsign, z * nsign); + } + TXTR_COORD(s, t); + glVertex3f(x * radius, y * radius, z * radius); + x = -sin(theta) * sin(rho + drho); + y = cos(theta) * sin(rho + drho); + z = nsign * cos(rho + drho); + if (normals) { + glNormal3f(x * nsign, y * nsign, z * nsign); + } + TXTR_COORD(s, t - dt); + s += ds; + glVertex3f(x * radius, y * radius, z * radius); + } + glEnd(); + t -= dt; + } + + if (!super.textureFlag) { + // draw -Z end as a triangle fan + glBegin(GL_TRIANGLE_FAN); + glNormal3f(0.0f, 0.0f, -1.0f); + glVertex3f(0.0f, 0.0f, -radius * nsign); + rho = PI - drho; + s = 1.0f; + for (j = slices; j >= 0; j--) { + theta = (j == slices) ? 0.0f : j * dtheta; + x = -sin(theta) * sin(rho); + y = cos(theta) * sin(rho); + z = nsign * cos(rho); + if (normals) + glNormal3f(x * nsign, y * nsign, z * nsign); + s -= ds; + glVertex3f(x * radius, y * radius, z * radius); + } + glEnd(); + } + } else if ( + super.drawStyle == GLU_LINE + || super.drawStyle == GLU_SILHOUETTE) { + // draw stack lines + for (i = 1; + i < stacks; + i++) { // stack line at i==stacks-1 was missing here + rho = i * drho; + glBegin(GL_LINE_LOOP); + for (j = 0; j < slices; j++) { + theta = j * dtheta; + x = cos(theta) * sin(rho); + y = sin(theta) * sin(rho); + z = cos(rho); + if (normals) + glNormal3f(x * nsign, y * nsign, z * nsign); + glVertex3f(x * radius, y * radius, z * radius); + } + glEnd(); + } + // draw slice lines + for (j = 0; j < slices; j++) { + theta = j * dtheta; + glBegin(GL_LINE_STRIP); + for (i = 0; i <= stacks; i++) { + rho = i * drho; + x = cos(theta) * sin(rho); + y = sin(theta) * sin(rho); + z = cos(rho); + if (normals) + glNormal3f(x * nsign, y * nsign, z * nsign); + glVertex3f(x * radius, y * radius, z * radius); + } + glEnd(); + } + } else if (super.drawStyle == GLU_POINT) { + // top and bottom-most points + glBegin(GL_POINTS); + if (normals) + glNormal3f(0.0f, 0.0f, nsign); + glVertex3f(0.0f, 0.0f, radius); + if (normals) + glNormal3f(0.0f, 0.0f, -nsign); + glVertex3f(0.0f, 0.0f, -radius); + + // loop over stacks + for (i = 1; i < stacks - 1; i++) { + rho = i * drho; + for (j = 0; j < slices; j++) { + theta = j * dtheta; + x = cos(theta) * sin(rho); + y = sin(theta) * sin(rho); + z = cos(rho); + if (normals) + glNormal3f(x * nsign, y * nsign, z * nsign); + glVertex3f(x * radius, y * radius, z * radius); + } + } + glEnd(); + } + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Util.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Util.java new file mode 100644 index 000000000..41a066fcf --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/Util.java @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.glu; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL12.*; + +/** + * Util.java + *

+ *

+ * Created 7-jan-2004 + * + * @author Erik Duijs + */ +public class Util { + + /** + * Return ceiling of integer division + * + * @param a + * @param b + * + * @return int + */ + protected static int ceil(int a, int b) { + return (a % b == 0 ? a / b : a / b + 1); + } + + /** + * Normalize vector + * + * @param v + * + * @return float[] + */ + protected static float[] normalize(float[] v) { + float r; + + r = (float)Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + if ( r == 0.0 ) + return v; + + r = 1.0f / r; + + v[0] *= r; + v[1] *= r; + v[2] *= r; + + return v; + } + + /** + * Calculate cross-product + * + * @param v1 + * @param v2 + * @param result + */ + protected static void cross(float[] v1, float[] v2, float[] result) { + result[0] = v1[1] * v2[2] - v1[2] * v2[1]; + result[1] = v1[2] * v2[0] - v1[0] * v2[2]; + result[2] = v1[0] * v2[1] - v1[1] * v2[0]; + } + + /** + * Method compPerPix. + * + * @param format + * + * @return int + */ + protected static int compPerPix(int format) { + /* Determine number of components per pixel */ + switch ( format ) { + case GL_COLOR_INDEX: + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + return 1; + case GL_LUMINANCE_ALPHA: + return 2; + case GL_RGB: + case GL_BGR: + return 3; + case GL_RGBA: + case GL_BGRA: + return 4; + default : + return -1; + } + } + + /** + * Method nearestPower. + *

+ * Compute the nearest power of 2 number. This algorithm is a little strange, but it works quite well. + * + * @param value + * + * @return int + */ + protected static int nearestPower(int value) { + int i; + + i = 1; + + /* Error! */ + if ( value == 0 ) + return -1; + + for ( ; ; ) { + if ( value == 1 ) { + return i; + } else if ( value == 3 ) { + return i << 2; + } + value >>= 1; + i <<= 1; + } + } + + /** + * Method bytesPerPixel. + * + * @param format + * @param type + * + * @return int + */ + protected static int bytesPerPixel(int format, int type) { + int n, m; + + switch ( format ) { + case GL_COLOR_INDEX: + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + n = 1; + break; + case GL_LUMINANCE_ALPHA: + n = 2; + break; + case GL_RGB: + case GL_BGR: + n = 3; + break; + case GL_RGBA: + case GL_BGRA: + n = 4; + break; + default : + n = 0; + } + + switch ( type ) { + case GL_UNSIGNED_BYTE: + m = 1; + break; + case GL_BYTE: + m = 1; + break; + case GL_BITMAP: + m = 1; + break; + case GL_UNSIGNED_SHORT: + m = 2; + break; + case GL_SHORT: + m = 2; + break; + case GL_UNSIGNED_INT: + m = 4; + break; + case GL_INT: + m = 4; + break; + case GL_FLOAT: + m = 4; + break; + default : + m = 0; + } + + return n * m; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/ActiveRegion.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/ActiveRegion.java new file mode 100644 index 000000000..7b566ec0f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/ActiveRegion.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class ActiveRegion { + GLUhalfEdge eUp; /* upper edge, directed right to left */ + DictNode nodeUp; /* dictionary node corresponding to eUp */ + int windingNumber; /* used to determine which regions are + * inside the polygon */ + boolean inside; /* is this region inside the polygon? */ + boolean sentinel; /* marks fake edges at t = +/-infinity */ + boolean dirty; /* marks regions where the upper or lower + * edge has changed, but we haven't checked + * whether they intersect yet */ + boolean fixUpperEdge; /* marks temporary edges introduced when + * we process a "right vertex" (one without + * any edges leaving to the right) */ +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/CachedVertex.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/CachedVertex.java new file mode 100644 index 000000000..d69547609 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/CachedVertex.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class CachedVertex { + public double[] coords = new double[3]; + public Object data; +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Dict.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Dict.java new file mode 100644 index 000000000..55c332092 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Dict.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class Dict { + DictNode head; + Object frame; + DictLeq leq; + + private Dict() { + } + + static Dict dictNewDict(Object frame, DictLeq leq) { + Dict dict = new Dict(); + dict.head = new DictNode(); + + dict.head.key = null; + dict.head.next = dict.head; + dict.head.prev = dict.head; + + dict.frame = frame; + dict.leq = leq; + + return dict; + } + + static void dictDeleteDict(Dict dict) { + dict.head = null; + dict.frame = null; + dict.leq = null; + } + + static DictNode dictInsert(Dict dict, Object key) { + return dictInsertBefore(dict, dict.head, key); + } + + static DictNode dictInsertBefore(Dict dict, DictNode node, Object key) { + do { + node = node.prev; + } while (node.key != null && !dict.leq.leq(dict.frame, node.key, key)); + + DictNode newNode = new DictNode(); + newNode.key = key; + newNode.next = node.next; + node.next.prev = newNode; + newNode.prev = node; + node.next = newNode; + + return newNode; + } + + static Object dictKey(DictNode aNode) { + return aNode.key; + } + + static DictNode dictSucc(DictNode aNode) { + return aNode.next; + } + + static DictNode dictPred(DictNode aNode) { + return aNode.prev; + } + + static DictNode dictMin(Dict aDict) { + return aDict.head.next; + } + + static DictNode dictMax(Dict aDict) { + return aDict.head.prev; + } + + static void dictDelete(Dict dict, DictNode node) { + node.next.prev = node.prev; + node.prev.next = node.next; + } + + static DictNode dictSearch(Dict dict, Object key) { + DictNode node = dict.head; + + do { + node = node.next; + } while (node.key != null && !(dict.leq.leq(dict.frame, key, node.key))); + + return node; + } + + public interface DictLeq { + boolean leq(Object frame, Object key1, Object key2); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/DictNode.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/DictNode.java new file mode 100644 index 000000000..ec93eb5b1 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/DictNode.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class DictNode { + Object key; + DictNode next; + DictNode prev; +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUface.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUface.java new file mode 100644 index 000000000..40ba208ae --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUface.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class GLUface { + public GLUface next; /* next face (never NULL) */ + public GLUface prev; /* previous face (never NULL) */ + public GLUhalfEdge anEdge; /* a half edge with this left face */ + public Object data; /* room for client's data */ + + /* Internal data (keep hidden) */ + public GLUface trail; /* "stack" for conversion to strips */ + public boolean marked; /* flag for conversion to strips */ + public boolean inside; /* this face is in the polygon interior */ +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUhalfEdge.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUhalfEdge.java new file mode 100644 index 000000000..65824c633 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUhalfEdge.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + + + +class GLUhalfEdge { + public GLUhalfEdge next; /* doubly-linked list (prev==Sym->next) */ + public GLUhalfEdge Sym; /* same edge, opposite direction */ + public GLUhalfEdge Onext; /* next edge CCW around origin */ + public GLUhalfEdge Lnext; /* next edge CCW around left face */ + public GLUvertex Org; /* origin vertex (Overtex too long) */ + public GLUface Lface; /* left face */ + + /* Internal data (keep hidden) */ + public ActiveRegion activeRegion; /* a region with this upper edge (sweep.c) */ + public int winding; /* change in winding number when crossing */ + public boolean first; + + GLUhalfEdge(boolean first) { + this.first = first; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUmesh.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUmesh.java new file mode 100644 index 000000000..3aa41edbc --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUmesh.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + + + +class GLUmesh { + GLUvertex vHead = new GLUvertex(); /* dummy header for vertex list */ + GLUface fHead = new GLUface(); /* dummy header for face list */ + GLUhalfEdge eHead = new GLUhalfEdge(true); /* dummy header for edge list */ + GLUhalfEdge eHeadSym = new GLUhalfEdge(false); /* and its symmetric counterpart */ +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUtessellatorImpl.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUtessellatorImpl.java new file mode 100644 index 000000000..dbbad30ea --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUtessellatorImpl.java @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +import org.lwjgl.util.glu.GLUtessellator; +import org.lwjgl.util.glu.GLUtessellatorCallback; +import org.lwjgl.util.glu.GLUtessellatorCallbackAdapter; + +import static org.lwjgl.util.glu.GLU.*; + +public class GLUtessellatorImpl implements GLUtessellator { + public static final int TESS_MAX_CACHE = 100; + + private int state; /* what begin/end calls have we seen? */ + + private GLUhalfEdge lastEdge; /* lastEdge->Org is the most recent vertex */ + GLUmesh mesh; /* stores the input contours, and eventually + the tessellation itself */ + + /*** state needed for projecting onto the sweep plane ***/ + + double[] normal = new double[3]; /* user-specified normal (if provided) */ + double[] sUnit = new double[3]; /* unit vector in s-direction (debugging) */ + double[] tUnit = new double[3]; /* unit vector in t-direction (debugging) */ + + /*** state needed for the line sweep ***/ + + private double relTolerance; /* tolerance for merging features */ + int windingRule; /* rule for determining polygon interior */ + boolean fatalError; /* fatal error: needed combine callback */ + + Dict dict; /* edge dictionary for sweep line */ + PriorityQ pq; /* priority queue of vertex events */ + GLUvertex event; /* current sweep event being processed */ + + /*** state needed for rendering callbacks (see render.c) ***/ + + boolean flagBoundary; /* mark boundary edges (use EdgeFlag) */ + boolean boundaryOnly; /* Extract contours, not triangles */ + GLUface lonelyTriList; + /* list of triangles which could not be rendered as strips or fans */ + + + + /*** state needed to cache single-contour polygons for renderCache() */ + + private boolean flushCacheOnNextVertex; /* empty cache on next vertex() call */ + int cacheCount; /* number of cached vertices */ + CachedVertex[] cache = new CachedVertex[TESS_MAX_CACHE]; /* the vertex data */ + + /*** rendering callbacks that also pass polygon data ***/ + private Object polygonData; /* client data for current polygon */ + + private GLUtessellatorCallback callBegin; + private GLUtessellatorCallback callEdgeFlag; + private GLUtessellatorCallback callVertex; + private GLUtessellatorCallback callEnd; +// private GLUtessellatorCallback callMesh; + private GLUtessellatorCallback callError; + private GLUtessellatorCallback callCombine; + + private GLUtessellatorCallback callBeginData; + private GLUtessellatorCallback callEdgeFlagData; + private GLUtessellatorCallback callVertexData; + private GLUtessellatorCallback callEndData; +// private GLUtessellatorCallback callMeshData; + private GLUtessellatorCallback callErrorData; + private GLUtessellatorCallback callCombineData; + + private static final double GLU_TESS_DEFAULT_TOLERANCE = 0.0; +// private static final int GLU_TESS_MESH = 100112; /* void (*)(GLUmesh *mesh) */ + private static GLUtessellatorCallback NULL_CB = new GLUtessellatorCallbackAdapter(); + +// #define MAX_FAST_ALLOC (MAX(sizeof(EdgePair), \ +// MAX(sizeof(GLUvertex),sizeof(GLUface)))) + + public GLUtessellatorImpl() { + state = TessState.T_DORMANT; + + normal[0] = 0; + normal[1] = 0; + normal[2] = 0; + + relTolerance = GLU_TESS_DEFAULT_TOLERANCE; + windingRule = GLU_TESS_WINDING_ODD; + flagBoundary = false; + boundaryOnly = false; + + callBegin = NULL_CB; + callEdgeFlag = NULL_CB; + callVertex = NULL_CB; + callEnd = NULL_CB; + callError = NULL_CB; + callCombine = NULL_CB; +// callMesh = NULL_CB; + + callBeginData = NULL_CB; + callEdgeFlagData = NULL_CB; + callVertexData = NULL_CB; + callEndData = NULL_CB; + callErrorData = NULL_CB; + callCombineData = NULL_CB; + + polygonData = null; + + for (int i = 0; i < cache.length; i++) { + cache[i] = new CachedVertex(); + } + } + + public static GLUtessellator gluNewTess() + { + return new GLUtessellatorImpl(); + } + + + private void makeDormant() { + /* Return the tessellator to its original dormant state. */ + + if (mesh != null) { + Mesh.__gl_meshDeleteMesh(mesh); + } + state = TessState.T_DORMANT; + lastEdge = null; + mesh = null; + } + + private void requireState(int newState) { + if (state != newState) gotoState(newState); + } + + private void gotoState(int newState) { + while (state != newState) { + /* We change the current state one level at a time, to get to + * the desired state. + */ + if (state < newState) { + if (state == TessState.T_DORMANT) { + callErrorOrErrorData(GLU_TESS_MISSING_BEGIN_POLYGON); + gluTessBeginPolygon(null); + } else if (state == TessState.T_IN_POLYGON) { + callErrorOrErrorData(GLU_TESS_MISSING_BEGIN_CONTOUR); + gluTessBeginContour(); + } + } else { + if (state == TessState.T_IN_CONTOUR) { + callErrorOrErrorData(GLU_TESS_MISSING_END_CONTOUR); + gluTessEndContour(); + } else if (state == TessState.T_IN_POLYGON) { + callErrorOrErrorData(GLU_TESS_MISSING_END_POLYGON); + /* gluTessEndPolygon( tess ) is too much work! */ + makeDormant(); + } + } + } + } + + public void gluDeleteTess() { + requireState(TessState.T_DORMANT); + } + + public void gluTessProperty(int which, double value) { + switch (which) { + case GLU_TESS_TOLERANCE: + if (value < 0.0 || value > 1.0) break; + relTolerance = value; + return; + + case GLU_TESS_WINDING_RULE: + int windingRule = (int) value; + if (windingRule != value) break; /* not an integer */ + + switch (windingRule) { + case GLU_TESS_WINDING_ODD: + case GLU_TESS_WINDING_NONZERO: + case GLU_TESS_WINDING_POSITIVE: + case GLU_TESS_WINDING_NEGATIVE: + case GLU_TESS_WINDING_ABS_GEQ_TWO: + this.windingRule = windingRule; + return; + default: + break; + } + + case GLU_TESS_BOUNDARY_ONLY: + boundaryOnly = (value != 0); + return; + + default: + callErrorOrErrorData(GLU_INVALID_ENUM); + return; + } + callErrorOrErrorData(GLU_INVALID_VALUE); + } + +/* Returns tessellator property */ + public void gluGetTessProperty(int which, double[] value, int value_offset) { + switch (which) { + case GLU_TESS_TOLERANCE: +/* tolerance should be in range [0..1] */ + assert (0.0 <= relTolerance && relTolerance <= 1.0); + value[value_offset] = relTolerance; + break; + case GLU_TESS_WINDING_RULE: + assert (windingRule == GLU_TESS_WINDING_ODD || + windingRule == GLU_TESS_WINDING_NONZERO || + windingRule == GLU_TESS_WINDING_POSITIVE || + windingRule == GLU_TESS_WINDING_NEGATIVE || + windingRule == GLU_TESS_WINDING_ABS_GEQ_TWO); + value[value_offset] = windingRule; + break; + case GLU_TESS_BOUNDARY_ONLY: + assert (boundaryOnly == true || boundaryOnly == false); + value[value_offset] = boundaryOnly ? 1 : 0; + break; + default: + value[value_offset] = 0.0; + callErrorOrErrorData(GLU_INVALID_ENUM); + break; + } + } /* gluGetTessProperty() */ + + public void gluTessNormal(double x, double y, double z) { + normal[0] = x; + normal[1] = y; + normal[2] = z; + } + + public void gluTessCallback(int which, GLUtessellatorCallback aCallback) { + switch (which) { + case GLU_TESS_BEGIN: + callBegin = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_BEGIN_DATA: + callBeginData = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_EDGE_FLAG: + callEdgeFlag = aCallback == null ? NULL_CB : aCallback; +/* If the client wants boundary edges to be flagged, + * we render everything as separate triangles (no strips or fans). + */ + flagBoundary = aCallback != null; + return; + case GLU_TESS_EDGE_FLAG_DATA: + callEdgeFlagData = callBegin = aCallback == null ? NULL_CB : aCallback; +/* If the client wants boundary edges to be flagged, + * we render everything as separate triangles (no strips or fans). + */ + flagBoundary = (aCallback != null); + return; + case GLU_TESS_VERTEX: + callVertex = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_VERTEX_DATA: + callVertexData = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_END: + callEnd = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_END_DATA: + callEndData = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_ERROR: + callError = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_ERROR_DATA: + callErrorData = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_COMBINE: + callCombine = aCallback == null ? NULL_CB : aCallback; + return; + case GLU_TESS_COMBINE_DATA: + callCombineData = aCallback == null ? NULL_CB : aCallback; + return; +// case GLU_TESS_MESH: +// callMesh = aCallback == null ? NULL_CB : aCallback; +// return; + default: + callErrorOrErrorData(GLU_INVALID_ENUM); + return; + } + } + + private boolean addVertex(double[] coords, Object vertexData) { + GLUhalfEdge e; + + e = lastEdge; + if (e == null) { +/* Make a self-loop (one vertex, one edge). */ + + e = Mesh.__gl_meshMakeEdge(mesh); + if (e == null) return false; + if (!Mesh.__gl_meshSplice(e, e.Sym)) return false; + } else { +/* Create a new vertex and edge which immediately follow e + * in the ordering around the left face. + */ + if (Mesh.__gl_meshSplitEdge(e) == null) return false; + e = e.Lnext; + } + +/* The new vertex is now e.Org. */ + e.Org.data = vertexData; + e.Org.coords[0] = coords[0]; + e.Org.coords[1] = coords[1]; + e.Org.coords[2] = coords[2]; + +/* The winding of an edge says how the winding number changes as we + * cross from the edge''s right face to its left face. We add the + * vertices in such an order that a CCW contour will add +1 to + * the winding number of the region inside the contour. + */ + e.winding = 1; + e.Sym.winding = -1; + + lastEdge = e; + + return true; + } + + private void cacheVertex(double[] coords, Object vertexData) { + if (cache[cacheCount] == null) { + cache[cacheCount] = new CachedVertex(); + } + + CachedVertex v = cache[cacheCount]; + + v.data = vertexData; + v.coords[0] = coords[0]; + v.coords[1] = coords[1]; + v.coords[2] = coords[2]; + ++cacheCount; + } + + + private boolean flushCache() { + CachedVertex[] v = cache; + + mesh = Mesh.__gl_meshNewMesh(); + if (mesh == null) return false; + + for (int i = 0; i < cacheCount; i++) { + CachedVertex vertex = v[i]; + if (!addVertex(vertex.coords, vertex.data)) return false; + } + cacheCount = 0; + flushCacheOnNextVertex = false; + + return true; + } + + public void gluTessVertex(double[] coords, int coords_offset, Object vertexData) { + int i; + boolean tooLarge = false; + double x; + double[] clamped = new double[3]; + + requireState(TessState.T_IN_CONTOUR); + + if (flushCacheOnNextVertex) { + if (!flushCache()) { + callErrorOrErrorData(GLU_OUT_OF_MEMORY); + return; + } + lastEdge = null; + } + for (i = 0; i < 3; ++i) { + x = coords[i+coords_offset]; + if (x < -GLU_TESS_MAX_COORD) { + x = -GLU_TESS_MAX_COORD; + tooLarge = true; + } + if (x > GLU_TESS_MAX_COORD) { + x = GLU_TESS_MAX_COORD; + tooLarge = true; + } + clamped[i] = x; + } + if (tooLarge) { + callErrorOrErrorData(GLU_TESS_COORD_TOO_LARGE); + } + + if (mesh == null) { + if (cacheCount < TESS_MAX_CACHE) { + cacheVertex(clamped, vertexData); + return; + } + if (!flushCache()) { + callErrorOrErrorData(GLU_OUT_OF_MEMORY); + return; + } + } + + if (!addVertex(clamped, vertexData)) { + callErrorOrErrorData(GLU_OUT_OF_MEMORY); + } + } + + + public void gluTessBeginPolygon(Object data) { + requireState(TessState.T_DORMANT); + + state = TessState.T_IN_POLYGON; + cacheCount = 0; + flushCacheOnNextVertex = false; + mesh = null; + + polygonData = data; + } + + + public void gluTessBeginContour() { + requireState(TessState.T_IN_POLYGON); + + state = TessState.T_IN_CONTOUR; + lastEdge = null; + if (cacheCount > 0) { +/* Just set a flag so we don't get confused by empty contours + * -- these can be generated accidentally with the obsolete + * NextContour() interface. + */ + flushCacheOnNextVertex = true; + } + } + + + public void gluTessEndContour() { + requireState(TessState.T_IN_CONTOUR); + state = TessState.T_IN_POLYGON; + } + + public void gluTessEndPolygon() { + GLUmesh mesh; + + try { + requireState(TessState.T_IN_POLYGON); + state = TessState.T_DORMANT; + + if (this.mesh == null) { + if (!flagBoundary /*&& callMesh == NULL_CB*/) { + +/* Try some special code to make the easy cases go quickly + * (eg. convex polygons). This code does NOT handle multiple contours, + * intersections, edge flags, and of course it does not generate + * an explicit mesh either. + */ + if (Render.__gl_renderCache(this)) { + polygonData = null; + return; + } + } + if (!flushCache()) throw new RuntimeException(); /* could've used a label*/ + } + +/* Determine the polygon normal and project vertices onto the plane + * of the polygon. + */ + Normal.__gl_projectPolygon(this); + +/* __gl_computeInterior( tess ) computes the planar arrangement specified + * by the given contours, and further subdivides this arrangement + * into regions. Each region is marked "inside" if it belongs + * to the polygon, according to the rule given by windingRule. + * Each interior region is guaranteed be monotone. + */ + if (!Sweep.__gl_computeInterior(this)) { + throw new RuntimeException(); /* could've used a label */ + } + + mesh = this.mesh; + if (!fatalError) { + boolean rc = true; + +/* If the user wants only the boundary contours, we throw away all edges + * except those which separate the interior from the exterior. + * Otherwise we tessellate all the regions marked "inside". + */ + if (boundaryOnly) { + rc = TessMono.__gl_meshSetWindingNumber(mesh, 1, true); + } else { + rc = TessMono.__gl_meshTessellateInterior(mesh); + } + if (!rc) throw new RuntimeException(); /* could've used a label */ + + Mesh.__gl_meshCheckMesh(mesh); + + if (callBegin != NULL_CB || callEnd != NULL_CB + || callVertex != NULL_CB || callEdgeFlag != NULL_CB + || callBeginData != NULL_CB + || callEndData != NULL_CB + || callVertexData != NULL_CB + || callEdgeFlagData != NULL_CB) { + if (boundaryOnly) { + Render.__gl_renderBoundary(this, mesh); /* output boundary contours */ + } else { + Render.__gl_renderMesh(this, mesh); /* output strips and fans */ + } + } +// if (callMesh != NULL_CB) { +// +///* Throw away the exterior faces, so that all faces are interior. +// * This way the user doesn't have to check the "inside" flag, +// * and we don't need to even reveal its existence. It also leaves +// * the freedom for an implementation to not generate the exterior +// * faces in the first place. +// */ +// TessMono.__gl_meshDiscardExterior(mesh); +// callMesh.mesh(mesh); /* user wants the mesh itself */ +// mesh = null; +// polygonData = null; +// return; +// } + } + Mesh.__gl_meshDeleteMesh(mesh); + polygonData = null; + mesh = null; + } catch (Exception e) { + e.printStackTrace(); + callErrorOrErrorData(GLU_OUT_OF_MEMORY); + } + } + + /*******************************************************/ + +/* Obsolete calls -- for backward compatibility */ + + public void gluBeginPolygon() { + gluTessBeginPolygon(null); + gluTessBeginContour(); + } + + +/*ARGSUSED*/ + public void gluNextContour(int type) { + gluTessEndContour(); + gluTessBeginContour(); + } + + + public void gluEndPolygon() { + gluTessEndContour(); + gluTessEndPolygon(); + } + + void callBeginOrBeginData(int a) { + if (callBeginData != NULL_CB) + callBeginData.beginData(a, polygonData); + else + callBegin.begin(a); + } + + void callVertexOrVertexData(Object a) { + if (callVertexData != NULL_CB) + callVertexData.vertexData(a, polygonData); + else + callVertex.vertex(a); + } + + void callEdgeFlagOrEdgeFlagData(boolean a) { + if (callEdgeFlagData != NULL_CB) + callEdgeFlagData.edgeFlagData(a, polygonData); + else + callEdgeFlag.edgeFlag(a); + } + + void callEndOrEndData() { + if (callEndData != NULL_CB) + callEndData.endData(polygonData); + else + callEnd.end(); + } + + void callCombineOrCombineData(double[] coords, Object[] vertexData, float[] weights, Object[] outData) { + if (callCombineData != NULL_CB) + callCombineData.combineData(coords, vertexData, weights, outData, polygonData); + else + callCombine.combine(coords, vertexData, weights, outData); + } + + void callErrorOrErrorData(int a) { + if (callErrorData != NULL_CB) + callErrorData.errorData(a, polygonData); + else + callError.error(a); + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUvertex.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUvertex.java new file mode 100644 index 000000000..374c968c3 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/GLUvertex.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class GLUvertex { + public GLUvertex next; /* next vertex (never NULL) */ + public GLUvertex prev; /* previous vertex (never NULL) */ + public GLUhalfEdge anEdge; /* a half-edge with this origin */ + public Object data; /* client's data */ + + /* Internal data (keep hidden) */ + public double[] coords = new double[3]; /* vertex location in 3D */ + public double s, t; /* projection onto the sweep plane */ + public int pqHandle; /* to allow deletion from priority queue */ +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Geom.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Geom.java new file mode 100644 index 000000000..23fef1fc6 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Geom.java @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class Geom { + private Geom() { + } + + /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w), + * evaluates the t-coord of the edge uw at the s-coord of the vertex v. + * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v. + * If uw is vertical (and thus passes thru v), the result is zero. + * + * The calculation is extremely accurate and stable, even when v + * is very close to u or w. In particular if we set v->t = 0 and + * let r be the negated result (this evaluates (uw)(v->s)), then + * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t). + */ + static double EdgeEval(GLUvertex u, GLUvertex v, GLUvertex w) { + double gapL, gapR; + + assert (VertLeq(u, v) && VertLeq(v, w)); + + gapL = v.s - u.s; + gapR = w.s - v.s; + + if (gapL + gapR > 0) { + if (gapL < gapR) { + return (v.t - u.t) + (u.t - w.t) * (gapL / (gapL + gapR)); + } else { + return (v.t - w.t) + (w.t - u.t) * (gapR / (gapL + gapR)); + } + } + /* vertical line */ + return 0; + } + + static double EdgeSign(GLUvertex u, GLUvertex v, GLUvertex w) { + double gapL, gapR; + + assert (VertLeq(u, v) && VertLeq(v, w)); + + gapL = v.s - u.s; + gapR = w.s - v.s; + + if (gapL + gapR > 0) { + return (v.t - w.t) * gapL + (v.t - u.t) * gapR; + } + /* vertical line */ + return 0; + } + + + /*********************************************************************** + * Define versions of EdgeSign, EdgeEval with s and t transposed. + */ + + static double TransEval(GLUvertex u, GLUvertex v, GLUvertex w) { + /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w), + * evaluates the t-coord of the edge uw at the s-coord of the vertex v. + * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v. + * If uw is vertical (and thus passes thru v), the result is zero. + * + * The calculation is extremely accurate and stable, even when v + * is very close to u or w. In particular if we set v->s = 0 and + * let r be the negated result (this evaluates (uw)(v->t)), then + * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s). + */ + double gapL, gapR; + + assert (TransLeq(u, v) && TransLeq(v, w)); + + gapL = v.t - u.t; + gapR = w.t - v.t; + + if (gapL + gapR > 0) { + if (gapL < gapR) { + return (v.s - u.s) + (u.s - w.s) * (gapL / (gapL + gapR)); + } else { + return (v.s - w.s) + (w.s - u.s) * (gapR / (gapL + gapR)); + } + } + /* vertical line */ + return 0; + } + + static double TransSign(GLUvertex u, GLUvertex v, GLUvertex w) { + /* Returns a number whose sign matches TransEval(u,v,w) but which + * is cheaper to evaluate. Returns > 0, == 0 , or < 0 + * as v is above, on, or below the edge uw. + */ + double gapL, gapR; + + assert (TransLeq(u, v) && TransLeq(v, w)); + + gapL = v.t - u.t; + gapR = w.t - v.t; + + if (gapL + gapR > 0) { + return (v.s - w.s) * gapL + (v.s - u.s) * gapR; + } + /* vertical line */ + return 0; + } + + + static boolean VertCCW(GLUvertex u, GLUvertex v, GLUvertex w) { + /* For almost-degenerate situations, the results are not reliable. + * Unless the floating-point arithmetic can be performed without + * rounding errors, *any* implementation will give incorrect results + * on some degenerate inputs, so the client must have some way to + * handle this situation. + */ + return (u.s * (v.t - w.t) + v.s * (w.t - u.t) + w.s * (u.t - v.t)) >= 0; + } + +/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b), + * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces + * this in the rare case that one argument is slightly negative. + * The implementation is extremely stable numerically. + * In particular it guarantees that the result r satisfies + * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate + * even when a and b differ greatly in magnitude. + */ + static double Interpolate(double a, double x, double b, double y) { + a = (a < 0) ? 0 : a; + b = (b < 0) ? 0 : b; + if (a <= b) { + if (b == 0) { + return (x + y) / 2.0; + } else { + return (x + (y - x) * (a / (a + b))); + } + } else { + return (y + (x - y) * (b / (a + b))); + } + } + + static void EdgeIntersect(GLUvertex o1, GLUvertex d1, + GLUvertex o2, GLUvertex d2, + GLUvertex v) +/* Given edges (o1,d1) and (o2,d2), compute their point of intersection. + * The computed point is guaranteed to lie in the intersection of the + * bounding rectangles defined by each edge. + */ { + double z1, z2; + + /* This is certainly not the most efficient way to find the intersection + * of two line segments, but it is very numerically stable. + * + * Strategy: find the two middle vertices in the VertLeq ordering, + * and interpolate the intersection s-value from these. Then repeat + * using the TransLeq ordering to find the intersection t-value. + */ + + if (!VertLeq(o1, d1)) { + GLUvertex temp = o1; + o1 = d1; + d1 = temp; + } + if (!VertLeq(o2, d2)) { + GLUvertex temp = o2; + o2 = d2; + d2 = temp; + } + if (!VertLeq(o1, o2)) { + GLUvertex temp = o1; + o1 = o2; + o2 = temp; + temp = d1; + d1 = d2; + d2 = temp; + } + + if (!VertLeq(o2, d1)) { + /* Technically, no intersection -- do our best */ + v.s = (o2.s + d1.s) / 2.0; + } else if (VertLeq(d1, d2)) { + /* Interpolate between o2 and d1 */ + z1 = EdgeEval(o1, o2, d1); + z2 = EdgeEval(o2, d1, d2); + if (z1 + z2 < 0) { + z1 = -z1; + z2 = -z2; + } + v.s = Interpolate(z1, o2.s, z2, d1.s); + } else { + /* Interpolate between o2 and d2 */ + z1 = EdgeSign(o1, o2, d1); + z2 = -EdgeSign(o1, d2, d1); + if (z1 + z2 < 0) { + z1 = -z1; + z2 = -z2; + } + v.s = Interpolate(z1, o2.s, z2, d2.s); + } + + /* Now repeat the process for t */ + + if (!TransLeq(o1, d1)) { + GLUvertex temp = o1; + o1 = d1; + d1 = temp; + } + if (!TransLeq(o2, d2)) { + GLUvertex temp = o2; + o2 = d2; + d2 = temp; + } + if (!TransLeq(o1, o2)) { + GLUvertex temp = o2; + o2 = o1; + o1 = temp; + temp = d2; + d2 = d1; + d1 = temp; + } + + if (!TransLeq(o2, d1)) { + /* Technically, no intersection -- do our best */ + v.t = (o2.t + d1.t) / 2.0; + } else if (TransLeq(d1, d2)) { + /* Interpolate between o2 and d1 */ + z1 = TransEval(o1, o2, d1); + z2 = TransEval(o2, d1, d2); + if (z1 + z2 < 0) { + z1 = -z1; + z2 = -z2; + } + v.t = Interpolate(z1, o2.t, z2, d1.t); + } else { + /* Interpolate between o2 and d2 */ + z1 = TransSign(o1, o2, d1); + z2 = -TransSign(o1, d2, d1); + if (z1 + z2 < 0) { + z1 = -z1; + z2 = -z2; + } + v.t = Interpolate(z1, o2.t, z2, d2.t); + } + } + + static boolean VertEq(GLUvertex u, GLUvertex v) { + return u.s == v.s && u.t == v.t; + } + + static boolean VertLeq(GLUvertex u, GLUvertex v) { + return u.s < v.s || (u.s == v.s && u.t <= v.t); + } + +/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */ + + static boolean TransLeq(GLUvertex u, GLUvertex v) { + return u.t < v.t || (u.t == v.t && u.s <= v.s); + } + + static boolean EdgeGoesLeft(GLUhalfEdge e) { + return VertLeq(e.Sym.Org, e.Org); + } + + static boolean EdgeGoesRight(GLUhalfEdge e) { + return VertLeq(e.Org, e.Sym.Org); + } + + static double VertL1dist(GLUvertex u, GLUvertex v) { + return Math.abs(u.s - v.s) + Math.abs(u.t - v.t); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Mesh.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Mesh.java new file mode 100644 index 000000000..11d10f4d0 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Mesh.java @@ -0,0 +1,766 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class Mesh { + private Mesh() { + } + + /************************ Utility Routines ************************/ +/* MakeEdge creates a new pair of half-edges which form their own loop. + * No vertex or face structures are allocated, but these must be assigned + * before the current edge operation is completed. + */ + static GLUhalfEdge MakeEdge(GLUhalfEdge eNext) { + GLUhalfEdge e; + GLUhalfEdge eSym; + GLUhalfEdge ePrev; + +// EdgePair * pair = (EdgePair *) +// memAlloc(sizeof(EdgePair)); +// if (pair == NULL) return NULL; +// +// e = &pair - > e; + e = new GLUhalfEdge(true); +// eSym = &pair - > eSym; + eSym = new GLUhalfEdge(false); + + + /* Make sure eNext points to the first edge of the edge pair */ + if (!eNext.first) { + eNext = eNext.Sym; + } + + /* Insert in circular doubly-linked list before eNext. + * Note that the prev pointer is stored in Sym->next. + */ + ePrev = eNext.Sym.next; + eSym.next = ePrev; + ePrev.Sym.next = e; + e.next = eNext; + eNext.Sym.next = eSym; + + e.Sym = eSym; + e.Onext = e; + e.Lnext = eSym; + e.Org = null; + e.Lface = null; + e.winding = 0; + e.activeRegion = null; + + eSym.Sym = e; + eSym.Onext = eSym; + eSym.Lnext = e; + eSym.Org = null; + eSym.Lface = null; + eSym.winding = 0; + eSym.activeRegion = null; + + return e; + } + +/* Splice( a, b ) is best described by the Guibas/Stolfi paper or the + * CS348a notes (see mesh.h). Basically it modifies the mesh so that + * a->Onext and b->Onext are exchanged. This can have various effects + * depending on whether a and b belong to different face or vertex rings. + * For more explanation see __gl_meshSplice() below. + */ + static void Splice(GLUhalfEdge a, GLUhalfEdge b) { + GLUhalfEdge aOnext = a.Onext; + GLUhalfEdge bOnext = b.Onext; + + aOnext.Sym.Lnext = b; + bOnext.Sym.Lnext = a; + a.Onext = bOnext; + b.Onext = aOnext; + } + +/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the + * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives + * a place to insert the new vertex in the global vertex list. We insert + * the new vertex *before* vNext so that algorithms which walk the vertex + * list will not see the newly created vertices. + */ + static void MakeVertex(GLUvertex newVertex, + GLUhalfEdge eOrig, GLUvertex vNext) { + GLUhalfEdge e; + GLUvertex vPrev; + GLUvertex vNew = newVertex; + + assert (vNew != null); + + /* insert in circular doubly-linked list before vNext */ + vPrev = vNext.prev; + vNew.prev = vPrev; + vPrev.next = vNew; + vNew.next = vNext; + vNext.prev = vNew; + + vNew.anEdge = eOrig; + vNew.data = null; + /* leave coords, s, t undefined */ + + /* fix other edges on this vertex loop */ + e = eOrig; + do { + e.Org = vNew; + e = e.Onext; + } while (e != eOrig); + } + +/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left + * face of all edges in the face loop to which eOrig belongs. "fNext" gives + * a place to insert the new face in the global face list. We insert + * the new face *before* fNext so that algorithms which walk the face + * list will not see the newly created faces. + */ + static void MakeFace(GLUface newFace, GLUhalfEdge eOrig, GLUface fNext) { + GLUhalfEdge e; + GLUface fPrev; + GLUface fNew = newFace; + + assert (fNew != null); + + /* insert in circular doubly-linked list before fNext */ + fPrev = fNext.prev; + fNew.prev = fPrev; + fPrev.next = fNew; + fNew.next = fNext; + fNext.prev = fNew; + + fNew.anEdge = eOrig; + fNew.data = null; + fNew.trail = null; + fNew.marked = false; + + /* The new face is marked "inside" if the old one was. This is a + * convenience for the common case where a face has been split in two. + */ + fNew.inside = fNext.inside; + + /* fix other edges on this face loop */ + e = eOrig; + do { + e.Lface = fNew; + e = e.Lnext; + } while (e != eOrig); + } + +/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym), + * and removes from the global edge list. + */ + static void KillEdge(GLUhalfEdge eDel) { + GLUhalfEdge ePrev, eNext; + + /* Half-edges are allocated in pairs, see EdgePair above */ + if (!eDel.first) { + eDel = eDel.Sym; + } + + /* delete from circular doubly-linked list */ + eNext = eDel.next; + ePrev = eDel.Sym.next; + eNext.Sym.next = ePrev; + ePrev.Sym.next = eNext; + } + + +/* KillVertex( vDel ) destroys a vertex and removes it from the global + * vertex list. It updates the vertex loop to point to a given new vertex. + */ + static void KillVertex(GLUvertex vDel, GLUvertex newOrg) { + GLUhalfEdge e, eStart = vDel.anEdge; + GLUvertex vPrev, vNext; + + /* change the origin of all affected edges */ + e = eStart; + do { + e.Org = newOrg; + e = e.Onext; + } while (e != eStart); + + /* delete from circular doubly-linked list */ + vPrev = vDel.prev; + vNext = vDel.next; + vNext.prev = vPrev; + vPrev.next = vNext; + } + +/* KillFace( fDel ) destroys a face and removes it from the global face + * list. It updates the face loop to point to a given new face. + */ + static void KillFace(GLUface fDel, GLUface newLface) { + GLUhalfEdge e, eStart = fDel.anEdge; + GLUface fPrev, fNext; + + /* change the left face of all affected edges */ + e = eStart; + do { + e.Lface = newLface; + e = e.Lnext; + } while (e != eStart); + + /* delete from circular doubly-linked list */ + fPrev = fDel.prev; + fNext = fDel.next; + fNext.prev = fPrev; + fPrev.next = fNext; + } + + + /****************** Basic Edge Operations **********************/ + +/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face). + * The loop consists of the two new half-edges. + */ + public static GLUhalfEdge __gl_meshMakeEdge(GLUmesh mesh) { + GLUvertex newVertex1 = new GLUvertex(); + GLUvertex newVertex2 = new GLUvertex(); + GLUface newFace = new GLUface(); + GLUhalfEdge e; + + e = MakeEdge(mesh.eHead); + if (e == null) return null; + + MakeVertex(newVertex1, e, mesh.vHead); + MakeVertex(newVertex2, e.Sym, mesh.vHead); + MakeFace(newFace, e, mesh.fHead); + return e; + } + + +/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the + * mesh connectivity and topology. It changes the mesh so that + * eOrg->Onext <- OLD( eDst->Onext ) + * eDst->Onext <- OLD( eOrg->Onext ) + * where OLD(...) means the value before the meshSplice operation. + * + * This can have two effects on the vertex structure: + * - if eOrg->Org != eDst->Org, the two vertices are merged together + * - if eOrg->Org == eDst->Org, the origin is split into two vertices + * In both cases, eDst->Org is changed and eOrg->Org is untouched. + * + * Similarly (and independently) for the face structure, + * - if eOrg->Lface == eDst->Lface, one loop is split into two + * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one + * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected. + * + * Some special cases: + * If eDst == eOrg, the operation has no effect. + * If eDst == eOrg->Lnext, the new face will have a single edge. + * If eDst == eOrg->Lprev, the old face will have a single edge. + * If eDst == eOrg->Onext, the new vertex will have a single edge. + * If eDst == eOrg->Oprev, the old vertex will have a single edge. + */ + public static boolean __gl_meshSplice(GLUhalfEdge eOrg, GLUhalfEdge eDst) { + boolean joiningLoops = false; + boolean joiningVertices = false; + + if (eOrg == eDst) return true; + + if (eDst.Org != eOrg.Org) { + /* We are merging two disjoint vertices -- destroy eDst->Org */ + joiningVertices = true; + KillVertex(eDst.Org, eOrg.Org); + } + if (eDst.Lface != eOrg.Lface) { + /* We are connecting two disjoint loops -- destroy eDst.Lface */ + joiningLoops = true; + KillFace(eDst.Lface, eOrg.Lface); + } + + /* Change the edge structure */ + Splice(eDst, eOrg); + + if (!joiningVertices) { + GLUvertex newVertex = new GLUvertex(); + + /* We split one vertex into two -- the new vertex is eDst.Org. + * Make sure the old vertex points to a valid half-edge. + */ + MakeVertex(newVertex, eDst, eOrg.Org); + eOrg.Org.anEdge = eOrg; + } + if (!joiningLoops) { + GLUface newFace = new GLUface(); + + /* We split one loop into two -- the new loop is eDst.Lface. + * Make sure the old face points to a valid half-edge. + */ + MakeFace(newFace, eDst, eOrg.Lface); + eOrg.Lface.anEdge = eOrg; + } + + return true; + } + + +/* __gl_meshDelete( eDel ) removes the edge eDel. There are several cases: + * if (eDel.Lface != eDel.Rface), we join two loops into one; the loop + * eDel.Lface is deleted. Otherwise, we are splitting one loop into two; + * the newly created loop will contain eDel.Dst. If the deletion of eDel + * would create isolated vertices, those are deleted as well. + * + * This function could be implemented as two calls to __gl_meshSplice + * plus a few calls to memFree, but this would allocate and delete + * unnecessary vertices and faces. + */ + static boolean __gl_meshDelete(GLUhalfEdge eDel) { + GLUhalfEdge eDelSym = eDel.Sym; + boolean joiningLoops = false; + + /* First step: disconnect the origin vertex eDel.Org. We make all + * changes to get a consistent mesh in this "intermediate" state. + */ + if (eDel.Lface != eDel.Sym.Lface) { + /* We are joining two loops into one -- remove the left face */ + joiningLoops = true; + KillFace(eDel.Lface, eDel.Sym.Lface); + } + + if (eDel.Onext == eDel) { + KillVertex(eDel.Org, null); + } else { + /* Make sure that eDel.Org and eDel.Sym.Lface point to valid half-edges */ + eDel.Sym.Lface.anEdge = eDel.Sym.Lnext; + eDel.Org.anEdge = eDel.Onext; + + Splice(eDel, eDel.Sym.Lnext); + if (!joiningLoops) { + GLUface newFace = new GLUface(); + + /* We are splitting one loop into two -- create a new loop for eDel. */ + MakeFace(newFace, eDel, eDel.Lface); + } + } + + /* Claim: the mesh is now in a consistent state, except that eDel.Org + * may have been deleted. Now we disconnect eDel.Dst. + */ + if (eDelSym.Onext == eDelSym) { + KillVertex(eDelSym.Org, null); + KillFace(eDelSym.Lface, null); + } else { + /* Make sure that eDel.Dst and eDel.Lface point to valid half-edges */ + eDel.Lface.anEdge = eDelSym.Sym.Lnext; + eDelSym.Org.anEdge = eDelSym.Onext; + Splice(eDelSym, eDelSym.Sym.Lnext); + } + + /* Any isolated vertices or faces have already been freed. */ + KillEdge(eDel); + + return true; + } + + + /******************** Other Edge Operations **********************/ + +/* All these routines can be implemented with the basic edge + * operations above. They are provided for convenience and efficiency. + */ + + +/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that + * eNew == eOrg.Lnext, and eNew.Dst is a newly created vertex. + * eOrg and eNew will have the same left face. + */ + static GLUhalfEdge __gl_meshAddEdgeVertex(GLUhalfEdge eOrg) { + GLUhalfEdge eNewSym; + GLUhalfEdge eNew = MakeEdge(eOrg); + + eNewSym = eNew.Sym; + + /* Connect the new edge appropriately */ + Splice(eNew, eOrg.Lnext); + + /* Set the vertex and face information */ + eNew.Org = eOrg.Sym.Org; + { + GLUvertex newVertex = new GLUvertex(); + + MakeVertex(newVertex, eNewSym, eNew.Org); + } + eNew.Lface = eNewSym.Lface = eOrg.Lface; + + return eNew; + } + + +/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew, + * such that eNew == eOrg.Lnext. The new vertex is eOrg.Sym.Org == eNew.Org. + * eOrg and eNew will have the same left face. + */ + public static GLUhalfEdge __gl_meshSplitEdge(GLUhalfEdge eOrg) { + GLUhalfEdge eNew; + GLUhalfEdge tempHalfEdge = __gl_meshAddEdgeVertex(eOrg); + + eNew = tempHalfEdge.Sym; + + /* Disconnect eOrg from eOrg.Sym.Org and connect it to eNew.Org */ + Splice(eOrg.Sym, eOrg.Sym.Sym.Lnext); + Splice(eOrg.Sym, eNew); + + /* Set the vertex and face information */ + eOrg.Sym.Org = eNew.Org; + eNew.Sym.Org.anEdge = eNew.Sym; /* may have pointed to eOrg.Sym */ + eNew.Sym.Lface = eOrg.Sym.Lface; + eNew.winding = eOrg.winding; /* copy old winding information */ + eNew.Sym.winding = eOrg.Sym.winding; + + return eNew; + } + + +/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg.Sym.Org + * to eDst.Org, and returns the corresponding half-edge eNew. + * If eOrg.Lface == eDst.Lface, this splits one loop into two, + * and the newly created loop is eNew.Lface. Otherwise, two disjoint + * loops are merged into one, and the loop eDst.Lface is destroyed. + * + * If (eOrg == eDst), the new face will have only two edges. + * If (eOrg.Lnext == eDst), the old face is reduced to a single edge. + * If (eOrg.Lnext.Lnext == eDst), the old face is reduced to two edges. + */ + static GLUhalfEdge __gl_meshConnect(GLUhalfEdge eOrg, GLUhalfEdge eDst) { + GLUhalfEdge eNewSym; + boolean joiningLoops = false; + GLUhalfEdge eNew = MakeEdge(eOrg); + + eNewSym = eNew.Sym; + + if (eDst.Lface != eOrg.Lface) { + /* We are connecting two disjoint loops -- destroy eDst.Lface */ + joiningLoops = true; + KillFace(eDst.Lface, eOrg.Lface); + } + + /* Connect the new edge appropriately */ + Splice(eNew, eOrg.Lnext); + Splice(eNewSym, eDst); + + /* Set the vertex and face information */ + eNew.Org = eOrg.Sym.Org; + eNewSym.Org = eDst.Org; + eNew.Lface = eNewSym.Lface = eOrg.Lface; + + /* Make sure the old face points to a valid half-edge */ + eOrg.Lface.anEdge = eNewSym; + + if (!joiningLoops) { + GLUface newFace = new GLUface(); + + /* We split one loop into two -- the new loop is eNew.Lface */ + MakeFace(newFace, eNew, eOrg.Lface); + } + return eNew; + } + + + /******************** Other Operations **********************/ + +/* __gl_meshZapFace( fZap ) destroys a face and removes it from the + * global face list. All edges of fZap will have a null pointer as their + * left face. Any edges which also have a null pointer as their right face + * are deleted entirely (along with any isolated vertices this produces). + * An entire mesh can be deleted by zapping its faces, one at a time, + * in any order. Zapped faces cannot be used in further mesh operations! + */ + static void __gl_meshZapFace(GLUface fZap) { + GLUhalfEdge eStart = fZap.anEdge; + GLUhalfEdge e, eNext, eSym; + GLUface fPrev, fNext; + + /* walk around face, deleting edges whose right face is also null */ + eNext = eStart.Lnext; + do { + e = eNext; + eNext = e.Lnext; + + e.Lface = null; + if (e.Sym.Lface == null) { + /* delete the edge -- see __gl_MeshDelete above */ + + if (e.Onext == e) { + KillVertex(e.Org, null); + } else { + /* Make sure that e.Org points to a valid half-edge */ + e.Org.anEdge = e.Onext; + Splice(e, e.Sym.Lnext); + } + eSym = e.Sym; + if (eSym.Onext == eSym) { + KillVertex(eSym.Org, null); + } else { + /* Make sure that eSym.Org points to a valid half-edge */ + eSym.Org.anEdge = eSym.Onext; + Splice(eSym, eSym.Sym.Lnext); + } + KillEdge(e); + } + } while (e != eStart); + + /* delete from circular doubly-linked list */ + fPrev = fZap.prev; + fNext = fZap.next; + fNext.prev = fPrev; + fPrev.next = fNext; + } + + +/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices, + * and no loops (what we usually call a "face"). + */ + public static GLUmesh __gl_meshNewMesh() { + GLUvertex v; + GLUface f; + GLUhalfEdge e; + GLUhalfEdge eSym; + GLUmesh mesh = new GLUmesh(); + + v = mesh.vHead; + f = mesh.fHead; + e = mesh.eHead; + eSym = mesh.eHeadSym; + + v.next = v.prev = v; + v.anEdge = null; + v.data = null; + + f.next = f.prev = f; + f.anEdge = null; + f.data = null; + f.trail = null; + f.marked = false; + f.inside = false; + + e.next = e; + e.Sym = eSym; + e.Onext = null; + e.Lnext = null; + e.Org = null; + e.Lface = null; + e.winding = 0; + e.activeRegion = null; + + eSym.next = eSym; + eSym.Sym = e; + eSym.Onext = null; + eSym.Lnext = null; + eSym.Org = null; + eSym.Lface = null; + eSym.winding = 0; + eSym.activeRegion = null; + + return mesh; + } + + +/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in + * both meshes, and returns the new mesh (the old meshes are destroyed). + */ + static GLUmesh __gl_meshUnion(GLUmesh mesh1, GLUmesh mesh2) { + GLUface f1 = mesh1.fHead; + GLUvertex v1 = mesh1.vHead; + GLUhalfEdge e1 = mesh1.eHead; + GLUface f2 = mesh2.fHead; + GLUvertex v2 = mesh2.vHead; + GLUhalfEdge e2 = mesh2.eHead; + + /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */ + if (f2.next != f2) { + f1.prev.next = f2.next; + f2.next.prev = f1.prev; + f2.prev.next = f1; + f1.prev = f2.prev; + } + + if (v2.next != v2) { + v1.prev.next = v2.next; + v2.next.prev = v1.prev; + v2.prev.next = v1; + v1.prev = v2.prev; + } + + if (e2.next != e2) { + e1.Sym.next.Sym.next = e2.next; + e2.next.Sym.next = e1.Sym.next; + e2.Sym.next.Sym.next = e1; + e1.Sym.next = e2.Sym.next; + } + + return mesh1; + } + + +/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. + */ + static void __gl_meshDeleteMeshZap(GLUmesh mesh) { + GLUface fHead = mesh.fHead; + + while (fHead.next != fHead) { + __gl_meshZapFace(fHead.next); + } + assert (mesh.vHead.next == mesh.vHead); + } + +/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh. + */ + public static void __gl_meshDeleteMesh(GLUmesh mesh) { + GLUface f, fNext; + GLUvertex v, vNext; + GLUhalfEdge e, eNext; + + for (f = mesh.fHead.next; f != mesh.fHead; f = fNext) { + fNext = f.next; + } + + for (v = mesh.vHead.next; v != mesh.vHead; v = vNext) { + vNext = v.next; + } + + for (e = mesh.eHead.next; e != mesh.eHead; e = eNext) { + /* One call frees both e and e.Sym (see EdgePair above) */ + eNext = e.next; + } + } + +/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency. + */ + public static void __gl_meshCheckMesh(GLUmesh mesh) { + GLUface fHead = mesh.fHead; + GLUvertex vHead = mesh.vHead; + GLUhalfEdge eHead = mesh.eHead; + GLUface f, fPrev; + GLUvertex v, vPrev; + GLUhalfEdge e, ePrev; + + fPrev = fHead; + for (fPrev = fHead; (f = fPrev.next) != fHead; fPrev = f) { + assert (f.prev == fPrev); + e = f.anEdge; + do { + assert (e.Sym != e); + assert (e.Sym.Sym == e); + assert (e.Lnext.Onext.Sym == e); + assert (e.Onext.Sym.Lnext == e); + assert (e.Lface == f); + e = e.Lnext; + } while (e != f.anEdge); + } + assert (f.prev == fPrev && f.anEdge == null && f.data == null); + + vPrev = vHead; + for (vPrev = vHead; (v = vPrev.next) != vHead; vPrev = v) { + assert (v.prev == vPrev); + e = v.anEdge; + do { + assert (e.Sym != e); + assert (e.Sym.Sym == e); + assert (e.Lnext.Onext.Sym == e); + assert (e.Onext.Sym.Lnext == e); + assert (e.Org == v); + e = e.Onext; + } while (e != v.anEdge); + } + assert (v.prev == vPrev && v.anEdge == null && v.data == null); + + ePrev = eHead; + for (ePrev = eHead; (e = ePrev.next) != eHead; ePrev = e) { + assert (e.Sym.next == ePrev.Sym); + assert (e.Sym != e); + assert (e.Sym.Sym == e); + assert (e.Org != null); + assert (e.Sym.Org != null); + assert (e.Lnext.Onext.Sym == e); + assert (e.Onext.Sym.Lnext == e); + } + assert (e.Sym.next == ePrev.Sym + && e.Sym == mesh.eHeadSym + && e.Sym.Sym == e + && e.Org == null && e.Sym.Org == null + && e.Lface == null && e.Sym.Lface == null); + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Normal.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Normal.java new file mode 100644 index 000000000..334081a78 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Normal.java @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +import org.lwjgl.util.glu.GLU; + +class Normal { + private Normal() { + } + + static boolean SLANTED_SWEEP; + static double S_UNIT_X; /* Pre-normalized */ + static double S_UNIT_Y; + private static final boolean TRUE_PROJECT = false; + + static { + if (SLANTED_SWEEP) { +/* The "feature merging" is not intended to be complete. There are + * special cases where edges are nearly parallel to the sweep line + * which are not implemented. The algorithm should still behave + * robustly (ie. produce a reasonable tesselation) in the presence + * of such edges, however it may miss features which could have been + * merged. We could minimize this effect by choosing the sweep line + * direction to be something unusual (ie. not parallel to one of the + * coordinate axes). + */ + S_UNIT_X = 0.50941539564955385; /* Pre-normalized */ + S_UNIT_Y = 0.86052074622010633; + } else { + S_UNIT_X = 1.0; + S_UNIT_Y = 0.0; + } + } + + private static double Dot(double[] u, double[] v) { + return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]); + } + + static void Normalize(double[] v) { + double len = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + + assert (len > 0); + len = Math.sqrt(len); + v[0] /= len; + v[1] /= len; + v[2] /= len; + } + + static int LongAxis(double[] v) { + int i = 0; + + if (Math.abs(v[1]) > Math.abs(v[0])) { + i = 1; + } + if (Math.abs(v[2]) > Math.abs(v[i])) { + i = 2; + } + return i; + } + + static void ComputeNormal(GLUtessellatorImpl tess, double[] norm) { + GLUvertex v, v1, v2; + double c, tLen2, maxLen2; + double[] maxVal, minVal, d1, d2, tNorm; + GLUvertex[] maxVert, minVert; + GLUvertex vHead = tess.mesh.vHead; + int i; + + maxVal = new double[3]; + minVal = new double[3]; + minVert = new GLUvertex[3]; + maxVert = new GLUvertex[3]; + d1 = new double[3]; + d2 = new double[3]; + tNorm = new double[3]; + + maxVal[0] = maxVal[1] = maxVal[2] = -2 * GLU.TESS_MAX_COORD; + minVal[0] = minVal[1] = minVal[2] = 2 * GLU.TESS_MAX_COORD; + + for (v = vHead.next; v != vHead; v = v.next) { + for (i = 0; i < 3; ++i) { + c = v.coords[i]; + if (c < minVal[i]) { + minVal[i] = c; + minVert[i] = v; + } + if (c > maxVal[i]) { + maxVal[i] = c; + maxVert[i] = v; + } + } + } + +/* Find two vertices separated by at least 1/sqrt(3) of the maximum + * distance between any two vertices + */ + i = 0; + if (maxVal[1] - minVal[1] > maxVal[0] - minVal[0]) { + i = 1; + } + if (maxVal[2] - minVal[2] > maxVal[i] - minVal[i]) { + i = 2; + } + if (minVal[i] >= maxVal[i]) { +/* All vertices are the same -- normal doesn't matter */ + norm[0] = 0; + norm[1] = 0; + norm[2] = 1; + return; + } + +/* Look for a third vertex which forms the triangle with maximum area + * (Length of normal == twice the triangle area) + */ + maxLen2 = 0; + v1 = minVert[i]; + v2 = maxVert[i]; + d1[0] = v1.coords[0] - v2.coords[0]; + d1[1] = v1.coords[1] - v2.coords[1]; + d1[2] = v1.coords[2] - v2.coords[2]; + for (v = vHead.next; v != vHead; v = v.next) { + d2[0] = v.coords[0] - v2.coords[0]; + d2[1] = v.coords[1] - v2.coords[1]; + d2[2] = v.coords[2] - v2.coords[2]; + tNorm[0] = d1[1] * d2[2] - d1[2] * d2[1]; + tNorm[1] = d1[2] * d2[0] - d1[0] * d2[2]; + tNorm[2] = d1[0] * d2[1] - d1[1] * d2[0]; + tLen2 = tNorm[0] * tNorm[0] + tNorm[1] * tNorm[1] + tNorm[2] * tNorm[2]; + if (tLen2 > maxLen2) { + maxLen2 = tLen2; + norm[0] = tNorm[0]; + norm[1] = tNorm[1]; + norm[2] = tNorm[2]; + } + } + + if (maxLen2 <= 0) { +/* All points lie on a single line -- any decent normal will do */ + norm[0] = norm[1] = norm[2] = 0; + norm[LongAxis(d1)] = 1; + } + } + + static void CheckOrientation(GLUtessellatorImpl tess) { + double area; + GLUface f, fHead = tess.mesh.fHead; + GLUvertex v, vHead = tess.mesh.vHead; + GLUhalfEdge e; + +/* When we compute the normal automatically, we choose the orientation + * so that the the sum of the signed areas of all contours is non-negative. + */ + area = 0; + for (f = fHead.next; f != fHead; f = f.next) { + e = f.anEdge; + if (e.winding <= 0) continue; + do { + area += (e.Org.s - e.Sym.Org.s) * (e.Org.t + e.Sym.Org.t); + e = e.Lnext; + } while (e != f.anEdge); + } + if (area < 0) { +/* Reverse the orientation by flipping all the t-coordinates */ + for (v = vHead.next; v != vHead; v = v.next) { + v.t = -v.t; + } + tess.tUnit[0] = -tess.tUnit[0]; + tess.tUnit[1] = -tess.tUnit[1]; + tess.tUnit[2] = -tess.tUnit[2]; + } + } + +/* Determine the polygon normal and project vertices onto the plane + * of the polygon. + */ + public static void __gl_projectPolygon(GLUtessellatorImpl tess) { + GLUvertex v, vHead = tess.mesh.vHead; + double w; + double[] norm = new double[3]; + double[] sUnit, tUnit; + int i; + boolean computedNormal = false; + + norm[0] = tess.normal[0]; + norm[1] = tess.normal[1]; + norm[2] = tess.normal[2]; + if (norm[0] == 0 && norm[1] == 0 && norm[2] == 0) { + ComputeNormal(tess, norm); + computedNormal = true; + } + sUnit = tess.sUnit; + tUnit = tess.tUnit; + i = LongAxis(norm); + + if (TRUE_PROJECT) { +/* Choose the initial sUnit vector to be approximately perpendicular + * to the normal. + */ + Normalize(norm); + + sUnit[i] = 0; + sUnit[(i + 1) % 3] = S_UNIT_X; + sUnit[(i + 2) % 3] = S_UNIT_Y; + +/* Now make it exactly perpendicular */ + w = Dot(sUnit, norm); + sUnit[0] -= w * norm[0]; + sUnit[1] -= w * norm[1]; + sUnit[2] -= w * norm[2]; + Normalize(sUnit); + +/* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */ + tUnit[0] = norm[1] * sUnit[2] - norm[2] * sUnit[1]; + tUnit[1] = norm[2] * sUnit[0] - norm[0] * sUnit[2]; + tUnit[2] = norm[0] * sUnit[1] - norm[1] * sUnit[0]; + Normalize(tUnit); + } else { +/* Project perpendicular to a coordinate axis -- better numerically */ + sUnit[i] = 0; + sUnit[(i + 1) % 3] = S_UNIT_X; + sUnit[(i + 2) % 3] = S_UNIT_Y; + + tUnit[i] = 0; + tUnit[(i + 1) % 3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y; + tUnit[(i + 2) % 3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X; + } + +/* Project the vertices onto the sweep plane */ + for (v = vHead.next; v != vHead; v = v.next) { + v.s = Dot(v.coords, sUnit); + v.t = Dot(v.coords, tUnit); + } + if (computedNormal) { + CheckOrientation(tess); + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQ.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQ.java new file mode 100644 index 000000000..92bee8233 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQ.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +abstract class PriorityQ { + public static final int INIT_SIZE = 32; + + public static class PQnode { + int handle; + } + + public static class PQhandleElem { + Object key; + int node; + } + + public interface Leq { + boolean leq(Object key1, Object key2); + } + + // #ifdef FOR_TRITE_TEST_PROGRAM +// private static boolean LEQ(PriorityQCommon.Leq leq, Object x,Object y) { +// return pq.leq.leq(x,y); +// } +// #else +/* Violates modularity, but a little faster */ +// #include "geom.h" + public static boolean LEQ(Leq leq, Object x, Object y) { + return Geom.VertLeq((GLUvertex) x, (GLUvertex) y); + } + + static PriorityQ pqNewPriorityQ(Leq leq) { + return new PriorityQSort(leq); + } + + abstract void pqDeletePriorityQ(); + + abstract boolean pqInit(); + + abstract int pqInsert(Object keyNew); + + abstract Object pqExtractMin(); + + abstract void pqDelete(int hCurr); + + abstract Object pqMinimum(); + + abstract boolean pqIsEmpty(); +// #endif +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQHeap.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQHeap.java new file mode 100644 index 000000000..2a177cb80 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQHeap.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + + + +class PriorityQHeap extends PriorityQ { + PriorityQ.PQnode[] nodes; + PriorityQ.PQhandleElem[] handles; + int size, max; + int freeList; + boolean initialized; + PriorityQ.Leq leq; + +/* really __gl_pqHeapNewPriorityQ */ +PriorityQHeap(PriorityQ.Leq leq) { + size = 0; + max = PriorityQ.INIT_SIZE; + nodes = new PriorityQ.PQnode[PriorityQ.INIT_SIZE + 1]; + for (int i = 0; i < nodes.length; i++) { + nodes[i] = new PQnode(); + } + handles = new PriorityQ.PQhandleElem[PriorityQ.INIT_SIZE + 1]; + for (int i = 0; i < handles.length; i++) { + handles[i] = new PQhandleElem(); + } + initialized = false; + freeList = 0; + this.leq = leq; + + nodes[1].handle = 1; /* so that Minimum() returns NULL */ + handles[1].key = null; + } + +/* really __gl_pqHeapDeletePriorityQ */ + void pqDeletePriorityQ() { + handles = null; + nodes = null; + } + + void FloatDown(int curr) { + PriorityQ.PQnode[] n = nodes; + PriorityQ.PQhandleElem[] h = handles; + int hCurr, hChild; + int child; + + hCurr = n[curr].handle; + for (; ;) { + child = curr << 1; + if (child < size && LEQ(leq, h[n[child + 1].handle].key, + h[n[child].handle].key)) { + ++child; + } + + assert (child <= max); + + hChild = n[child].handle; + if (child > size || LEQ(leq, h[hCurr].key, h[hChild].key)) { + n[curr].handle = hCurr; + h[hCurr].node = curr; + break; + } + n[curr].handle = hChild; + h[hChild].node = curr; + curr = child; + } + } + + + void FloatUp(int curr) { + PriorityQ.PQnode[] n = nodes; + PriorityQ.PQhandleElem[] h = handles; + int hCurr, hParent; + int parent; + + hCurr = n[curr].handle; + for (; ;) { + parent = curr >> 1; + hParent = n[parent].handle; + if (parent == 0 || LEQ(leq, h[hParent].key, h[hCurr].key)) { + n[curr].handle = hCurr; + h[hCurr].node = curr; + break; + } + n[curr].handle = hParent; + h[hParent].node = curr; + curr = parent; + } + } + +/* really __gl_pqHeapInit */ + boolean pqInit() { + int i; + + /* This method of building a heap is O(n), rather than O(n lg n). */ + + for (i = size; i >= 1; --i) { + FloatDown(i); + } + initialized = true; + + return true; + } + +/* really __gl_pqHeapInsert */ +/* returns LONG_MAX iff out of memory */ + int pqInsert(Object keyNew) { + int curr; + int free; + + curr = ++size; + if ((curr * 2) > max) { + PriorityQ.PQnode[] saveNodes = nodes; + PriorityQ.PQhandleElem[] saveHandles = handles; + + /* If the heap overflows, double its size. */ + max <<= 1; +// pq->nodes = (PQnode *)memRealloc( pq->nodes, (size_t) ((pq->max + 1) * sizeof( pq->nodes[0] ))); + PriorityQ.PQnode[] pqNodes = new PriorityQ.PQnode[max + 1]; + System.arraycopy( nodes, 0, pqNodes, 0, nodes.length ); + for (int i = nodes.length; i < pqNodes.length; i++) { + pqNodes[i] = new PQnode(); + } + nodes = pqNodes; + if (nodes == null) { + nodes = saveNodes; /* restore ptr to free upon return */ + return Integer.MAX_VALUE; + } + +// pq->handles = (PQhandleElem *)memRealloc( pq->handles,(size_t)((pq->max + 1) * sizeof( pq->handles[0] ))); + PriorityQ.PQhandleElem[] pqHandles = new PriorityQ.PQhandleElem[max + 1]; + System.arraycopy( handles, 0, pqHandles, 0, handles.length ); + for (int i = handles.length; i < pqHandles.length; i++) { + pqHandles[i] = new PQhandleElem(); + } + handles = pqHandles; + if (handles == null) { + handles = saveHandles; /* restore ptr to free upon return */ + return Integer.MAX_VALUE; + } + } + + if (freeList == 0) { + free = curr; + } else { + free = freeList; + freeList = handles[free].node; + } + + nodes[curr].handle = free; + handles[free].node = curr; + handles[free].key = keyNew; + + if (initialized) { + FloatUp(curr); + } + assert (free != Integer.MAX_VALUE); + return free; + } + +/* really __gl_pqHeapExtractMin */ + Object pqExtractMin() { + PriorityQ.PQnode[] n = nodes; + PriorityQ.PQhandleElem[] h = handles; + int hMin = n[1].handle; + Object min = h[hMin].key; + + if (size > 0) { + n[1].handle = n[size].handle; + h[n[1].handle].node = 1; + + h[hMin].key = null; + h[hMin].node = freeList; + freeList = hMin; + + if (--size > 0) { + FloatDown(1); + } + } + return min; + } + +/* really __gl_pqHeapDelete */ + void pqDelete(int hCurr) { + PriorityQ.PQnode[] n = nodes; + PriorityQ.PQhandleElem[] h = handles; + int curr; + + assert (hCurr >= 1 && hCurr <= max && h[hCurr].key != null); + + curr = h[hCurr].node; + n[curr].handle = n[size].handle; + h[n[curr].handle].node = curr; + + if (curr <= --size) { + if (curr <= 1 || LEQ(leq, h[n[curr >> 1].handle].key, h[n[curr].handle].key)) { + FloatDown(curr); + } else { + FloatUp(curr); + } + } + h[hCurr].key = null; + h[hCurr].node = freeList; + freeList = hCurr; + } + + Object pqMinimum() { + return handles[nodes[1].handle].key; + } + + boolean pqIsEmpty() { + return size == 0; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQSort.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQSort.java new file mode 100644 index 000000000..21dff93b5 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/PriorityQSort.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + + + +class PriorityQSort extends PriorityQ { + PriorityQHeap heap; + Object[] keys; + + // JAVA: 'order' contains indices into the keys array. + // This simulates the indirect pointers used in the original C code + // (from Frank Suykens, Luciad.com). + int[] order; + int size, max; + boolean initialized; + PriorityQ.Leq leq; + + PriorityQSort(PriorityQ.Leq leq) { + heap = new PriorityQHeap(leq); + + keys = new Object[PriorityQ.INIT_SIZE]; + + size = 0; + max = PriorityQ.INIT_SIZE; + initialized = false; + this.leq = leq; + } + +/* really __gl_pqSortDeletePriorityQ */ + void pqDeletePriorityQ() { + if (heap != null) heap.pqDeletePriorityQ(); + order = null; + keys = null; + } + + private static boolean LT(PriorityQ.Leq leq, Object x, Object y) { + return (!PriorityQHeap.LEQ(leq, y, x)); + } + + private static boolean GT(PriorityQ.Leq leq, Object x, Object y) { + return (!PriorityQHeap.LEQ(leq, x, y)); + } + + private static void Swap(int[] array, int a, int b) { + if (true) { + int tmp = array[a]; + array[a] = array[b]; + array[b] = tmp; + } + } + + private static class Stack { + int p, r; + } + +/* really __gl_pqSortInit */ + boolean pqInit() { + int p, r, i, j; + int piv; + Stack[] stack = new Stack[50]; + for (int k = 0; k < stack.length; k++) { + stack[k] = new Stack(); + } + int top = 0; + + int seed = 2016473283; + + /* Create an array of indirect pointers to the keys, so that we + * the handles we have returned are still valid. + */ + order = new int[size + 1]; +/* the previous line is a patch to compensate for the fact that IBM */ +/* machines return a null on a malloc of zero bytes (unlike SGI), */ +/* so we have to put in this defense to guard against a memory */ +/* fault four lines down. from fossum@austin.ibm.com. */ + p = 0; + r = size - 1; + for (piv = 0, i = p; i <= r; ++piv, ++i) { + // indirect pointers: keep an index into the keys array, not a direct pointer to its contents + order[i] = piv; + } + + /* Sort the indirect pointers in descending order, + * using randomized Quicksort + */ + stack[top].p = p; + stack[top].r = r; + ++top; + while (--top >= 0) { + p = stack[top].p; + r = stack[top].r; + while (r > p + 10) { + seed = Math.abs( seed * 1539415821 + 1 ); + i = p + seed % (r - p + 1); + piv = order[i]; + order[i] = order[p]; + order[p] = piv; + i = p - 1; + j = r + 1; + do { + do { + ++i; + } while (GT(leq, keys[order[i]], keys[piv])); + do { + --j; + } while (LT(leq, keys[order[j]], keys[piv])); + Swap(order, i, j); + } while (i < j); + Swap(order, i, j); /* Undo last swap */ + if (i - p < r - j) { + stack[top].p = j + 1; + stack[top].r = r; + ++top; + r = i - 1; + } else { + stack[top].p = p; + stack[top].r = i - 1; + ++top; + p = j + 1; + } + } + /* Insertion sort small lists */ + for (i = p + 1; i <= r; ++i) { + piv = order[i]; + for (j = i; j > p && LT(leq, keys[order[j - 1]], keys[piv]); --j) { + order[j] = order[j - 1]; + } + order[j] = piv; + } + } + max = size; + initialized = true; + heap.pqInit(); /* always succeeds */ + +/* #ifndef NDEBUG + p = order; + r = p + size - 1; + for (i = p; i < r; ++i) { + Assertion.doAssert(LEQ( * * (i + 1), **i )); + } + #endif*/ + + return true; + } + +/* really __gl_pqSortInsert */ +/* returns LONG_MAX iff out of memory */ + int pqInsert(Object keyNew) { + int curr; + + if (initialized) { + return heap.pqInsert(keyNew); + } + curr = size; + if (++size >= max) { + Object[] saveKey = keys; + + /* If the heap overflows, double its size. */ + max <<= 1; +// pq->keys = (PQHeapKey *)memRealloc( pq->keys,(size_t)(pq->max * sizeof( pq->keys[0] ))); + Object[] pqKeys = new Object[max]; + System.arraycopy( keys, 0, pqKeys, 0, keys.length ); + keys = pqKeys; + if (keys == null) { + keys = saveKey; /* restore ptr to free upon return */ + return Integer.MAX_VALUE; + } + } + assert curr != Integer.MAX_VALUE; + keys[curr] = keyNew; + + /* Negative handles index the sorted array. */ + return -(curr + 1); + } + +/* really __gl_pqSortExtractMin */ + Object pqExtractMin() { + Object sortMin, heapMin; + + if (size == 0) { + return heap.pqExtractMin(); + } + sortMin = keys[order[size - 1]]; + if (!heap.pqIsEmpty()) { + heapMin = heap.pqMinimum(); + if (LEQ(leq, heapMin, sortMin)) { + return heap.pqExtractMin(); + } + } + do { + --size; + } while (size > 0 && keys[order[size - 1]] == null); + return sortMin; + } + +/* really __gl_pqSortMinimum */ + Object pqMinimum() { + Object sortMin, heapMin; + + if (size == 0) { + return heap.pqMinimum(); + } + sortMin = keys[order[size - 1]]; + if (!heap.pqIsEmpty()) { + heapMin = heap.pqMinimum(); + if (PriorityQHeap.LEQ(leq, heapMin, sortMin)) { + return heapMin; + } + } + return sortMin; + } + +/* really __gl_pqSortIsEmpty */ + boolean pqIsEmpty() { + return (size == 0) && heap.pqIsEmpty(); + } + +/* really __gl_pqSortDelete */ + void pqDelete(int curr) { + if (curr >= 0) { + heap.pqDelete(curr); + return; + } + curr = -(curr + 1); + assert curr < max && keys[curr] != null; + + keys[curr] = null; + while (size > 0 && keys[order[size - 1]] == null) { + --size; + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Render.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Render.java new file mode 100644 index 000000000..13ef9f400 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Render.java @@ -0,0 +1,589 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.util.glu.GLU.*; + +class Render { + private static final boolean USE_OPTIMIZED_CODE_PATH = false; + + private Render() { + } + + private static final RenderFan renderFan = new RenderFan(); + private static final RenderStrip renderStrip = new RenderStrip(); + private static final RenderTriangle renderTriangle = new RenderTriangle(); + +/* This structure remembers the information we need about a primitive + * to be able to render it later, once we have determined which + * primitive is able to use the most triangles. + */ + private static class FaceCount { + private FaceCount() { + } + + private FaceCount(long size, GLUhalfEdge eStart, renderCallBack render) { + this.size = size; + this.eStart = eStart; + this.render = render; + } + + long size; /* number of triangles used */ + GLUhalfEdge eStart; /* edge where this primitive starts */ + renderCallBack render; + }; + + private interface renderCallBack { + void render(GLUtessellatorImpl tess, GLUhalfEdge e, long size); + } + + /************************ Strips and Fans decomposition ******************/ + +/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle + * fans, strips, and separate triangles. A substantial effort is made + * to use as few rendering primitives as possible (ie. to make the fans + * and strips as large as possible). + * + * The rendering output is provided as callbacks (see the api). + */ + public static void __gl_renderMesh(GLUtessellatorImpl tess, GLUmesh mesh) { + GLUface f; + + /* Make a list of separate triangles so we can render them all at once */ + tess.lonelyTriList = null; + + for (f = mesh.fHead.next; f != mesh.fHead; f = f.next) { + f.marked = false; + } + for (f = mesh.fHead.next; f != mesh.fHead; f = f.next) { + + /* We examine all faces in an arbitrary order. Whenever we find + * an unprocessed face F, we output a group of faces including F + * whose size is maximum. + */ + if (f.inside && !f.marked) { + RenderMaximumFaceGroup(tess, f); + assert (f.marked); + } + } + if (tess.lonelyTriList != null) { + RenderLonelyTriangles(tess, tess.lonelyTriList); + tess.lonelyTriList = null; + } + } + + + static void RenderMaximumFaceGroup(GLUtessellatorImpl tess, GLUface fOrig) { + /* We want to find the largest triangle fan or strip of unmarked faces + * which includes the given face fOrig. There are 3 possible fans + * passing through fOrig (one centered at each vertex), and 3 possible + * strips (one for each CCW permutation of the vertices). Our strategy + * is to try all of these, and take the primitive which uses the most + * triangles (a greedy approach). + */ + GLUhalfEdge e = fOrig.anEdge; + FaceCount max = new FaceCount(); + FaceCount newFace; + + max.size = 1; + max.eStart = e; + max.render = renderTriangle; + + if (!tess.flagBoundary) { + newFace = MaximumFan(e); + if (newFace.size > max.size) { + max = newFace; + } + newFace = MaximumFan(e.Lnext); + if (newFace.size > max.size) { + max = newFace; + } + newFace = MaximumFan(e.Onext.Sym); + if (newFace.size > max.size) { + max = newFace; + } + + newFace = MaximumStrip(e); + if (newFace.size > max.size) { + max = newFace; + } + newFace = MaximumStrip(e.Lnext); + if (newFace.size > max.size) { + max = newFace; + } + newFace = MaximumStrip(e.Onext.Sym); + if (newFace.size > max.size) { + max = newFace; + } + } + max.render.render(tess, max.eStart, max.size); + } + + +/* Macros which keep track of faces we have marked temporarily, and allow + * us to backtrack when necessary. With triangle fans, this is not + * really necessary, since the only awkward case is a loop of triangles + * around a single origin vertex. However with strips the situation is + * more complicated, and we need a general tracking method like the + * one here. + */ + private static boolean Marked(GLUface f) { + return !f.inside || f.marked; + } + + private static GLUface AddToTrail(GLUface f, GLUface t) { + f.trail = t; + f.marked = true; + return f; + } + + private static void FreeTrail(GLUface t) { + if (true) { + while (t != null) { + t.marked = false; + t = t.trail; + } + } + + /* else absorb trailing semicolon */ + } + + static FaceCount MaximumFan(GLUhalfEdge eOrig) { + /* eOrig.Lface is the face we want to render. We want to find the size + * of a maximal fan around eOrig.Org. To do this we just walk around + * the origin vertex as far as possible in both directions. + */ + FaceCount newFace = new FaceCount(0, null, renderFan); + GLUface trail = null; + GLUhalfEdge e; + + for (e = eOrig; !Marked(e.Lface); e = e.Onext) { + trail = AddToTrail(e.Lface, trail); + ++newFace.size; + } + for (e = eOrig; !Marked(e.Sym.Lface); e = e.Sym.Lnext) { + trail = AddToTrail(e.Sym.Lface, trail); + ++newFace.size; + } + newFace.eStart = e; + /*LINTED*/ + FreeTrail(trail); + return newFace; + } + + + private static boolean IsEven(long n) { + return (n & 0x1L) == 0; + } + + static FaceCount MaximumStrip(GLUhalfEdge eOrig) { + /* Here we are looking for a maximal strip that contains the vertices + * eOrig.Org, eOrig.Dst, eOrig.Lnext.Dst (in that order or the + * reverse, such that all triangles are oriented CCW). + * + * Again we walk forward and backward as far as possible. However for + * strips there is a twist: to get CCW orientations, there must be + * an *even* number of triangles in the strip on one side of eOrig. + * We walk the strip starting on a side with an even number of triangles; + * if both side have an odd number, we are forced to shorten one side. + */ + FaceCount newFace = new FaceCount(0, null, renderStrip); + long headSize = 0, tailSize = 0; + GLUface trail = null; + GLUhalfEdge e, eTail, eHead; + + for (e = eOrig; !Marked(e.Lface); ++tailSize, e = e.Onext) { + trail = AddToTrail(e.Lface, trail); + ++tailSize; + e = e.Lnext.Sym; + if (Marked(e.Lface)) break; + trail = AddToTrail(e.Lface, trail); + } + eTail = e; + + for (e = eOrig; !Marked(e.Sym.Lface); ++headSize, e = e.Sym.Onext.Sym) { + trail = AddToTrail(e.Sym.Lface, trail); + ++headSize; + e = e.Sym.Lnext; + if (Marked(e.Sym.Lface)) break; + trail = AddToTrail(e.Sym.Lface, trail); + } + eHead = e; + + newFace.size = tailSize + headSize; + if (IsEven(tailSize)) { + newFace.eStart = eTail.Sym; + } else if (IsEven(headSize)) { + newFace.eStart = eHead; + } else { + /* Both sides have odd length, we must shorten one of them. In fact, + * we must start from eHead to guarantee inclusion of eOrig.Lface. + */ + --newFace.size; + newFace.eStart = eHead.Onext; + } + /*LINTED*/ + FreeTrail(trail); + return newFace; + } + + private static class RenderTriangle implements renderCallBack { + public void render(GLUtessellatorImpl tess, GLUhalfEdge e, long size) { + /* Just add the triangle to a triangle list, so we can render all + * the separate triangles at once. + */ + assert (size == 1); + tess.lonelyTriList = AddToTrail(e.Lface, tess.lonelyTriList); + } + } + + + static void RenderLonelyTriangles(GLUtessellatorImpl tess, GLUface f) { + /* Now we render all the separate triangles which could not be + * grouped into a triangle fan or strip. + */ + GLUhalfEdge e; + int newState; + int edgeState = -1; /* force edge state output for first vertex */ + + tess.callBeginOrBeginData(GL_TRIANGLES); + + for (; f != null; f = f.trail) { + /* Loop once for each edge (there will always be 3 edges) */ + + e = f.anEdge; + do { + if (tess.flagBoundary) { + /* Set the "edge state" to true just before we output the + * first vertex of each edge on the polygon boundary. + */ + newState = (!e.Sym.Lface.inside) ? 1 : 0; + if (edgeState != newState) { + edgeState = newState; + tess.callEdgeFlagOrEdgeFlagData( edgeState != 0); + } + } + tess.callVertexOrVertexData( e.Org.data); + + e = e.Lnext; + } while (e != f.anEdge); + } + tess.callEndOrEndData(); + } + + private static class RenderFan implements renderCallBack { + public void render(GLUtessellatorImpl tess, GLUhalfEdge e, long size) { + /* Render as many CCW triangles as possible in a fan starting from + * edge "e". The fan *should* contain exactly "size" triangles + * (otherwise we've goofed up somewhere). + */ + tess.callBeginOrBeginData(GL_TRIANGLE_FAN); + tess.callVertexOrVertexData( e.Org.data); + tess.callVertexOrVertexData( e.Sym.Org.data); + + while (!Marked(e.Lface)) { + e.Lface.marked = true; + --size; + e = e.Onext; + tess.callVertexOrVertexData( e.Sym.Org.data); + } + + assert (size == 0); + tess.callEndOrEndData(); + } + } + + private static class RenderStrip implements renderCallBack { + public void render(GLUtessellatorImpl tess, GLUhalfEdge e, long size) { + /* Render as many CCW triangles as possible in a strip starting from + * edge "e". The strip *should* contain exactly "size" triangles + * (otherwise we've goofed up somewhere). + */ + tess.callBeginOrBeginData(GL_TRIANGLE_STRIP); + tess.callVertexOrVertexData( e.Org.data); + tess.callVertexOrVertexData( e.Sym.Org.data); + + while (!Marked(e.Lface)) { + e.Lface.marked = true; + --size; + e = e.Lnext.Sym; + tess.callVertexOrVertexData( e.Org.data); + if (Marked(e.Lface)) break; + + e.Lface.marked = true; + --size; + e = e.Onext; + tess.callVertexOrVertexData( e.Sym.Org.data); + } + + assert (size == 0); + tess.callEndOrEndData(); + } + } + + /************************ Boundary contour decomposition ******************/ + +/* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one + * contour for each face marked "inside". The rendering output is + * provided as callbacks (see the api). + */ + public static void __gl_renderBoundary(GLUtessellatorImpl tess, GLUmesh mesh) { + GLUface f; + GLUhalfEdge e; + + for (f = mesh.fHead.next; f != mesh.fHead; f = f.next) { + if (f.inside) { + tess.callBeginOrBeginData(GL_LINE_LOOP); + e = f.anEdge; + do { + tess.callVertexOrVertexData( e.Org.data); + e = e.Lnext; + } while (e != f.anEdge); + tess.callEndOrEndData(); + } + } + } + + + /************************ Quick-and-dirty decomposition ******************/ + + private static final int SIGN_INCONSISTENT = 2; + + static int ComputeNormal(GLUtessellatorImpl tess, double[] norm, boolean check) +/* + * If check==false, we compute the polygon normal and place it in norm[]. + * If check==true, we check that each triangle in the fan from v0 has a + * consistent orientation with respect to norm[]. If triangles are + * consistently oriented CCW, return 1; if CW, return -1; if all triangles + * are degenerate return 0; otherwise (no consistent orientation) return + * SIGN_INCONSISTENT. + */ { + CachedVertex[] v = tess.cache; +// CachedVertex vn = v0 + tess.cacheCount; + int vn = tess.cacheCount; +// CachedVertex vc; + int vc; + double dot, xc, yc, zc, xp, yp, zp; + double[] n = new double[3]; + int sign = 0; + + /* Find the polygon normal. It is important to get a reasonable + * normal even when the polygon is self-intersecting (eg. a bowtie). + * Otherwise, the computed normal could be very tiny, but perpendicular + * to the true plane of the polygon due to numerical noise. Then all + * the triangles would appear to be degenerate and we would incorrectly + * decompose the polygon as a fan (or simply not render it at all). + * + * We use a sum-of-triangles normal algorithm rather than the more + * efficient sum-of-trapezoids method (used in CheckOrientation() + * in normal.c). This lets us explicitly reverse the signed area + * of some triangles to get a reasonable normal in the self-intersecting + * case. + */ + if (!check) { + norm[0] = norm[1] = norm[2] = 0.0; + } + + vc = 1; + xc = v[vc].coords[0] - v[0].coords[0]; + yc = v[vc].coords[1] - v[0].coords[1]; + zc = v[vc].coords[2] - v[0].coords[2]; + while (++vc < vn) { + xp = xc; + yp = yc; + zp = zc; + xc = v[vc].coords[0] - v[0].coords[0]; + yc = v[vc].coords[1] - v[0].coords[1]; + zc = v[vc].coords[2] - v[0].coords[2]; + + /* Compute (vp - v0) cross (vc - v0) */ + n[0] = yp * zc - zp * yc; + n[1] = zp * xc - xp * zc; + n[2] = xp * yc - yp * xc; + + dot = n[0] * norm[0] + n[1] * norm[1] + n[2] * norm[2]; + if (!check) { + /* Reverse the contribution of back-facing triangles to get + * a reasonable normal for self-intersecting polygons (see above) + */ + if (dot >= 0) { + norm[0] += n[0]; + norm[1] += n[1]; + norm[2] += n[2]; + } else { + norm[0] -= n[0]; + norm[1] -= n[1]; + norm[2] -= n[2]; + } + } else if (dot != 0) { + /* Check the new orientation for consistency with previous triangles */ + if (dot > 0) { + if (sign < 0) return SIGN_INCONSISTENT; + sign = 1; + } else { + if (sign > 0) return SIGN_INCONSISTENT; + sign = -1; + } + } + } + return sign; + } + +/* __gl_renderCache( tess ) takes a single contour and tries to render it + * as a triangle fan. This handles convex polygons, as well as some + * non-convex polygons if we get lucky. + * + * Returns true if the polygon was successfully rendered. The rendering + * output is provided as callbacks (see the api). + */ + public static boolean __gl_renderCache(GLUtessellatorImpl tess) { + CachedVertex[] v = tess.cache; +// CachedVertex vn = v0 + tess.cacheCount; + int vn = tess.cacheCount; +// CachedVertex vc; + int vc; + double[] norm = new double[3]; + int sign; + + if (tess.cacheCount < 3) { + /* Degenerate contour -- no output */ + return true; + } + + norm[0] = tess.normal[0]; + norm[1] = tess.normal[1]; + norm[2] = tess.normal[2]; + if (norm[0] == 0 && norm[1] == 0 && norm[2] == 0) { + ComputeNormal( tess, norm, false); + } + + sign = ComputeNormal( tess, norm, true); + if (sign == SIGN_INCONSISTENT) { + /* Fan triangles did not have a consistent orientation */ + return false; + } + if (sign == 0) { + /* All triangles were degenerate */ + return true; + } + + if ( !USE_OPTIMIZED_CODE_PATH ) { + return false; + } else { + /* Make sure we do the right thing for each winding rule */ + switch (tess.windingRule) { + case GLU_TESS_WINDING_ODD: + case GLU_TESS_WINDING_NONZERO: + break; + case GLU_TESS_WINDING_POSITIVE: + if (sign < 0) return true; + break; + case GLU_TESS_WINDING_NEGATIVE: + if (sign > 0) return true; + break; + case GLU_TESS_WINDING_ABS_GEQ_TWO: + return true; + } + + tess.callBeginOrBeginData( tess.boundaryOnly ? GL_LINE_LOOP + : (tess.cacheCount > 3) ? GL_TRIANGLE_FAN + : GL_TRIANGLES); + + tess.callVertexOrVertexData( v[0].data); + if (sign > 0) { + for (vc = 1; vc < vn; ++vc) { + tess.callVertexOrVertexData( v[vc].data); + } + } else { + for (vc = vn - 1; vc > 0; --vc) { + tess.callVertexOrVertexData( v[vc].data); + } + } + tess.callEndOrEndData(); + return true; + } + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Sweep.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Sweep.java new file mode 100644 index 000000000..e8cc98c15 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/Sweep.java @@ -0,0 +1,1384 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +import static org.lwjgl.util.glu.GLU.*; + +class Sweep { + private Sweep() { + } + +// #ifdef FOR_TRITE_TEST_PROGRAM +// extern void DebugEvent( GLUtessellator *tess ); +// #else + private static void DebugEvent(GLUtessellatorImpl tess) { + + } +// #endif + +/* + * Invariants for the Edge Dictionary. + * - each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2) + * at any valid location of the sweep event + * - if EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2 + * share a common endpoint + * - for each e, e.Dst has been processed, but not e.Org + * - each edge e satisfies VertLeq(e.Dst,event) && VertLeq(event,e.Org) + * where "event" is the current sweep line event. + * - no edge e has zero length + * + * Invariants for the Mesh (the processed portion). + * - the portion of the mesh left of the sweep line is a planar graph, + * ie. there is *some* way to embed it in the plane + * - no processed edge has zero length + * - no two processed vertices have identical coordinates + * - each "inside" region is monotone, ie. can be broken into two chains + * of monotonically increasing vertices according to VertLeq(v1,v2) + * - a non-invariant: these chains may intersect (very slightly) + * + * Invariants for the Sweep. + * - if none of the edges incident to the event vertex have an activeRegion + * (ie. none of these edges are in the edge dictionary), then the vertex + * has only right-going edges. + * - if an edge is marked "fixUpperEdge" (it is a temporary edge introduced + * by ConnectRightVertex), then it is the only right-going edge from + * its associated vertex. (This says that these edges exist only + * when it is necessary.) + */ + +/* When we merge two edges into one, we need to compute the combined + * winding of the new edge. + */ + private static void AddWinding(GLUhalfEdge eDst, GLUhalfEdge eSrc) { + eDst.winding += eSrc.winding; + eDst.Sym.winding += eSrc.Sym.winding; + } + + + private static ActiveRegion RegionBelow(ActiveRegion r) { + return ((ActiveRegion) Dict.dictKey(Dict.dictPred(r.nodeUp))); + } + + private static ActiveRegion RegionAbove(ActiveRegion r) { + return ((ActiveRegion) Dict.dictKey(Dict.dictSucc(r.nodeUp))); + } + + static boolean EdgeLeq(GLUtessellatorImpl tess, ActiveRegion reg1, ActiveRegion reg2) +/* + * Both edges must be directed from right to left (this is the canonical + * direction for the upper edge of each region). + * + * The strategy is to evaluate a "t" value for each edge at the + * current sweep line position, given by tess.event. The calculations + * are designed to be very stable, but of course they are not perfect. + * + * Special case: if both edge destinations are at the sweep event, + * we sort the edges by slope (they would otherwise compare equally). + */ { + GLUvertex event = tess.event; + GLUhalfEdge e1, e2; + double t1, t2; + + e1 = reg1.eUp; + e2 = reg2.eUp; + + if (e1.Sym.Org == event) { + if (e2.Sym.Org == event) { + /* Two edges right of the sweep line which meet at the sweep event. + * Sort them by slope. + */ + if (Geom.VertLeq(e1.Org, e2.Org)) { + return Geom.EdgeSign(e2.Sym.Org, e1.Org, e2.Org) <= 0; + } + return Geom.EdgeSign(e1.Sym.Org, e2.Org, e1.Org) >= 0; + } + return Geom.EdgeSign(e2.Sym.Org, event, e2.Org) <= 0; + } + if (e2.Sym.Org == event) { + return Geom.EdgeSign(e1.Sym.Org, event, e1.Org) >= 0; + } + + /* General case - compute signed distance *from* e1, e2 to event */ + t1 = Geom.EdgeEval(e1.Sym.Org, event, e1.Org); + t2 = Geom.EdgeEval(e2.Sym.Org, event, e2.Org); + return (t1 >= t2); + } + + + static void DeleteRegion(GLUtessellatorImpl tess, ActiveRegion reg) { + if (reg.fixUpperEdge) { + /* It was created with zero winding number, so it better be + * deleted with zero winding number (ie. it better not get merged + * with a real edge). + */ + assert (reg.eUp.winding == 0); + } + reg.eUp.activeRegion = null; + Dict.dictDelete(tess.dict, reg.nodeUp); /* __gl_dictListDelete */ + } + + + static boolean FixUpperEdge(ActiveRegion reg, GLUhalfEdge newEdge) +/* + * Replace an upper edge which needs fixing (see ConnectRightVertex). + */ { + assert (reg.fixUpperEdge); + if (!Mesh.__gl_meshDelete(reg.eUp)) return false; + reg.fixUpperEdge = false; + reg.eUp = newEdge; + newEdge.activeRegion = reg; + + return true; + } + + static ActiveRegion TopLeftRegion(ActiveRegion reg) { + GLUvertex org = reg.eUp.Org; + GLUhalfEdge e; + + /* Find the region above the uppermost edge with the same origin */ + do { + reg = RegionAbove(reg); + } while (reg.eUp.Org == org); + + /* If the edge above was a temporary edge introduced by ConnectRightVertex, + * now is the time to fix it. + */ + if (reg.fixUpperEdge) { + e = Mesh.__gl_meshConnect(RegionBelow(reg).eUp.Sym, reg.eUp.Lnext); + if (e == null) return null; + if (!FixUpperEdge(reg, e)) return null; + reg = RegionAbove(reg); + } + return reg; + } + + static ActiveRegion TopRightRegion(ActiveRegion reg) { + GLUvertex dst = reg.eUp.Sym.Org; + + /* Find the region above the uppermost edge with the same destination */ + do { + reg = RegionAbove(reg); + } while (reg.eUp.Sym.Org == dst); + return reg; + } + + static ActiveRegion AddRegionBelow(GLUtessellatorImpl tess, + ActiveRegion regAbove, + GLUhalfEdge eNewUp) +/* + * Add a new active region to the sweep line, *somewhere* below "regAbove" + * (according to where the new edge belongs in the sweep-line dictionary). + * The upper edge of the new region will be "eNewUp". + * Winding number and "inside" flag are not updated. + */ { + ActiveRegion regNew = new ActiveRegion(); + //if (regNew == null) throw new RuntimeException(); + + regNew.eUp = eNewUp; + /* __gl_dictListInsertBefore */ + regNew.nodeUp = Dict.dictInsertBefore(tess.dict, regAbove.nodeUp, regNew); + if (regNew.nodeUp == null) throw new RuntimeException(); + regNew.fixUpperEdge = false; + regNew.sentinel = false; + regNew.dirty = false; + + eNewUp.activeRegion = regNew; + return regNew; + } + + static boolean IsWindingInside(GLUtessellatorImpl tess, int n) { + switch (tess.windingRule) { + case GLU_TESS_WINDING_ODD: + return (n & 1) != 0; + case GLU_TESS_WINDING_NONZERO: + return (n != 0); + case GLU_TESS_WINDING_POSITIVE: + return (n > 0); + case GLU_TESS_WINDING_NEGATIVE: + return (n < 0); + case GLU_TESS_WINDING_ABS_GEQ_TWO: + return (n >= 2) || (n <= -2); + } + /*LINTED*/ +// assert (false); + throw new InternalError(); + /*NOTREACHED*/ + } + + + static void ComputeWinding(GLUtessellatorImpl tess, ActiveRegion reg) { + reg.windingNumber = RegionAbove(reg).windingNumber + reg.eUp.winding; + reg.inside = IsWindingInside(tess, reg.windingNumber); + } + + + static void FinishRegion(GLUtessellatorImpl tess, ActiveRegion reg) +/* + * Delete a region from the sweep line. This happens when the upper + * and lower chains of a region meet (at a vertex on the sweep line). + * The "inside" flag is copied to the appropriate mesh face (we could + * not do this before -- since the structure of the mesh is always + * changing, this face may not have even existed until now). + */ { + GLUhalfEdge e = reg.eUp; + GLUface f = e.Lface; + + f.inside = reg.inside; + f.anEdge = e; /* optimization for __gl_meshTessellateMonoRegion() */ + DeleteRegion(tess, reg); + } + + + static GLUhalfEdge FinishLeftRegions(GLUtessellatorImpl tess, + ActiveRegion regFirst, ActiveRegion regLast) +/* + * We are given a vertex with one or more left-going edges. All affected + * edges should be in the edge dictionary. Starting at regFirst.eUp, + * we walk down deleting all regions where both edges have the same + * origin vOrg. At the same time we copy the "inside" flag from the + * active region to the face, since at this point each face will belong + * to at most one region (this was not necessarily true until this point + * in the sweep). The walk stops at the region above regLast; if regLast + * is null we walk as far as possible. At the same time we relink the + * mesh if necessary, so that the ordering of edges around vOrg is the + * same as in the dictionary. + */ { + ActiveRegion reg, regPrev; + GLUhalfEdge e, ePrev; + + regPrev = regFirst; + ePrev = regFirst.eUp; + while (regPrev != regLast) { + regPrev.fixUpperEdge = false; /* placement was OK */ + reg = RegionBelow(regPrev); + e = reg.eUp; + if (e.Org != ePrev.Org) { + if (!reg.fixUpperEdge) { + /* Remove the last left-going edge. Even though there are no further + * edges in the dictionary with this origin, there may be further + * such edges in the mesh (if we are adding left edges to a vertex + * that has already been processed). Thus it is important to call + * FinishRegion rather than just DeleteRegion. + */ + FinishRegion(tess, regPrev); + break; + } + /* If the edge below was a temporary edge introduced by + * ConnectRightVertex, now is the time to fix it. + */ + e = Mesh.__gl_meshConnect(ePrev.Onext.Sym, e.Sym); + if (e == null) throw new RuntimeException(); + if (!FixUpperEdge(reg, e)) throw new RuntimeException(); + } + + /* Relink edges so that ePrev.Onext == e */ + if (ePrev.Onext != e) { + if (!Mesh.__gl_meshSplice(e.Sym.Lnext, e)) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(ePrev, e)) throw new RuntimeException(); + } + FinishRegion(tess, regPrev); /* may change reg.eUp */ + ePrev = reg.eUp; + regPrev = reg; + } + return ePrev; + } + + + static void AddRightEdges(GLUtessellatorImpl tess, ActiveRegion regUp, + GLUhalfEdge eFirst, GLUhalfEdge eLast, GLUhalfEdge eTopLeft, + boolean cleanUp) +/* + * Purpose: insert right-going edges into the edge dictionary, and update + * winding numbers and mesh connectivity appropriately. All right-going + * edges share a common origin vOrg. Edges are inserted CCW starting at + * eFirst; the last edge inserted is eLast.Sym.Lnext. If vOrg has any + * left-going edges already processed, then eTopLeft must be the edge + * such that an imaginary upward vertical segment from vOrg would be + * contained between eTopLeft.Sym.Lnext and eTopLeft; otherwise eTopLeft + * should be null. + */ { + ActiveRegion reg, regPrev; + GLUhalfEdge e, ePrev; + boolean firstTime = true; + + /* Insert the new right-going edges in the dictionary */ + e = eFirst; + do { + assert (Geom.VertLeq(e.Org, e.Sym.Org)); + AddRegionBelow(tess, regUp, e.Sym); + e = e.Onext; + } while (e != eLast); + + /* Walk *all* right-going edges from e.Org, in the dictionary order, + * updating the winding numbers of each region, and re-linking the mesh + * edges to match the dictionary ordering (if necessary). + */ + if (eTopLeft == null) { + eTopLeft = RegionBelow(regUp).eUp.Sym.Onext; + } + regPrev = regUp; + ePrev = eTopLeft; + for (; ;) { + reg = RegionBelow(regPrev); + e = reg.eUp.Sym; + if (e.Org != ePrev.Org) break; + + if (e.Onext != ePrev) { + /* Unlink e from its current position, and relink below ePrev */ + if (!Mesh.__gl_meshSplice(e.Sym.Lnext, e)) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(ePrev.Sym.Lnext, e)) throw new RuntimeException(); + } + /* Compute the winding number and "inside" flag for the new regions */ + reg.windingNumber = regPrev.windingNumber - e.winding; + reg.inside = IsWindingInside(tess, reg.windingNumber); + + /* Check for two outgoing edges with same slope -- process these + * before any intersection tests (see example in __gl_computeInterior). + */ + regPrev.dirty = true; + if (!firstTime && CheckForRightSplice(tess, regPrev)) { + AddWinding(e, ePrev); + DeleteRegion(tess, regPrev); + if (!Mesh.__gl_meshDelete(ePrev)) throw new RuntimeException(); + } + firstTime = false; + regPrev = reg; + ePrev = e; + } + regPrev.dirty = true; + assert (regPrev.windingNumber - e.winding == reg.windingNumber); + + if (cleanUp) { + /* Check for intersections between newly adjacent edges. */ + WalkDirtyRegions(tess, regPrev); + } + } + + + static void CallCombine(GLUtessellatorImpl tess, GLUvertex isect, + Object[] data, float[] weights, boolean needed) { + double[] coords = new double[3]; + + /* Copy coord data in case the callback changes it. */ + coords[0] = isect.coords[0]; + coords[1] = isect.coords[1]; + coords[2] = isect.coords[2]; + + Object[] outData = new Object[1]; + tess.callCombineOrCombineData(coords, data, weights, outData); + isect.data = outData[0]; + if (isect.data == null) { + if (!needed) { + isect.data = data[0]; + } else if (!tess.fatalError) { + /* The only way fatal error is when two edges are found to intersect, + * but the user has not provided the callback necessary to handle + * generated intersection points. + */ + tess.callErrorOrErrorData(GLU_TESS_NEED_COMBINE_CALLBACK); + tess.fatalError = true; + } + } + } + + static void SpliceMergeVertices(GLUtessellatorImpl tess, GLUhalfEdge e1, + GLUhalfEdge e2) +/* + * Two vertices with idential coordinates are combined into one. + * e1.Org is kept, while e2.Org is discarded. + */ { + Object[] data = new Object[4]; + float[] weights = new float[]{0.5f, 0.5f, 0.0f, 0.0f}; + + data[0] = e1.Org.data; + data[1] = e2.Org.data; + CallCombine(tess, e1.Org, data, weights, false); + if (!Mesh.__gl_meshSplice(e1, e2)) throw new RuntimeException(); + } + + static void VertexWeights(GLUvertex isect, GLUvertex org, GLUvertex dst, + float[] weights) +/* + * Find some weights which describe how the intersection vertex is + * a linear combination of "org" and "dest". Each of the two edges + * which generated "isect" is allocated 50% of the weight; each edge + * splits the weight between its org and dst according to the + * relative distance to "isect". + */ { + double t1 = Geom.VertL1dist(org, isect); + double t2 = Geom.VertL1dist(dst, isect); + + weights[0] = (float) (0.5 * t2 / (t1 + t2)); + weights[1] = (float) (0.5 * t1 / (t1 + t2)); + isect.coords[0] += weights[0] * org.coords[0] + weights[1] * dst.coords[0]; + isect.coords[1] += weights[0] * org.coords[1] + weights[1] * dst.coords[1]; + isect.coords[2] += weights[0] * org.coords[2] + weights[1] * dst.coords[2]; + } + + + static void GetIntersectData(GLUtessellatorImpl tess, GLUvertex isect, + GLUvertex orgUp, GLUvertex dstUp, + GLUvertex orgLo, GLUvertex dstLo) +/* + * We've computed a new intersection point, now we need a "data" pointer + * from the user so that we can refer to this new vertex in the + * rendering callbacks. + */ { + Object[] data = new Object[4]; + float[] weights = new float[4]; + float[] weights1 = new float[2]; + float[] weights2 = new float[2]; + + data[0] = orgUp.data; + data[1] = dstUp.data; + data[2] = orgLo.data; + data[3] = dstLo.data; + + isect.coords[0] = isect.coords[1] = isect.coords[2] = 0; + VertexWeights(isect, orgUp, dstUp, weights1); + VertexWeights(isect, orgLo, dstLo, weights2); + System.arraycopy(weights1, 0, weights, 0, 2); + System.arraycopy(weights2, 0, weights, 2, 2); + + CallCombine(tess, isect, data, weights, true); + } + + static boolean CheckForRightSplice(GLUtessellatorImpl tess, ActiveRegion regUp) +/* + * Check the upper and lower edge of "regUp", to make sure that the + * eUp.Org is above eLo, or eLo.Org is below eUp (depending on which + * origin is leftmost). + * + * The main purpose is to splice right-going edges with the same + * dest vertex and nearly identical slopes (ie. we can't distinguish + * the slopes numerically). However the splicing can also help us + * to recover from numerical errors. For example, suppose at one + * point we checked eUp and eLo, and decided that eUp.Org is barely + * above eLo. Then later, we split eLo into two edges (eg. from + * a splice operation like this one). This can change the result of + * our test so that now eUp.Org is incident to eLo, or barely below it. + * We must correct this condition to maintain the dictionary invariants. + * + * One possibility is to check these edges for intersection again + * (ie. CheckForIntersect). This is what we do if possible. However + * CheckForIntersect requires that tess.event lies between eUp and eLo, + * so that it has something to fall back on when the intersection + * calculation gives us an unusable answer. So, for those cases where + * we can't check for intersection, this routine fixes the problem + * by just splicing the offending vertex into the other edge. + * This is a guaranteed solution, no matter how degenerate things get. + * Basically this is a combinatorial solution to a numerical problem. + */ { + ActiveRegion regLo = RegionBelow(regUp); + GLUhalfEdge eUp = regUp.eUp; + GLUhalfEdge eLo = regLo.eUp; + + if (Geom.VertLeq(eUp.Org, eLo.Org)) { + if (Geom.EdgeSign(eLo.Sym.Org, eUp.Org, eLo.Org) > 0) return false; + + /* eUp.Org appears to be below eLo */ + if (!Geom.VertEq(eUp.Org, eLo.Org)) { + /* Splice eUp.Org into eLo */ + if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(eUp, eLo.Sym.Lnext)) throw new RuntimeException(); + regUp.dirty = regLo.dirty = true; + + } else if (eUp.Org != eLo.Org) { + /* merge the two vertices, discarding eUp.Org */ + tess.pq.pqDelete(eUp.Org.pqHandle); /* __gl_pqSortDelete */ + SpliceMergeVertices(tess, eLo.Sym.Lnext, eUp); + } + } else { + if (Geom.EdgeSign(eUp.Sym.Org, eLo.Org, eUp.Org) < 0) return false; + + /* eLo.Org appears to be above eUp, so splice eLo.Org into eUp */ + RegionAbove(regUp).dirty = regUp.dirty = true; + if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(eLo.Sym.Lnext, eUp)) throw new RuntimeException(); + } + return true; + } + + static boolean CheckForLeftSplice(GLUtessellatorImpl tess, ActiveRegion regUp) +/* + * Check the upper and lower edge of "regUp", to make sure that the + * eUp.Sym.Org is above eLo, or eLo.Sym.Org is below eUp (depending on which + * destination is rightmost). + * + * Theoretically, this should always be true. However, splitting an edge + * into two pieces can change the results of previous tests. For example, + * suppose at one point we checked eUp and eLo, and decided that eUp.Sym.Org + * is barely above eLo. Then later, we split eLo into two edges (eg. from + * a splice operation like this one). This can change the result of + * the test so that now eUp.Sym.Org is incident to eLo, or barely below it. + * We must correct this condition to maintain the dictionary invariants + * (otherwise new edges might get inserted in the wrong place in the + * dictionary, and bad stuff will happen). + * + * We fix the problem by just splicing the offending vertex into the + * other edge. + */ { + ActiveRegion regLo = RegionBelow(regUp); + GLUhalfEdge eUp = regUp.eUp; + GLUhalfEdge eLo = regLo.eUp; + GLUhalfEdge e; + + assert (!Geom.VertEq(eUp.Sym.Org, eLo.Sym.Org)); + + if (Geom.VertLeq(eUp.Sym.Org, eLo.Sym.Org)) { + if (Geom.EdgeSign(eUp.Sym.Org, eLo.Sym.Org, eUp.Org) < 0) return false; + + /* eLo.Sym.Org is above eUp, so splice eLo.Sym.Org into eUp */ + RegionAbove(regUp).dirty = regUp.dirty = true; + e = Mesh.__gl_meshSplitEdge(eUp); + if (e == null) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(eLo.Sym, e)) throw new RuntimeException(); + e.Lface.inside = regUp.inside; + } else { + if (Geom.EdgeSign(eLo.Sym.Org, eUp.Sym.Org, eLo.Org) > 0) return false; + + /* eUp.Sym.Org is below eLo, so splice eUp.Sym.Org into eLo */ + regUp.dirty = regLo.dirty = true; + e = Mesh.__gl_meshSplitEdge(eLo); + if (e == null) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(eUp.Lnext, eLo.Sym)) throw new RuntimeException(); + e.Sym.Lface.inside = regUp.inside; + } + return true; + } + + + static boolean CheckForIntersect(GLUtessellatorImpl tess, ActiveRegion regUp) +/* + * Check the upper and lower edges of the given region to see if + * they intersect. If so, create the intersection and add it + * to the data structures. + * + * Returns true if adding the new intersection resulted in a recursive + * call to AddRightEdges(); in this case all "dirty" regions have been + * checked for intersections, and possibly regUp has been deleted. + */ { + ActiveRegion regLo = RegionBelow(regUp); + GLUhalfEdge eUp = regUp.eUp; + GLUhalfEdge eLo = regLo.eUp; + GLUvertex orgUp = eUp.Org; + GLUvertex orgLo = eLo.Org; + GLUvertex dstUp = eUp.Sym.Org; + GLUvertex dstLo = eLo.Sym.Org; + double tMinUp, tMaxLo; + GLUvertex isect = new GLUvertex(); + GLUvertex orgMin; + GLUhalfEdge e; + + assert (!Geom.VertEq(dstLo, dstUp)); + assert (Geom.EdgeSign(dstUp, tess.event, orgUp) <= 0); + assert (Geom.EdgeSign(dstLo, tess.event, orgLo) >= 0); + assert (orgUp != tess.event && orgLo != tess.event); + assert (!regUp.fixUpperEdge && !regLo.fixUpperEdge); + + if (orgUp == orgLo) return false; /* right endpoints are the same */ + + tMinUp = Math.min(orgUp.t, dstUp.t); + tMaxLo = Math.max(orgLo.t, dstLo.t); + if (tMinUp > tMaxLo) return false; /* t ranges do not overlap */ + + if (Geom.VertLeq(orgUp, orgLo)) { + if (Geom.EdgeSign(dstLo, orgUp, orgLo) > 0) return false; + } else { + if (Geom.EdgeSign(dstUp, orgLo, orgUp) < 0) return false; + } + + /* At this point the edges intersect, at least marginally */ + DebugEvent(tess); + + Geom.EdgeIntersect(dstUp, orgUp, dstLo, orgLo, isect); + /* The following properties are guaranteed: */ + assert (Math.min(orgUp.t, dstUp.t) <= isect.t); + assert (isect.t <= Math.max(orgLo.t, dstLo.t)); + assert (Math.min(dstLo.s, dstUp.s) <= isect.s); + assert (isect.s <= Math.max(orgLo.s, orgUp.s)); + + if (Geom.VertLeq(isect, tess.event)) { + /* The intersection point lies slightly to the left of the sweep line, + * so move it until it''s slightly to the right of the sweep line. + * (If we had perfect numerical precision, this would never happen + * in the first place). The easiest and safest thing to do is + * replace the intersection by tess.event. + */ + isect.s = tess.event.s; + isect.t = tess.event.t; + } + /* Similarly, if the computed intersection lies to the right of the + * rightmost origin (which should rarely happen), it can cause + * unbelievable inefficiency on sufficiently degenerate inputs. + * (If you have the test program, try running test54.d with the + * "X zoom" option turned on). + */ + orgMin = Geom.VertLeq(orgUp, orgLo) ? orgUp : orgLo; + if (Geom.VertLeq(orgMin, isect)) { + isect.s = orgMin.s; + isect.t = orgMin.t; + } + + if (Geom.VertEq(isect, orgUp) || Geom.VertEq(isect, orgLo)) { + /* Easy case -- intersection at one of the right endpoints */ + CheckForRightSplice(tess, regUp); + return false; + } + + if ((!Geom.VertEq(dstUp, tess.event) + && Geom.EdgeSign(dstUp, tess.event, isect) >= 0) + || (!Geom.VertEq(dstLo, tess.event) + && Geom.EdgeSign(dstLo, tess.event, isect) <= 0)) { + /* Very unusual -- the new upper or lower edge would pass on the + * wrong side of the sweep event, or through it. This can happen + * due to very small numerical errors in the intersection calculation. + */ + if (dstLo == tess.event) { + /* Splice dstLo into eUp, and process the new region(s) */ + if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(eLo.Sym, eUp)) throw new RuntimeException(); + regUp = TopLeftRegion(regUp); + if (regUp == null) throw new RuntimeException(); + eUp = RegionBelow(regUp).eUp; + FinishLeftRegions(tess, RegionBelow(regUp), regLo); + AddRightEdges(tess, regUp, eUp.Sym.Lnext, eUp, eUp, true); + return true; + } + if (dstUp == tess.event) { + /* Splice dstUp into eLo, and process the new region(s) */ + if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(eUp.Lnext, eLo.Sym.Lnext)) throw new RuntimeException(); + regLo = regUp; + regUp = TopRightRegion(regUp); + e = RegionBelow(regUp).eUp.Sym.Onext; + regLo.eUp = eLo.Sym.Lnext; + eLo = FinishLeftRegions(tess, regLo, null); + AddRightEdges(tess, regUp, eLo.Onext, eUp.Sym.Onext, e, true); + return true; + } + /* Special case: called from ConnectRightVertex. If either + * edge passes on the wrong side of tess.event, split it + * (and wait for ConnectRightVertex to splice it appropriately). + */ + if (Geom.EdgeSign(dstUp, tess.event, isect) >= 0) { + RegionAbove(regUp).dirty = regUp.dirty = true; + if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException(); + eUp.Org.s = tess.event.s; + eUp.Org.t = tess.event.t; + } + if (Geom.EdgeSign(dstLo, tess.event, isect) <= 0) { + regUp.dirty = regLo.dirty = true; + if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException(); + eLo.Org.s = tess.event.s; + eLo.Org.t = tess.event.t; + } + /* leave the rest for ConnectRightVertex */ + return false; + } + + /* General case -- split both edges, splice into new vertex. + * When we do the splice operation, the order of the arguments is + * arbitrary as far as correctness goes. However, when the operation + * creates a new face, the work done is proportional to the size of + * the new face. We expect the faces in the processed part of + * the mesh (ie. eUp.Lface) to be smaller than the faces in the + * unprocessed original contours (which will be eLo.Sym.Lnext.Lface). + */ + if (Mesh.__gl_meshSplitEdge(eUp.Sym) == null) throw new RuntimeException(); + if (Mesh.__gl_meshSplitEdge(eLo.Sym) == null) throw new RuntimeException(); + if (!Mesh.__gl_meshSplice(eLo.Sym.Lnext, eUp)) throw new RuntimeException(); + eUp.Org.s = isect.s; + eUp.Org.t = isect.t; + eUp.Org.pqHandle = tess.pq.pqInsert(eUp.Org); /* __gl_pqSortInsert */ + if (eUp.Org.pqHandle == Long.MAX_VALUE) { + tess.pq.pqDeletePriorityQ(); /* __gl_pqSortDeletePriorityQ */ + tess.pq = null; + throw new RuntimeException(); + } + GetIntersectData(tess, eUp.Org, orgUp, dstUp, orgLo, dstLo); + RegionAbove(regUp).dirty = regUp.dirty = regLo.dirty = true; + return false; + } + + static void WalkDirtyRegions(GLUtessellatorImpl tess, ActiveRegion regUp) +/* + * When the upper or lower edge of any region changes, the region is + * marked "dirty". This routine walks through all the dirty regions + * and makes sure that the dictionary invariants are satisfied + * (see the comments at the beginning of this file). Of course + * new dirty regions can be created as we make changes to restore + * the invariants. + */ { + ActiveRegion regLo = RegionBelow(regUp); + GLUhalfEdge eUp, eLo; + + for (; ;) { + /* Find the lowest dirty region (we walk from the bottom up). */ + while (regLo.dirty) { + regUp = regLo; + regLo = RegionBelow(regLo); + } + if (!regUp.dirty) { + regLo = regUp; + regUp = RegionAbove(regUp); + if (regUp == null || !regUp.dirty) { + /* We've walked all the dirty regions */ + return; + } + } + regUp.dirty = false; + eUp = regUp.eUp; + eLo = regLo.eUp; + + if (eUp.Sym.Org != eLo.Sym.Org) { + /* Check that the edge ordering is obeyed at the Dst vertices. */ + if (CheckForLeftSplice(tess, regUp)) { + + /* If the upper or lower edge was marked fixUpperEdge, then + * we no longer need it (since these edges are needed only for + * vertices which otherwise have no right-going edges). + */ + if (regLo.fixUpperEdge) { + DeleteRegion(tess, regLo); + if (!Mesh.__gl_meshDelete(eLo)) throw new RuntimeException(); + regLo = RegionBelow(regUp); + eLo = regLo.eUp; + } else if (regUp.fixUpperEdge) { + DeleteRegion(tess, regUp); + if (!Mesh.__gl_meshDelete(eUp)) throw new RuntimeException(); + regUp = RegionAbove(regLo); + eUp = regUp.eUp; + } + } + } + if (eUp.Org != eLo.Org) { + if (eUp.Sym.Org != eLo.Sym.Org + && !regUp.fixUpperEdge && !regLo.fixUpperEdge + && (eUp.Sym.Org == tess.event || eLo.Sym.Org == tess.event)) { + /* When all else fails in CheckForIntersect(), it uses tess.event + * as the intersection location. To make this possible, it requires + * that tess.event lie between the upper and lower edges, and also + * that neither of these is marked fixUpperEdge (since in the worst + * case it might splice one of these edges into tess.event, and + * violate the invariant that fixable edges are the only right-going + * edge from their associated vertex). + */ + if (CheckForIntersect(tess, regUp)) { + /* WalkDirtyRegions() was called recursively; we're done */ + return; + } + } else { + /* Even though we can't use CheckForIntersect(), the Org vertices + * may violate the dictionary edge ordering. Check and correct this. + */ + CheckForRightSplice(tess, regUp); + } + } + if (eUp.Org == eLo.Org && eUp.Sym.Org == eLo.Sym.Org) { + /* A degenerate loop consisting of only two edges -- delete it. */ + AddWinding(eLo, eUp); + DeleteRegion(tess, regUp); + if (!Mesh.__gl_meshDelete(eUp)) throw new RuntimeException(); + regUp = RegionAbove(regLo); + } + } + } + + + static void ConnectRightVertex(GLUtessellatorImpl tess, ActiveRegion regUp, + GLUhalfEdge eBottomLeft) +/* + * Purpose: connect a "right" vertex vEvent (one where all edges go left) + * to the unprocessed portion of the mesh. Since there are no right-going + * edges, two regions (one above vEvent and one below) are being merged + * into one. "regUp" is the upper of these two regions. + * + * There are two reasons for doing this (adding a right-going edge): + * - if the two regions being merged are "inside", we must add an edge + * to keep them separated (the combined region would not be monotone). + * - in any case, we must leave some record of vEvent in the dictionary, + * so that we can merge vEvent with features that we have not seen yet. + * For example, maybe there is a vertical edge which passes just to + * the right of vEvent; we would like to splice vEvent into this edge. + * + * However, we don't want to connect vEvent to just any vertex. We don''t + * want the new edge to cross any other edges; otherwise we will create + * intersection vertices even when the input data had no self-intersections. + * (This is a bad thing; if the user's input data has no intersections, + * we don't want to generate any false intersections ourselves.) + * + * Our eventual goal is to connect vEvent to the leftmost unprocessed + * vertex of the combined region (the union of regUp and regLo). + * But because of unseen vertices with all right-going edges, and also + * new vertices which may be created by edge intersections, we don''t + * know where that leftmost unprocessed vertex is. In the meantime, we + * connect vEvent to the closest vertex of either chain, and mark the region + * as "fixUpperEdge". This flag says to delete and reconnect this edge + * to the next processed vertex on the boundary of the combined region. + * Quite possibly the vertex we connected to will turn out to be the + * closest one, in which case we won''t need to make any changes. + */ { + GLUhalfEdge eNew; + GLUhalfEdge eTopLeft = eBottomLeft.Onext; + ActiveRegion regLo = RegionBelow(regUp); + GLUhalfEdge eUp = regUp.eUp; + GLUhalfEdge eLo = regLo.eUp; + boolean degenerate = false; + + if (eUp.Sym.Org != eLo.Sym.Org) { + CheckForIntersect(tess, regUp); + } + + /* Possible new degeneracies: upper or lower edge of regUp may pass + * through vEvent, or may coincide with new intersection vertex + */ + if (Geom.VertEq(eUp.Org, tess.event)) { + if (!Mesh.__gl_meshSplice(eTopLeft.Sym.Lnext, eUp)) throw new RuntimeException(); + regUp = TopLeftRegion(regUp); + if (regUp == null) throw new RuntimeException(); + eTopLeft = RegionBelow(regUp).eUp; + FinishLeftRegions(tess, RegionBelow(regUp), regLo); + degenerate = true; + } + if (Geom.VertEq(eLo.Org, tess.event)) { + if (!Mesh.__gl_meshSplice(eBottomLeft, eLo.Sym.Lnext)) throw new RuntimeException(); + eBottomLeft = FinishLeftRegions(tess, regLo, null); + degenerate = true; + } + if (degenerate) { + AddRightEdges(tess, regUp, eBottomLeft.Onext, eTopLeft, eTopLeft, true); + return; + } + + /* Non-degenerate situation -- need to add a temporary, fixable edge. + * Connect to the closer of eLo.Org, eUp.Org. + */ + if (Geom.VertLeq(eLo.Org, eUp.Org)) { + eNew = eLo.Sym.Lnext; + } else { + eNew = eUp; + } + eNew = Mesh.__gl_meshConnect(eBottomLeft.Onext.Sym, eNew); + if (eNew == null) throw new RuntimeException(); + + /* Prevent cleanup, otherwise eNew might disappear before we've even + * had a chance to mark it as a temporary edge. + */ + AddRightEdges(tess, regUp, eNew, eNew.Onext, eNew.Onext, false); + eNew.Sym.activeRegion.fixUpperEdge = true; + WalkDirtyRegions(tess, regUp); + } + +/* Because vertices at exactly the same location are merged together + * before we process the sweep event, some degenerate cases can't occur. + * However if someone eventually makes the modifications required to + * merge features which are close together, the cases below marked + * TOLERANCE_NONZERO will be useful. They were debugged before the + * code to merge identical vertices in the main loop was added. + */ + private static final boolean TOLERANCE_NONZERO = false; + + static void ConnectLeftDegenerate(GLUtessellatorImpl tess, + ActiveRegion regUp, GLUvertex vEvent) +/* + * The event vertex lies exacty on an already-processed edge or vertex. + * Adding the new vertex involves splicing it into the already-processed + * part of the mesh. + */ { + GLUhalfEdge e, eTopLeft, eTopRight, eLast; + ActiveRegion reg; + + e = regUp.eUp; + if (Geom.VertEq(e.Org, vEvent)) { + /* e.Org is an unprocessed vertex - just combine them, and wait + * for e.Org to be pulled from the queue + */ + assert (TOLERANCE_NONZERO); + SpliceMergeVertices(tess, e, vEvent.anEdge); + return; + } + + if (!Geom.VertEq(e.Sym.Org, vEvent)) { + /* General case -- splice vEvent into edge e which passes through it */ + if (Mesh.__gl_meshSplitEdge(e.Sym) == null) throw new RuntimeException(); + if (regUp.fixUpperEdge) { + /* This edge was fixable -- delete unused portion of original edge */ + if (!Mesh.__gl_meshDelete(e.Onext)) throw new RuntimeException(); + regUp.fixUpperEdge = false; + } + if (!Mesh.__gl_meshSplice(vEvent.anEdge, e)) throw new RuntimeException(); + SweepEvent(tess, vEvent); /* recurse */ + return; + } + + /* vEvent coincides with e.Sym.Org, which has already been processed. + * Splice in the additional right-going edges. + */ + assert (TOLERANCE_NONZERO); + regUp = TopRightRegion(regUp); + reg = RegionBelow(regUp); + eTopRight = reg.eUp.Sym; + eTopLeft = eLast = eTopRight.Onext; + if (reg.fixUpperEdge) { + /* Here e.Sym.Org has only a single fixable edge going right. + * We can delete it since now we have some real right-going edges. + */ + assert (eTopLeft != eTopRight); /* there are some left edges too */ + DeleteRegion(tess, reg); + if (!Mesh.__gl_meshDelete(eTopRight)) throw new RuntimeException(); + eTopRight = eTopLeft.Sym.Lnext; + } + if (!Mesh.__gl_meshSplice(vEvent.anEdge, eTopRight)) throw new RuntimeException(); + if (!Geom.EdgeGoesLeft(eTopLeft)) { + /* e.Sym.Org had no left-going edges -- indicate this to AddRightEdges() */ + eTopLeft = null; + } + AddRightEdges(tess, regUp, eTopRight.Onext, eLast, eTopLeft, true); + } + + + static void ConnectLeftVertex(GLUtessellatorImpl tess, GLUvertex vEvent) +/* + * Purpose: connect a "left" vertex (one where both edges go right) + * to the processed portion of the mesh. Let R be the active region + * containing vEvent, and let U and L be the upper and lower edge + * chains of R. There are two possibilities: + * + * - the normal case: split R into two regions, by connecting vEvent to + * the rightmost vertex of U or L lying to the left of the sweep line + * + * - the degenerate case: if vEvent is close enough to U or L, we + * merge vEvent into that edge chain. The subcases are: + * - merging with the rightmost vertex of U or L + * - merging with the active edge of U or L + * - merging with an already-processed portion of U or L + */ { + ActiveRegion regUp, regLo, reg; + GLUhalfEdge eUp, eLo, eNew; + ActiveRegion tmp = new ActiveRegion(); + + /* assert ( vEvent.anEdge.Onext.Onext == vEvent.anEdge ); */ + + /* Get a pointer to the active region containing vEvent */ + tmp.eUp = vEvent.anEdge.Sym; + /* __GL_DICTLISTKEY */ /* __gl_dictListSearch */ + regUp = (ActiveRegion) Dict.dictKey(Dict.dictSearch(tess.dict, tmp)); + regLo = RegionBelow(regUp); + eUp = regUp.eUp; + eLo = regLo.eUp; + + /* Try merging with U or L first */ + if (Geom.EdgeSign(eUp.Sym.Org, vEvent, eUp.Org) == 0) { + ConnectLeftDegenerate(tess, regUp, vEvent); + return; + } + + /* Connect vEvent to rightmost processed vertex of either chain. + * e.Sym.Org is the vertex that we will connect to vEvent. + */ + reg = Geom.VertLeq(eLo.Sym.Org, eUp.Sym.Org) ? regUp : regLo; + + if (regUp.inside || reg.fixUpperEdge) { + if (reg == regUp) { + eNew = Mesh.__gl_meshConnect(vEvent.anEdge.Sym, eUp.Lnext); + if (eNew == null) throw new RuntimeException(); + } else { + GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(eLo.Sym.Onext.Sym, vEvent.anEdge); + if (tempHalfEdge == null) throw new RuntimeException(); + + eNew = tempHalfEdge.Sym; + } + if (reg.fixUpperEdge) { + if (!FixUpperEdge(reg, eNew)) throw new RuntimeException(); + } else { + ComputeWinding(tess, AddRegionBelow(tess, regUp, eNew)); + } + SweepEvent(tess, vEvent); + } else { + /* The new vertex is in a region which does not belong to the polygon. + * We don''t need to connect this vertex to the rest of the mesh. + */ + AddRightEdges(tess, regUp, vEvent.anEdge, vEvent.anEdge, null, true); + } + } + + + static void SweepEvent(GLUtessellatorImpl tess, GLUvertex vEvent) +/* + * Does everything necessary when the sweep line crosses a vertex. + * Updates the mesh and the edge dictionary. + */ { + ActiveRegion regUp, reg; + GLUhalfEdge e, eTopLeft, eBottomLeft; + + tess.event = vEvent; /* for access in EdgeLeq() */ + DebugEvent(tess); + + /* Check if this vertex is the right endpoint of an edge that is + * already in the dictionary. In this case we don't need to waste + * time searching for the location to insert new edges. + */ + e = vEvent.anEdge; + while (e.activeRegion == null) { + e = e.Onext; + if (e == vEvent.anEdge) { + /* All edges go right -- not incident to any processed edges */ + ConnectLeftVertex(tess, vEvent); + return; + } + } + + /* Processing consists of two phases: first we "finish" all the + * active regions where both the upper and lower edges terminate + * at vEvent (ie. vEvent is closing off these regions). + * We mark these faces "inside" or "outside" the polygon according + * to their winding number, and delete the edges from the dictionary. + * This takes care of all the left-going edges from vEvent. + */ + regUp = TopLeftRegion(e.activeRegion); + if (regUp == null) throw new RuntimeException(); + reg = RegionBelow(regUp); + eTopLeft = reg.eUp; + eBottomLeft = FinishLeftRegions(tess, reg, null); + + /* Next we process all the right-going edges from vEvent. This + * involves adding the edges to the dictionary, and creating the + * associated "active regions" which record information about the + * regions between adjacent dictionary edges. + */ + if (eBottomLeft.Onext == eTopLeft) { + /* No right-going edges -- add a temporary "fixable" edge */ + ConnectRightVertex(tess, regUp, eBottomLeft); + } else { + AddRightEdges(tess, regUp, eBottomLeft.Onext, eTopLeft, eTopLeft, true); + } + } + + +/* Make the sentinel coordinates big enough that they will never be + * merged with real input features. (Even with the largest possible + * input contour and the maximum tolerance of 1.0, no merging will be + * done with coordinates larger than 3 * GLU_TESS_MAX_COORD). + */ + private static final double SENTINEL_COORD = (4.0 * GLU_TESS_MAX_COORD); + + static void AddSentinel(GLUtessellatorImpl tess, double t) +/* + * We add two sentinel edges above and below all other edges, + * to avoid special cases at the top and bottom. + */ { + GLUhalfEdge e; + ActiveRegion reg = new ActiveRegion(); + //if (reg == null) throw new RuntimeException(); + + e = Mesh.__gl_meshMakeEdge(tess.mesh); + if (e == null) throw new RuntimeException(); + + e.Org.s = SENTINEL_COORD; + e.Org.t = t; + e.Sym.Org.s = -SENTINEL_COORD; + e.Sym.Org.t = t; + tess.event = e.Sym.Org; /* initialize it */ + + reg.eUp = e; + reg.windingNumber = 0; + reg.inside = false; + reg.fixUpperEdge = false; + reg.sentinel = true; + reg.dirty = false; + reg.nodeUp = Dict.dictInsert(tess.dict, reg); /* __gl_dictListInsertBefore */ + if (reg.nodeUp == null) throw new RuntimeException(); + } + + + static void InitEdgeDict(final GLUtessellatorImpl tess) +/* + * We maintain an ordering of edge intersections with the sweep line. + * This order is maintained in a dynamic dictionary. + */ { + /* __gl_dictListNewDict */ + tess.dict = Dict.dictNewDict(tess, new Dict.DictLeq() { + public boolean leq(Object frame, Object key1, Object key2) { + return EdgeLeq(tess, (ActiveRegion) key1, (ActiveRegion) key2); + } + }); + if (tess.dict == null) throw new RuntimeException(); + + AddSentinel(tess, -SENTINEL_COORD); + AddSentinel(tess, SENTINEL_COORD); + } + + + static void DoneEdgeDict(GLUtessellatorImpl tess) { + ActiveRegion reg; + int fixedEdges = 0; + + /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */ + while ((reg = (ActiveRegion) Dict.dictKey(Dict.dictMin(tess.dict))) != null) { + /* + * At the end of all processing, the dictionary should contain + * only the two sentinel edges, plus at most one "fixable" edge + * created by ConnectRightVertex(). + */ + if (!reg.sentinel) { + assert (reg.fixUpperEdge); + assert (++fixedEdges == 1); + } + assert (reg.windingNumber == 0); + DeleteRegion(tess, reg); +/* __gl_meshDelete( reg.eUp );*/ + } + Dict.dictDeleteDict(tess.dict); /* __gl_dictListDeleteDict */ + } + + + static void RemoveDegenerateEdges(GLUtessellatorImpl tess) +/* + * Remove zero-length edges, and contours with fewer than 3 vertices. + */ { + GLUhalfEdge e, eNext, eLnext; + GLUhalfEdge eHead = tess.mesh.eHead; + + /*LINTED*/ + for (e = eHead.next; e != eHead; e = eNext) { + eNext = e.next; + eLnext = e.Lnext; + + if (Geom.VertEq(e.Org, e.Sym.Org) && e.Lnext.Lnext != e) { + /* Zero-length edge, contour has at least 3 edges */ + + SpliceMergeVertices(tess, eLnext, e); /* deletes e.Org */ + if (!Mesh.__gl_meshDelete(e)) throw new RuntimeException(); /* e is a self-loop */ + e = eLnext; + eLnext = e.Lnext; + } + if (eLnext.Lnext == e) { + /* Degenerate contour (one or two edges) */ + + if (eLnext != e) { + if (eLnext == eNext || eLnext == eNext.Sym) { + eNext = eNext.next; + } + if (!Mesh.__gl_meshDelete(eLnext)) throw new RuntimeException(); + } + if (e == eNext || e == eNext.Sym) { + eNext = eNext.next; + } + if (!Mesh.__gl_meshDelete(e)) throw new RuntimeException(); + } + } + } + + static boolean InitPriorityQ(GLUtessellatorImpl tess) +/* + * Insert all vertices into the priority queue which determines the + * order in which vertices cross the sweep line. + */ { + PriorityQ pq; + GLUvertex v, vHead; + + /* __gl_pqSortNewPriorityQ */ + pq = tess.pq = PriorityQ.pqNewPriorityQ(new PriorityQ.Leq() { + public boolean leq(Object key1, Object key2) { + return Geom.VertLeq(((GLUvertex) key1), (GLUvertex) key2); + } + }); + if (pq == null) return false; + + vHead = tess.mesh.vHead; + for (v = vHead.next; v != vHead; v = v.next) { + v.pqHandle = pq.pqInsert(v); /* __gl_pqSortInsert */ + if (v.pqHandle == Long.MAX_VALUE) break; + } + if (v != vHead || !pq.pqInit()) { /* __gl_pqSortInit */ + tess.pq.pqDeletePriorityQ(); /* __gl_pqSortDeletePriorityQ */ + tess.pq = null; + return false; + } + + return true; + } + + + static void DonePriorityQ(GLUtessellatorImpl tess) { + tess.pq.pqDeletePriorityQ(); /* __gl_pqSortDeletePriorityQ */ + } + + + static boolean RemoveDegenerateFaces(GLUmesh mesh) +/* + * Delete any degenerate faces with only two edges. WalkDirtyRegions() + * will catch almost all of these, but it won't catch degenerate faces + * produced by splice operations on already-processed edges. + * The two places this can happen are in FinishLeftRegions(), when + * we splice in a "temporary" edge produced by ConnectRightVertex(), + * and in CheckForLeftSplice(), where we splice already-processed + * edges to ensure that our dictionary invariants are not violated + * by numerical errors. + * + * In both these cases it is *very* dangerous to delete the offending + * edge at the time, since one of the routines further up the stack + * will sometimes be keeping a pointer to that edge. + */ { + GLUface f, fNext; + GLUhalfEdge e; + + /*LINTED*/ + for (f = mesh.fHead.next; f != mesh.fHead; f = fNext) { + fNext = f.next; + e = f.anEdge; + assert (e.Lnext != e); + + if (e.Lnext.Lnext == e) { + /* A face with only two edges */ + AddWinding(e.Onext, e); + if (!Mesh.__gl_meshDelete(e)) return false; + } + } + return true; + } + + public static boolean __gl_computeInterior(GLUtessellatorImpl tess) +/* + * __gl_computeInterior( tess ) computes the planar arrangement specified + * by the given contours, and further subdivides this arrangement + * into regions. Each region is marked "inside" if it belongs + * to the polygon, according to the rule given by tess.windingRule. + * Each interior region is guaranteed be monotone. + */ { + GLUvertex v, vNext; + + tess.fatalError = false; + + /* Each vertex defines an event for our sweep line. Start by inserting + * all the vertices in a priority queue. Events are processed in + * lexicographic order, ie. + * + * e1 < e2 iff e1.x < e2.x || (e1.x == e2.x && e1.y < e2.y) + */ + RemoveDegenerateEdges(tess); + if (!InitPriorityQ(tess)) return false; /* if error */ + InitEdgeDict(tess); + + /* __gl_pqSortExtractMin */ + while ((v = (GLUvertex) tess.pq.pqExtractMin()) != null) { + for (; ;) { + vNext = (GLUvertex) tess.pq.pqMinimum(); /* __gl_pqSortMinimum */ + if (vNext == null || !Geom.VertEq(vNext, v)) break; + + /* Merge together all vertices at exactly the same location. + * This is more efficient than processing them one at a time, + * simplifies the code (see ConnectLeftDegenerate), and is also + * important for correct handling of certain degenerate cases. + * For example, suppose there are two identical edges A and B + * that belong to different contours (so without this code they would + * be processed by separate sweep events). Suppose another edge C + * crosses A and B from above. When A is processed, we split it + * at its intersection point with C. However this also splits C, + * so when we insert B we may compute a slightly different + * intersection point. This might leave two edges with a small + * gap between them. This kind of error is especially obvious + * when using boundary extraction (GLU_TESS_BOUNDARY_ONLY). + */ + vNext = (GLUvertex) tess.pq.pqExtractMin(); /* __gl_pqSortExtractMin*/ + SpliceMergeVertices(tess, v.anEdge, vNext.anEdge); + } + SweepEvent(tess, v); + } + + /* Set tess.event for debugging purposes */ + /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */ + tess.event = ((ActiveRegion) Dict.dictKey(Dict.dictMin(tess.dict))).eUp.Org; + DebugEvent(tess); + DoneEdgeDict(tess); + DonePriorityQ(tess); + + if (!RemoveDegenerateFaces(tess.mesh)) return false; + Mesh.__gl_meshCheckMesh(tess.mesh); + + return true; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessMono.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessMono.java new file mode 100644 index 000000000..10890e661 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessMono.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class TessMono { +/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region + * (what else would it do??) The region must consist of a single + * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this + * case means that any vertical line intersects the interior of the + * region in a single interval. + * + * Tessellation consists of adding interior edges (actually pairs of + * half-edges), to split the region into non-overlapping triangles. + * + * The basic idea is explained in Preparata and Shamos (which I don''t + * have handy right now), although their implementation is more + * complicated than this one. The are two edge chains, an upper chain + * and a lower chain. We process all vertices from both chains in order, + * from right to left. + * + * The algorithm ensures that the following invariant holds after each + * vertex is processed: the untessellated region consists of two + * chains, where one chain (say the upper) is a single edge, and + * the other chain is concave. The left vertex of the single edge + * is always to the left of all vertices in the concave chain. + * + * Each step consists of adding the rightmost unprocessed vertex to one + * of the two chains, and forming a fan of triangles from the rightmost + * of two chain endpoints. Determining whether we can add each triangle + * to the fan is a simple orientation test. By making the fan as large + * as possible, we restore the invariant (check it yourself). + */ + static boolean __gl_meshTessellateMonoRegion(GLUface face) { + GLUhalfEdge up, lo; + + /* All edges are oriented CCW around the boundary of the region. + * First, find the half-edge whose origin vertex is rightmost. + * Since the sweep goes from left to right, face->anEdge should + * be close to the edge we want. + */ + up = face.anEdge; + assert (up.Lnext != up && up.Lnext.Lnext != up); + + for (; Geom.VertLeq(up.Sym.Org, up.Org); up = up.Onext.Sym) + ; + for (; Geom.VertLeq(up.Org, up.Sym.Org); up = up.Lnext) + ; + lo = up.Onext.Sym; + + while (up.Lnext != lo) { + if (Geom.VertLeq(up.Sym.Org, lo.Org)) { + /* up.Sym.Org is on the left. It is safe to form triangles from lo.Org. + * The EdgeGoesLeft test guarantees progress even when some triangles + * are CW, given that the upper and lower chains are truly monotone. + */ + while (lo.Lnext != up && (Geom.EdgeGoesLeft(lo.Lnext) + || Geom.EdgeSign(lo.Org, lo.Sym.Org, lo.Lnext.Sym.Org) <= 0)) { + GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(lo.Lnext, lo); + if (tempHalfEdge == null) return false; + lo = tempHalfEdge.Sym; + } + lo = lo.Onext.Sym; + } else { + /* lo.Org is on the left. We can make CCW triangles from up.Sym.Org. */ + while (lo.Lnext != up && (Geom.EdgeGoesRight(up.Onext.Sym) + || Geom.EdgeSign(up.Sym.Org, up.Org, up.Onext.Sym.Org) >= 0)) { + GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(up, up.Onext.Sym); + if (tempHalfEdge == null) return false; + up = tempHalfEdge.Sym; + } + up = up.Lnext; + } + } + + /* Now lo.Org == up.Sym.Org == the leftmost vertex. The remaining region + * can be tessellated in a fan from this leftmost vertex. + */ + assert (lo.Lnext != up); + while (lo.Lnext.Lnext != up) { + GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(lo.Lnext, lo); + if (tempHalfEdge == null) return false; + lo = tempHalfEdge.Sym; + } + + return true; + } + + +/* __gl_meshTessellateInterior( mesh ) tessellates each region of + * the mesh which is marked "inside" the polygon. Each such region + * must be monotone. + */ + public static boolean __gl_meshTessellateInterior(GLUmesh mesh) { + GLUface f, next; + + /*LINTED*/ + for (f = mesh.fHead.next; f != mesh.fHead; f = next) { + /* Make sure we don''t try to tessellate the new triangles. */ + next = f.next; + if (f.inside) { + if (!__gl_meshTessellateMonoRegion(f)) return false; + } + } + + return true; + } + + +/* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces + * which are not marked "inside" the polygon. Since further mesh operations + * on NULL faces are not allowed, the main purpose is to clean up the + * mesh so that exterior loops are not represented in the data structure. + */ + public static void __gl_meshDiscardExterior(GLUmesh mesh) { + GLUface f, next; + + /*LINTED*/ + for (f = mesh.fHead.next; f != mesh.fHead; f = next) { + /* Since f will be destroyed, save its next pointer. */ + next = f.next; + if (!f.inside) { + Mesh.__gl_meshZapFace(f); + } + } + } + +// private static final int MARKED_FOR_DELETION = 0x7fffffff; + +/* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the + * winding numbers on all edges so that regions marked "inside" the + * polygon have a winding number of "value", and regions outside + * have a winding number of 0. + * + * If keepOnlyBoundary is TRUE, it also deletes all edges which do not + * separate an interior region from an exterior one. + */ + public static boolean __gl_meshSetWindingNumber(GLUmesh mesh, int value, boolean keepOnlyBoundary) { + GLUhalfEdge e, eNext; + + for (e = mesh.eHead.next; e != mesh.eHead; e = eNext) { + eNext = e.next; + if (e.Sym.Lface.inside != e.Lface.inside) { + + /* This is a boundary edge (one side is interior, one is exterior). */ + e.winding = (e.Lface.inside) ? value : -value; + } else { + + /* Both regions are interior, or both are exterior. */ + if (!keepOnlyBoundary) { + e.winding = 0; + } else { + if (!Mesh.__gl_meshDelete(e)) return false; + } + } + } + return true; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessState.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessState.java new file mode 100644 index 000000000..1c5c396e5 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/glu/tessellation/TessState.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package org.lwjgl.util.glu.tessellation; + +class TessState { + public static final int T_DORMANT = 0; + public static final int T_IN_POLYGON = 1; + public static final int T_IN_CONTOUR = 2; +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/input/ControllerAdapter.java.z b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/input/ControllerAdapter.java.z new file mode 100644 index 000000000..8c1226a6f --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/input/ControllerAdapter.java.z @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.input; + +import org.lwjgl.input.Controller; + +/** + * Adapter for the Controller interface. It can be used as placeholder + * Controller, which doesn't do anything (eg if Controllers.create() fails and + * you don't want to take care of that). + * + * @author Onyx, Aho and all the other aliases... + */ +public class ControllerAdapter implements Controller { + + /** + * Get the name assigned to this controller. + * + * @return The name assigned to this controller + */ + public String getName() { + return "Dummy Controller"; + } + + /** + * Get the index of this controller in the collection + * + * @return The index of this controller in the collection + */ + public int getIndex() { + return 0; //-1 maybe? + } + + /** + * Retrieve the number of buttons available on this controller + * + * @return The number of butotns available on this controller + */ + public int getButtonCount() { + return 0; + } + + /** + * Get the name of the specified button. Be warned, often this is as + * exciting as "Button X" + * + * @param index The index of the button whose name should be retrieved + * @return The name of the button requested + */ + public String getButtonName(int index) { + return "button n/a"; + } + + /** + * Check if a button is currently pressed + * + * @param index The button to check + * @return True if the button is currently pressed + */ + public boolean isButtonPressed(int index) { + return false; + } + + /** + * Poll the controller for new data. This will also update events + */ + public void poll() { + } + + /** + * Get the X-Axis value of the POV on this controller + * + * @return The X-Axis value of the POV on this controller + */ + public float getPovX() { + return 0f; + } + + /** + * Get the Y-Axis value of the POV on this controller + * + * @return The Y-Axis value of the POV on this controller + */ + public float getPovY() { + return 0f; + } + + /** + * Get the dead zone for a specified axis + * + * @param index The index of the axis for which to retrieve the dead zone + * @return The dead zone for the specified axis + */ + public float getDeadZone(int index) { + return 0f; + } + + /** + * Set the dead zone for the specified axis + * + * @param index The index of hte axis for which to set the dead zone + * @param zone The dead zone to use for the specified axis + */ + public void setDeadZone(int index, float zone) { + } + + /** + * Retrieve the number of axes available on this controller. + * + * @return The number of axes available on this controller. + */ + public int getAxisCount() { + return 0; + } + + /** + * Get the name that's given to the specified axis + * + * @param index The index of the axis whose name should be retrieved + * @return The name of the specified axis. + */ + public String getAxisName(int index) { + return "axis n/a"; + } + + /** + * Retrieve the value thats currently available on a specified axis. The + * value will always be between 1.0 and -1.0 and will calibrate as values + * are passed read. It may be useful to get the player to wiggle the + * joystick from side to side to get the calibration right. + * + * @param index The index of axis to be read + * @return The value from the specified axis. + */ + public float getAxisValue(int index) { + return 0f; + } + + /** + * Get the value from the X axis if there is one. If no X axis is defined a + * zero value will be returned. + * + * @return The value from the X axis + */ + public float getXAxisValue() { + return 0f; + } + + /** + * Get the dead zone for the X axis. + * + * @return The dead zone for the X axis + */ + public float getXAxisDeadZone() { + return 0f; + } + + /** + * Set the dead zone for the X axis + * + * @param zone The dead zone to use for the X axis + */ + public void setXAxisDeadZone(float zone) { + } + + /** + * Get the value from the Y axis if there is one. If no Y axis is defined a + * zero value will be returned. + * + * @return The value from the Y axis + */ + public float getYAxisValue() { + return 0f; + } + + /** + * Get the dead zone for the Y axis. + * + * @return The dead zone for the Y axis + */ + public float getYAxisDeadZone() { + return 0f; + } + + /** + * Set the dead zone for the Y axis + * + * @param zone The dead zone to use for the Y axis + */ + public void setYAxisDeadZone(float zone) { + } + + /** + * Get the value from the Z axis if there is one. If no Z axis is defined a + * zero value will be returned. + * + * @return The value from the Z axis + */ + public float getZAxisValue() { + return 0f; + } + + /** + * Get the dead zone for the Z axis. + * + * @return The dead zone for the Z axis + */ + public float getZAxisDeadZone() { + return 0f; + } + + /** + * Set the dead zone for the Z axis + * + * @param zone The dead zone to use for the Z axis + */ + public void setZAxisDeadZone(float zone) { + } + + /** + * Get the value from the RX axis if there is one. If no RX axis is defined + * a zero value will be returned. + * + * @return The value from the RX axis + */ + public float getRXAxisValue() { + return 0f; + } + + /** + * Get the dead zone for the RX axis. + * + * @return The dead zone for the RX axis + */ + public float getRXAxisDeadZone() { + return 0f; + } + + /** + * Set the dead zone for the RX axis + * + * @param zone The dead zone to use for the RX axis + */ + public void setRXAxisDeadZone(float zone) { + } + + /** + * Get the value from the RY axis if there is one. If no RY axis is defined + * a zero value will be returned. + * + * @return The value from the RY axis + */ + public float getRYAxisValue() { + return 0f; + } + + /** + * Get the dead zone for the RY axis. + * + * @return The dead zone for the RY axis + */ + public float getRYAxisDeadZone() { + return 0f; + } + + /** + * Set the dead zone for the RY axis + * + * @param zone The dead zone to use for the RY axis + */ + public void setRYAxisDeadZone(float zone) { + } + + /** + * Get the value from the RZ axis if there is one. If no RZ axis is defined + * a zero value will be returned. + * + * @return The value from the RZ axis + */ + public float getRZAxisValue() { + return 0f; + } + + /** + * Get the dead zone for the RZ axis. + * + * @return The dead zone for the RZ axis + */ + public float getRZAxisDeadZone() { + return 0f; + } + + /** + * Set the dead zone for the RZ axis + * + * @param zone The dead zone to use for the RZ axis + */ + public void setRZAxisDeadZone(float zone) { + } + + public int getRumblerCount() { + return 0; + } + + public String getRumblerName(int index) { + return "rumber n/a"; + } + + public void setRumblerStrength(int index, float strength) { + } +} \ No newline at end of file diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix.java new file mode 100644 index 000000000..545b1c98e --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Base class for matrices. When a matrix is constructed it will be the identity + * matrix unless otherwise stated. + * + * @author cix_foo + * @version $Revision: 3418 $ + * $Id: Matrix.java 3418 2010-09-28 21:11:35Z spasi $ + */ +public abstract class Matrix implements Serializable { + + /** + * Constructor for Matrix. + */ + protected Matrix() { + super(); + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public abstract Matrix setIdentity(); + + + /** + * Invert this matrix + * @return this + */ + public abstract Matrix invert(); + + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public abstract Matrix load(FloatBuffer buf); + + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (mathematical) order. + * + * @param buf A float buffer to read from + * @return this + */ + public abstract Matrix loadTranspose(FloatBuffer buf); + + + /** + * Negate this matrix + * @return this + */ + public abstract Matrix negate(); + + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + * @return this + */ + public abstract Matrix store(FloatBuffer buf); + + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + * @return this + */ + public abstract Matrix storeTranspose(FloatBuffer buf); + + + /** + * Transpose this matrix + * @return this + */ + public abstract Matrix transpose(); + + + /** + * Set this matrix to 0. + * @return this + */ + public abstract Matrix setZero(); + + + /** + * @return the determinant of the matrix + */ + public abstract float determinant(); + + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix2f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix2f.java new file mode 100644 index 000000000..6a3b7fef9 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix2f.java @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 2x2 matrix + * + * @author cix_foo + * @version $Revision: 3799 $ + * $Id: Matrix2f.java 3799 2012-09-12 11:29:40Z kappa1 $ + */ + +public class Matrix2f extends Matrix implements Serializable { + + private static final long serialVersionUID = 1L; + + public float m00, m01, m10, m11; + + /** + * Constructor for Matrix2f. The matrix is initialised to the identity. + */ + public Matrix2f() { + setIdentity(); + } + + /** + * Constructor + */ + public Matrix2f(Matrix2f src) { + load(src); + } + + /** + * Load from another matrix + * @param src The source matrix + * @return this + */ + public Matrix2f load(Matrix2f src) { + return load(src, this); + } + + /** + * Copy the source matrix to the destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new one should be created. + * @return The copied matrix + */ + public static Matrix2f load(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = src.m00; + dest.m01 = src.m01; + dest.m10 = src.m10; + dest.m11 = src.m11; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (mathematical) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m10); + buf.put(m11); + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m01); + buf.put(m11); + return this; + } + + + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f add(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f sub(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix2f mul(Matrix2f left, Matrix2f right, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + float m00 = left.m00 * right.m00 + left.m10 * right.m01; + float m01 = left.m01 * right.m00 + left.m11 * right.m01; + float m10 = left.m00 * right.m10 + left.m10 * right.m11; + float m11 = left.m01 * right.m10 + left.m11 * right.m11; + + dest.m00 = m00; + dest.m01 = m01; + dest.m10 = m10; + dest.m11 = m11; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector2f transform(Matrix2f left, Vector2f right, Vector2f dest) { + if (dest == null) + dest = new Vector2f(); + + float x = left.m00 * right.x + left.m10 * right.y; + float y = left.m01 * right.x + left.m11 * right.y; + + dest.x = x; + dest.y = y; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this); + } + + /** + * Transpose this matrix and place the result in another matrix. + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix2f transpose(Matrix2f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result in the destination matrix. + * @param src The source matrix or null if a new matrix is to be created + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix2f transpose(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + float m01 = src.m10; + float m10 = src.m01; + + dest.m01 = m01; + dest.m10 = m10; + + return dest; + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and place the result in the destination matrix. + * @param src The source matrix to be inverted + * @param dest The destination matrix or null if a new matrix is to be created + * @return The inverted matrix, or null if source can't be reverted. + */ + public static Matrix2f invert(Matrix2f src, Matrix2f dest) { + /* + *inv(A) = 1/det(A) * adj(A); + */ + + float determinant = src.determinant(); + if (determinant != 0) { + if (dest == null) + dest = new Matrix2f(); + float determinant_inv = 1f/determinant; + float t00 = src.m11*determinant_inv; + float t01 = -src.m01*determinant_inv; + float t11 = src.m00*determinant_inv; + float t10 = -src.m10*determinant_inv; + + dest.m00 = t00; + dest.m01 = t01; + dest.m10 = t10; + dest.m11 = t11; + return dest; + } else + return null; + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append('\n'); + return buf.toString(); + } + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and stash the result in another matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix2f negate(Matrix2f dest) { + return negate(this, dest); + } + + /** + * Negate the source matrix and stash the result in the destination matrix. + * @param src The source matrix to be negated + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public static Matrix2f negate(Matrix2f src, Matrix2f dest) { + if (dest == null) + dest = new Matrix2f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m01; + dest.m10 = -src.m10; + dest.m11 = -src.m11; + + return dest; + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the source matrix to be the identity matrix. + * @param src The matrix to set to the identity. + * @return The source matrix + */ + public static Matrix2f setIdentity(Matrix2f src) { + src.m00 = 1.0f; + src.m01 = 0.0f; + src.m10 = 0.0f; + src.m11 = 1.0f; + return src; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + public static Matrix2f setZero(Matrix2f src) { + src.m00 = 0.0f; + src.m01 = 0.0f; + src.m10 = 0.0f; + src.m11 = 0.0f; + return src; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Matrix#determinant() + */ + public float determinant() { + return m00 * m11 - m01*m10; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix3f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix3f.java new file mode 100644 index 000000000..13cf0fbc8 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix3f.java @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 3x3 matrix. + * + * @author cix_foo + * @version $Revision: 3799 $ + * $Id: Matrix3f.java 3799 2012-09-12 11:29:40Z kappa1 $ + */ + +public class Matrix3f extends Matrix implements Serializable { + + private static final long serialVersionUID = 1L; + + public float m00, + m01, + m02, + m10, + m11, + m12, + m20, + m21, + m22; + + /** + * Constructor for Matrix3f. Matrix is initialised to the identity. + */ + public Matrix3f() { + super(); + setIdentity(); + } + + /** + * Load from another matrix + * @param src The source matrix + * @return this + */ + public Matrix3f load(Matrix3f src) { + return load(src, this); + } + + /** + * Copy source matrix to destination matrix + * @param src The source matrix + * @param dest The destination matrix, or null of a new matrix is to be created + * @return The copied matrix + */ + public static Matrix3f load(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = src.m00; + dest.m10 = src.m10; + dest.m20 = src.m20; + dest.m01 = src.m01; + dest.m11 = src.m11; + dest.m21 = src.m21; + dest.m02 = src.m02; + dest.m12 = src.m12; + dest.m22 = src.m22; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m02 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + m12 = buf.get(); + m20 = buf.get(); + m21 = buf.get(); + m22 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (maths) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m20 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + m21 = buf.get(); + m02 = buf.get(); + m12 = buf.get(); + m22 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m20); + buf.put(m21); + buf.put(m22); + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m20); + buf.put(m01); + buf.put(m11); + buf.put(m21); + buf.put(m02); + buf.put(m12); + buf.put(m22); + return this; + } + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f add(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m02 = left.m02 + right.m02; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + dest.m12 = left.m12 + right.m12; + dest.m20 = left.m20 + right.m20; + dest.m21 = left.m21 + right.m21; + dest.m22 = left.m22 + right.m22; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f sub(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m02 = left.m02 - right.m02; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + dest.m12 = left.m12 - right.m12; + dest.m20 = left.m20 - right.m20; + dest.m21 = left.m21 - right.m21; + dest.m22 = left.m22 - right.m22; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix3f mul(Matrix3f left, Matrix3f right, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + float m00 = + left.m00 * right.m00 + left.m10 * right.m01 + left.m20 * right.m02; + float m01 = + left.m01 * right.m00 + left.m11 * right.m01 + left.m21 * right.m02; + float m02 = + left.m02 * right.m00 + left.m12 * right.m01 + left.m22 * right.m02; + float m10 = + left.m00 * right.m10 + left.m10 * right.m11 + left.m20 * right.m12; + float m11 = + left.m01 * right.m10 + left.m11 * right.m11 + left.m21 * right.m12; + float m12 = + left.m02 * right.m10 + left.m12 * right.m11 + left.m22 * right.m12; + float m20 = + left.m00 * right.m20 + left.m10 * right.m21 + left.m20 * right.m22; + float m21 = + left.m01 * right.m20 + left.m11 * right.m21 + left.m21 * right.m22; + float m22 = + left.m02 * right.m20 + left.m12 * right.m21 + left.m22 * right.m22; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector3f transform(Matrix3f left, Vector3f right, Vector3f dest) { + if (dest == null) + dest = new Vector3f(); + + float x = left.m00 * right.x + left.m10 * right.y + left.m20 * right.z; + float y = left.m01 * right.x + left.m11 * right.y + left.m21 * right.z; + float z = left.m02 * right.x + left.m12 * right.y + left.m22 * right.z; + + dest.x = x; + dest.y = y; + dest.z = z; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this, this); + } + + /** + * Transpose this matrix and place the result in another matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix3f transpose(Matrix3f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result into the destination matrix + * @param src The source matrix to be transposed + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix3f transpose(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + float m00 = src.m00; + float m01 = src.m10; + float m02 = src.m20; + float m10 = src.m01; + float m11 = src.m11; + float m12 = src.m21; + float m20 = src.m02; + float m21 = src.m12; + float m22 = src.m22; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + return dest; + } + + /** + * @return the determinant of the matrix + */ + public float determinant() { + float f = + m00 * (m11 * m22 - m12 * m21) + + m01 * (m12 * m20 - m10 * m22) + + m02 * (m10 * m21 - m11 * m20); + return f; + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append(m20).append(' ').append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append(m21).append(' ').append('\n'); + buf.append(m02).append(' ').append(m12).append(' ').append(m22).append(' ').append('\n'); + return buf.toString(); + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and put the result into the destination matrix + * @param src The source matrix to be inverted + * @param dest The destination matrix, or null if a new one is to be created + * @return The inverted matrix if successful, null otherwise + */ + public static Matrix3f invert(Matrix3f src, Matrix3f dest) { + float determinant = src.determinant(); + + if (determinant != 0) { + if (dest == null) + dest = new Matrix3f(); + /* do it the ordinary way + * + * inv(A) = 1/det(A) * adj(T), where adj(T) = transpose(Conjugate Matrix) + * + * m00 m01 m02 + * m10 m11 m12 + * m20 m21 m22 + */ + float determinant_inv = 1f/determinant; + + // get the conjugate matrix + float t00 = src.m11 * src.m22 - src.m12* src.m21; + float t01 = - src.m10 * src.m22 + src.m12 * src.m20; + float t02 = src.m10 * src.m21 - src.m11 * src.m20; + float t10 = - src.m01 * src.m22 + src.m02 * src.m21; + float t11 = src.m00 * src.m22 - src.m02 * src.m20; + float t12 = - src.m00 * src.m21 + src.m01 * src.m20; + float t20 = src.m01 * src.m12 - src.m02 * src.m11; + float t21 = -src.m00 * src.m12 + src.m02 * src.m10; + float t22 = src.m00 * src.m11 - src.m01 * src.m10; + + dest.m00 = t00*determinant_inv; + dest.m11 = t11*determinant_inv; + dest.m22 = t22*determinant_inv; + dest.m01 = t10*determinant_inv; + dest.m10 = t01*determinant_inv; + dest.m20 = t02*determinant_inv; + dest.m02 = t20*determinant_inv; + dest.m12 = t21*determinant_inv; + dest.m21 = t12*determinant_inv; + return dest; + } else + return null; + } + + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix3f negate(Matrix3f dest) { + return negate(this, dest); + } + + /** + * Negate the source matrix and place the result in the destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public static Matrix3f negate(Matrix3f src, Matrix3f dest) { + if (dest == null) + dest = new Matrix3f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m02; + dest.m02 = -src.m01; + dest.m10 = -src.m10; + dest.m11 = -src.m12; + dest.m12 = -src.m11; + dest.m20 = -src.m20; + dest.m21 = -src.m22; + dest.m22 = -src.m21; + return dest; + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the matrix to be the identity matrix. + * @param m The matrix to be set to the identity + * @return m + */ + public static Matrix3f setIdentity(Matrix3f m) { + m.m00 = 1.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m10 = 0.0f; + m.m11 = 1.0f; + m.m12 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 1.0f; + return m; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + /** + * Set the matrix matrix to 0. + * @param m The matrix to be set to 0 + * @return m + */ + public static Matrix3f setZero(Matrix3f m) { + m.m00 = 0.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m10 = 0.0f; + m.m11 = 0.0f; + m.m12 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 0.0f; + return m; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix4f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix4f.java new file mode 100644 index 000000000..b24dca626 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Matrix4f.java @@ -0,0 +1,849 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * Holds a 4x4 float matrix. + * + * @author foo + */ +public class Matrix4f extends Matrix implements Serializable { + private static final long serialVersionUID = 1L; + + public float m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33; + + /** + * Construct a new matrix, initialized to the identity. + */ + public Matrix4f() { + super(); + setIdentity(); + } + + public Matrix4f(final Matrix4f src) { + super(); + load(src); + } + + /** + * Returns a string representation of this matrix + */ + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(m00).append(' ').append(m10).append(' ').append(m20).append(' ').append(m30).append('\n'); + buf.append(m01).append(' ').append(m11).append(' ').append(m21).append(' ').append(m31).append('\n'); + buf.append(m02).append(' ').append(m12).append(' ').append(m22).append(' ').append(m32).append('\n'); + buf.append(m03).append(' ').append(m13).append(' ').append(m23).append(' ').append(m33).append('\n'); + return buf.toString(); + } + + /** + * Set this matrix to be the identity matrix. + * @return this + */ + public Matrix setIdentity() { + return setIdentity(this); + } + + /** + * Set the given matrix to be the identity matrix. + * @param m The matrix to set to the identity + * @return m + */ + public static Matrix4f setIdentity(Matrix4f m) { + m.m00 = 1.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m03 = 0.0f; + m.m10 = 0.0f; + m.m11 = 1.0f; + m.m12 = 0.0f; + m.m13 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 1.0f; + m.m23 = 0.0f; + m.m30 = 0.0f; + m.m31 = 0.0f; + m.m32 = 0.0f; + m.m33 = 1.0f; + + return m; + } + + /** + * Set this matrix to 0. + * @return this + */ + public Matrix setZero() { + return setZero(this); + } + + /** + * Set the given matrix to 0. + * @param m The matrix to set to 0 + * @return m + */ + public static Matrix4f setZero(Matrix4f m) { + m.m00 = 0.0f; + m.m01 = 0.0f; + m.m02 = 0.0f; + m.m03 = 0.0f; + m.m10 = 0.0f; + m.m11 = 0.0f; + m.m12 = 0.0f; + m.m13 = 0.0f; + m.m20 = 0.0f; + m.m21 = 0.0f; + m.m22 = 0.0f; + m.m23 = 0.0f; + m.m30 = 0.0f; + m.m31 = 0.0f; + m.m32 = 0.0f; + m.m33 = 0.0f; + + return m; + } + + /** + * Load from another matrix4f + * @param src The source matrix + * @return this + */ + public Matrix4f load(Matrix4f src) { + return load(src, this); + } + + /** + * Copy the source matrix to the destination matrix + * @param src The source matrix + * @param dest The destination matrix, or null of a new one is to be created + * @return The copied matrix + */ + public static Matrix4f load(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + dest.m00 = src.m00; + dest.m01 = src.m01; + dest.m02 = src.m02; + dest.m03 = src.m03; + dest.m10 = src.m10; + dest.m11 = src.m11; + dest.m12 = src.m12; + dest.m13 = src.m13; + dest.m20 = src.m20; + dest.m21 = src.m21; + dest.m22 = src.m22; + dest.m23 = src.m23; + dest.m30 = src.m30; + dest.m31 = src.m31; + dest.m32 = src.m32; + dest.m33 = src.m33; + + return dest; + } + + /** + * Load from a float buffer. The buffer stores the matrix in column major + * (OpenGL) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix load(FloatBuffer buf) { + + m00 = buf.get(); + m01 = buf.get(); + m02 = buf.get(); + m03 = buf.get(); + m10 = buf.get(); + m11 = buf.get(); + m12 = buf.get(); + m13 = buf.get(); + m20 = buf.get(); + m21 = buf.get(); + m22 = buf.get(); + m23 = buf.get(); + m30 = buf.get(); + m31 = buf.get(); + m32 = buf.get(); + m33 = buf.get(); + + return this; + } + + /** + * Load from a float buffer. The buffer stores the matrix in row major + * (maths) order. + * + * @param buf A float buffer to read from + * @return this + */ + public Matrix loadTranspose(FloatBuffer buf) { + + m00 = buf.get(); + m10 = buf.get(); + m20 = buf.get(); + m30 = buf.get(); + m01 = buf.get(); + m11 = buf.get(); + m21 = buf.get(); + m31 = buf.get(); + m02 = buf.get(); + m12 = buf.get(); + m22 = buf.get(); + m32 = buf.get(); + m03 = buf.get(); + m13 = buf.get(); + m23 = buf.get(); + m33 = buf.get(); + + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m03); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m13); + buf.put(m20); + buf.put(m21); + buf.put(m22); + buf.put(m23); + buf.put(m30); + buf.put(m31); + buf.put(m32); + buf.put(m33); + return this; + } + + /** + * Store this matrix in a float buffer. The matrix is stored in row + * major (maths) order. + * @param buf The buffer to store this matrix in + */ + public Matrix storeTranspose(FloatBuffer buf) { + buf.put(m00); + buf.put(m10); + buf.put(m20); + buf.put(m30); + buf.put(m01); + buf.put(m11); + buf.put(m21); + buf.put(m31); + buf.put(m02); + buf.put(m12); + buf.put(m22); + buf.put(m32); + buf.put(m03); + buf.put(m13); + buf.put(m23); + buf.put(m33); + return this; + } + + /** + * Store the rotation portion of this matrix in a float buffer. The matrix is stored in column + * major (openGL) order. + * @param buf The buffer to store this matrix in + */ + public Matrix store3f(FloatBuffer buf) { + buf.put(m00); + buf.put(m01); + buf.put(m02); + buf.put(m10); + buf.put(m11); + buf.put(m12); + buf.put(m20); + buf.put(m21); + buf.put(m22); + return this; + } + + /** + * Add two matrices together and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f add(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = left.m00 + right.m00; + dest.m01 = left.m01 + right.m01; + dest.m02 = left.m02 + right.m02; + dest.m03 = left.m03 + right.m03; + dest.m10 = left.m10 + right.m10; + dest.m11 = left.m11 + right.m11; + dest.m12 = left.m12 + right.m12; + dest.m13 = left.m13 + right.m13; + dest.m20 = left.m20 + right.m20; + dest.m21 = left.m21 + right.m21; + dest.m22 = left.m22 + right.m22; + dest.m23 = left.m23 + right.m23; + dest.m30 = left.m30 + right.m30; + dest.m31 = left.m31 + right.m31; + dest.m32 = left.m32 + right.m32; + dest.m33 = left.m33 + right.m33; + + return dest; + } + + /** + * Subtract the right matrix from the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f sub(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = left.m00 - right.m00; + dest.m01 = left.m01 - right.m01; + dest.m02 = left.m02 - right.m02; + dest.m03 = left.m03 - right.m03; + dest.m10 = left.m10 - right.m10; + dest.m11 = left.m11 - right.m11; + dest.m12 = left.m12 - right.m12; + dest.m13 = left.m13 - right.m13; + dest.m20 = left.m20 - right.m20; + dest.m21 = left.m21 - right.m21; + dest.m22 = left.m22 - right.m22; + dest.m23 = left.m23 - right.m23; + dest.m30 = left.m30 - right.m30; + dest.m31 = left.m31 - right.m31; + dest.m32 = left.m32 - right.m32; + dest.m33 = left.m33 - right.m33; + + return dest; + } + + /** + * Multiply the right matrix by the left and place the result in a third matrix. + * @param left The left source matrix + * @param right The right source matrix + * @param dest The destination matrix, or null if a new one is to be created + * @return the destination matrix + */ + public static Matrix4f mul(Matrix4f left, Matrix4f right, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + float m00 = left.m00 * right.m00 + left.m10 * right.m01 + left.m20 * right.m02 + left.m30 * right.m03; + float m01 = left.m01 * right.m00 + left.m11 * right.m01 + left.m21 * right.m02 + left.m31 * right.m03; + float m02 = left.m02 * right.m00 + left.m12 * right.m01 + left.m22 * right.m02 + left.m32 * right.m03; + float m03 = left.m03 * right.m00 + left.m13 * right.m01 + left.m23 * right.m02 + left.m33 * right.m03; + float m10 = left.m00 * right.m10 + left.m10 * right.m11 + left.m20 * right.m12 + left.m30 * right.m13; + float m11 = left.m01 * right.m10 + left.m11 * right.m11 + left.m21 * right.m12 + left.m31 * right.m13; + float m12 = left.m02 * right.m10 + left.m12 * right.m11 + left.m22 * right.m12 + left.m32 * right.m13; + float m13 = left.m03 * right.m10 + left.m13 * right.m11 + left.m23 * right.m12 + left.m33 * right.m13; + float m20 = left.m00 * right.m20 + left.m10 * right.m21 + left.m20 * right.m22 + left.m30 * right.m23; + float m21 = left.m01 * right.m20 + left.m11 * right.m21 + left.m21 * right.m22 + left.m31 * right.m23; + float m22 = left.m02 * right.m20 + left.m12 * right.m21 + left.m22 * right.m22 + left.m32 * right.m23; + float m23 = left.m03 * right.m20 + left.m13 * right.m21 + left.m23 * right.m22 + left.m33 * right.m23; + float m30 = left.m00 * right.m30 + left.m10 * right.m31 + left.m20 * right.m32 + left.m30 * right.m33; + float m31 = left.m01 * right.m30 + left.m11 * right.m31 + left.m21 * right.m32 + left.m31 * right.m33; + float m32 = left.m02 * right.m30 + left.m12 * right.m31 + left.m22 * right.m32 + left.m32 * right.m33; + float m33 = left.m03 * right.m30 + left.m13 * right.m31 + left.m23 * right.m32 + left.m33 * right.m33; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m03 = m03; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m13 = m13; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + dest.m23 = m23; + dest.m30 = m30; + dest.m31 = m31; + dest.m32 = m32; + dest.m33 = m33; + + return dest; + } + + /** + * Transform a Vector by a matrix and return the result in a destination + * vector. + * @param left The left matrix + * @param right The right vector + * @param dest The destination vector, or null if a new one is to be created + * @return the destination vector + */ + public static Vector4f transform(Matrix4f left, Vector4f right, Vector4f dest) { + if (dest == null) + dest = new Vector4f(); + + float x = left.m00 * right.x + left.m10 * right.y + left.m20 * right.z + left.m30 * right.w; + float y = left.m01 * right.x + left.m11 * right.y + left.m21 * right.z + left.m31 * right.w; + float z = left.m02 * right.x + left.m12 * right.y + left.m22 * right.z + left.m32 * right.w; + float w = left.m03 * right.x + left.m13 * right.y + left.m23 * right.z + left.m33 * right.w; + + dest.x = x; + dest.y = y; + dest.z = z; + dest.w = w; + + return dest; + } + + /** + * Transpose this matrix + * @return this + */ + public Matrix transpose() { + return transpose(this); + } + + /** + * Translate this matrix + * @param vec The vector to translate by + * @return this + */ + public Matrix4f translate(Vector2f vec) { + return translate(vec, this); + } + + /** + * Translate this matrix + * @param vec The vector to translate by + * @return this + */ + public Matrix4f translate(Vector3f vec) { + return translate(vec, this); + } + + /** + * Scales this matrix + * @param vec The vector to scale by + * @return this + */ + public Matrix4f scale(Vector3f vec) { + return scale(vec, this, this); + } + + /** + * Scales the source matrix and put the result in the destination matrix + * @param vec The vector to scale by + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The scaled matrix + */ + public static Matrix4f scale(Vector3f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + dest.m00 = src.m00 * vec.x; + dest.m01 = src.m01 * vec.x; + dest.m02 = src.m02 * vec.x; + dest.m03 = src.m03 * vec.x; + dest.m10 = src.m10 * vec.y; + dest.m11 = src.m11 * vec.y; + dest.m12 = src.m12 * vec.y; + dest.m13 = src.m13 * vec.y; + dest.m20 = src.m20 * vec.z; + dest.m21 = src.m21 * vec.z; + dest.m22 = src.m22 * vec.z; + dest.m23 = src.m23 * vec.z; + return dest; + } + + /** + * Rotates the matrix around the given axis the specified angle + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @return this + */ + public Matrix4f rotate(float angle, Vector3f axis) { + return rotate(angle, axis, this); + } + + /** + * Rotates the matrix around the given axis the specified angle + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @param dest The matrix to put the result, or null if a new matrix is to be created + * @return The rotated matrix + */ + public Matrix4f rotate(float angle, Vector3f axis, Matrix4f dest) { + return rotate(angle, axis, this, dest); + } + + /** + * Rotates the source matrix around the given axis the specified angle and + * put the result in the destination matrix. + * @param angle the angle, in radians. + * @param axis The vector representing the rotation axis. Must be normalized. + * @param src The matrix to rotate + * @param dest The matrix to put the result, or null if a new matrix is to be created + * @return The rotated matrix + */ + public static Matrix4f rotate(float angle, Vector3f axis, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + float c = (float) Math.cos(angle); + float s = (float) Math.sin(angle); + float oneminusc = 1.0f - c; + float xy = axis.x*axis.y; + float yz = axis.y*axis.z; + float xz = axis.x*axis.z; + float xs = axis.x*s; + float ys = axis.y*s; + float zs = axis.z*s; + + float f00 = axis.x*axis.x*oneminusc+c; + float f01 = xy*oneminusc+zs; + float f02 = xz*oneminusc-ys; + // n[3] not used + float f10 = xy*oneminusc-zs; + float f11 = axis.y*axis.y*oneminusc+c; + float f12 = yz*oneminusc+xs; + // n[7] not used + float f20 = xz*oneminusc+ys; + float f21 = yz*oneminusc-xs; + float f22 = axis.z*axis.z*oneminusc+c; + + float t00 = src.m00 * f00 + src.m10 * f01 + src.m20 * f02; + float t01 = src.m01 * f00 + src.m11 * f01 + src.m21 * f02; + float t02 = src.m02 * f00 + src.m12 * f01 + src.m22 * f02; + float t03 = src.m03 * f00 + src.m13 * f01 + src.m23 * f02; + float t10 = src.m00 * f10 + src.m10 * f11 + src.m20 * f12; + float t11 = src.m01 * f10 + src.m11 * f11 + src.m21 * f12; + float t12 = src.m02 * f10 + src.m12 * f11 + src.m22 * f12; + float t13 = src.m03 * f10 + src.m13 * f11 + src.m23 * f12; + dest.m20 = src.m00 * f20 + src.m10 * f21 + src.m20 * f22; + dest.m21 = src.m01 * f20 + src.m11 * f21 + src.m21 * f22; + dest.m22 = src.m02 * f20 + src.m12 * f21 + src.m22 * f22; + dest.m23 = src.m03 * f20 + src.m13 * f21 + src.m23 * f22; + dest.m00 = t00; + dest.m01 = t01; + dest.m02 = t02; + dest.m03 = t03; + dest.m10 = t10; + dest.m11 = t11; + dest.m12 = t12; + dest.m13 = t13; + return dest; + } + + /** + * Translate this matrix and stash the result in another matrix + * @param vec The vector to translate by + * @param dest The destination matrix or null if a new matrix is to be created + * @return the translated matrix + */ + public Matrix4f translate(Vector3f vec, Matrix4f dest) { + return translate(vec, this, dest); + } + + /** + * Translate the source matrix and stash the result in the destination matrix + * @param vec The vector to translate by + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return The translated matrix + */ + public static Matrix4f translate(Vector3f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m30 += src.m00 * vec.x + src.m10 * vec.y + src.m20 * vec.z; + dest.m31 += src.m01 * vec.x + src.m11 * vec.y + src.m21 * vec.z; + dest.m32 += src.m02 * vec.x + src.m12 * vec.y + src.m22 * vec.z; + dest.m33 += src.m03 * vec.x + src.m13 * vec.y + src.m23 * vec.z; + + return dest; + } + + /** + * Translate this matrix and stash the result in another matrix + * @param vec The vector to translate by + * @param dest The destination matrix or null if a new matrix is to be created + * @return the translated matrix + */ + public Matrix4f translate(Vector2f vec, Matrix4f dest) { + return translate(vec, this, dest); + } + + /** + * Translate the source matrix and stash the result in the destination matrix + * @param vec The vector to translate by + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return The translated matrix + */ + public static Matrix4f translate(Vector2f vec, Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m30 += src.m00 * vec.x + src.m10 * vec.y; + dest.m31 += src.m01 * vec.x + src.m11 * vec.y; + dest.m32 += src.m02 * vec.x + src.m12 * vec.y; + dest.m33 += src.m03 * vec.x + src.m13 * vec.y; + + return dest; + } + + /** + * Transpose this matrix and place the result in another matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public Matrix4f transpose(Matrix4f dest) { + return transpose(this, dest); + } + + /** + * Transpose the source matrix and place the result in the destination matrix + * @param src The source matrix + * @param dest The destination matrix or null if a new matrix is to be created + * @return the transposed matrix + */ + public static Matrix4f transpose(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + float m00 = src.m00; + float m01 = src.m10; + float m02 = src.m20; + float m03 = src.m30; + float m10 = src.m01; + float m11 = src.m11; + float m12 = src.m21; + float m13 = src.m31; + float m20 = src.m02; + float m21 = src.m12; + float m22 = src.m22; + float m23 = src.m32; + float m30 = src.m03; + float m31 = src.m13; + float m32 = src.m23; + float m33 = src.m33; + + dest.m00 = m00; + dest.m01 = m01; + dest.m02 = m02; + dest.m03 = m03; + dest.m10 = m10; + dest.m11 = m11; + dest.m12 = m12; + dest.m13 = m13; + dest.m20 = m20; + dest.m21 = m21; + dest.m22 = m22; + dest.m23 = m23; + dest.m30 = m30; + dest.m31 = m31; + dest.m32 = m32; + dest.m33 = m33; + + return dest; + } + + /** + * @return the determinant of the matrix + */ + public float determinant() { + float f = + m00 + * ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32) + - m13 * m22 * m31 + - m11 * m23 * m32 + - m12 * m21 * m33); + f -= m01 + * ((m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32) + - m13 * m22 * m30 + - m10 * m23 * m32 + - m12 * m20 * m33); + f += m02 + * ((m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31) + - m13 * m21 * m30 + - m10 * m23 * m31 + - m11 * m20 * m33); + f -= m03 + * ((m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31) + - m12 * m21 * m30 + - m10 * m22 * m31 + - m11 * m20 * m32); + return f; + } + + /** + * Calculate the determinant of a 3x3 matrix + * @return result + */ + + private static float determinant3x3(float t00, float t01, float t02, + float t10, float t11, float t12, + float t20, float t21, float t22) + { + return t00 * (t11 * t22 - t12 * t21) + + t01 * (t12 * t20 - t10 * t22) + + t02 * (t10 * t21 - t11 * t20); + } + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public Matrix invert() { + return invert(this, this); + } + + /** + * Invert the source matrix and put the result in the destination + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The inverted matrix if successful, null otherwise + */ + public static Matrix4f invert(Matrix4f src, Matrix4f dest) { + float determinant = src.determinant(); + + if (determinant != 0) { + /* + * m00 m01 m02 m03 + * m10 m11 m12 m13 + * m20 m21 m22 m23 + * m30 m31 m32 m33 + */ + if (dest == null) + dest = new Matrix4f(); + float determinant_inv = 1f/determinant; + + // first row + float t00 = determinant3x3(src.m11, src.m12, src.m13, src.m21, src.m22, src.m23, src.m31, src.m32, src.m33); + float t01 = -determinant3x3(src.m10, src.m12, src.m13, src.m20, src.m22, src.m23, src.m30, src.m32, src.m33); + float t02 = determinant3x3(src.m10, src.m11, src.m13, src.m20, src.m21, src.m23, src.m30, src.m31, src.m33); + float t03 = -determinant3x3(src.m10, src.m11, src.m12, src.m20, src.m21, src.m22, src.m30, src.m31, src.m32); + // second row + float t10 = -determinant3x3(src.m01, src.m02, src.m03, src.m21, src.m22, src.m23, src.m31, src.m32, src.m33); + float t11 = determinant3x3(src.m00, src.m02, src.m03, src.m20, src.m22, src.m23, src.m30, src.m32, src.m33); + float t12 = -determinant3x3(src.m00, src.m01, src.m03, src.m20, src.m21, src.m23, src.m30, src.m31, src.m33); + float t13 = determinant3x3(src.m00, src.m01, src.m02, src.m20, src.m21, src.m22, src.m30, src.m31, src.m32); + // third row + float t20 = determinant3x3(src.m01, src.m02, src.m03, src.m11, src.m12, src.m13, src.m31, src.m32, src.m33); + float t21 = -determinant3x3(src.m00, src.m02, src.m03, src.m10, src.m12, src.m13, src.m30, src.m32, src.m33); + float t22 = determinant3x3(src.m00, src.m01, src.m03, src.m10, src.m11, src.m13, src.m30, src.m31, src.m33); + float t23 = -determinant3x3(src.m00, src.m01, src.m02, src.m10, src.m11, src.m12, src.m30, src.m31, src.m32); + // fourth row + float t30 = -determinant3x3(src.m01, src.m02, src.m03, src.m11, src.m12, src.m13, src.m21, src.m22, src.m23); + float t31 = determinant3x3(src.m00, src.m02, src.m03, src.m10, src.m12, src.m13, src.m20, src.m22, src.m23); + float t32 = -determinant3x3(src.m00, src.m01, src.m03, src.m10, src.m11, src.m13, src.m20, src.m21, src.m23); + float t33 = determinant3x3(src.m00, src.m01, src.m02, src.m10, src.m11, src.m12, src.m20, src.m21, src.m22); + + // transpose and divide by the determinant + dest.m00 = t00*determinant_inv; + dest.m11 = t11*determinant_inv; + dest.m22 = t22*determinant_inv; + dest.m33 = t33*determinant_inv; + dest.m01 = t10*determinant_inv; + dest.m10 = t01*determinant_inv; + dest.m20 = t02*determinant_inv; + dest.m02 = t20*determinant_inv; + dest.m12 = t21*determinant_inv; + dest.m21 = t12*determinant_inv; + dest.m03 = t30*determinant_inv; + dest.m30 = t03*determinant_inv; + dest.m13 = t31*determinant_inv; + dest.m31 = t13*determinant_inv; + dest.m32 = t23*determinant_inv; + dest.m23 = t32*determinant_inv; + return dest; + } else + return null; + } + + /** + * Negate this matrix + * @return this + */ + public Matrix negate() { + return negate(this); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param dest The destination matrix, or null if a new matrix is to be created + * @return the negated matrix + */ + public Matrix4f negate(Matrix4f dest) { + return negate(this, dest); + } + + /** + * Negate this matrix and place the result in a destination matrix. + * @param src The source matrix + * @param dest The destination matrix, or null if a new matrix is to be created + * @return The negated matrix + */ + public static Matrix4f negate(Matrix4f src, Matrix4f dest) { + if (dest == null) + dest = new Matrix4f(); + + dest.m00 = -src.m00; + dest.m01 = -src.m01; + dest.m02 = -src.m02; + dest.m03 = -src.m03; + dest.m10 = -src.m10; + dest.m11 = -src.m11; + dest.m12 = -src.m12; + dest.m13 = -src.m13; + dest.m20 = -src.m20; + dest.m21 = -src.m21; + dest.m22 = -src.m22; + dest.m23 = -src.m23; + dest.m30 = -src.m30; + dest.m31 = -src.m31; + dest.m32 = -src.m32; + dest.m33 = -src.m33; + + return dest; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Quaternion.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Quaternion.java new file mode 100644 index 000000000..f47cc0a03 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Quaternion.java @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +/** + * + * Quaternions for LWJGL! + * + * @author fbi + * @version $Revision: 3418 $ + * $Id: Quaternion.java 3418 2010-09-28 21:11:35Z spasi $ + */ + +import java.nio.FloatBuffer; + +public class Quaternion extends Vector implements ReadableVector4f { + private static final long serialVersionUID = 1L; + + public float x, y, z, w; + + /** + * C'tor. The quaternion will be initialized to the identity. + */ + public Quaternion() { + super(); + setIdentity(); + } + + /** + * C'tor + * + * @param src + */ + public Quaternion(ReadableVector4f src) { + set(src); + } + + /** + * C'tor + * + */ + public Quaternion(float x, float y, float z, float w) { + set(x, y, z, w); + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.util.vector.WritableVector4f#set(float, float, float, + * float) + */ + public void set(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** + * Load from another Vector4f + * + * @param src + * The source vector + * @return this + */ + public Quaternion set(ReadableVector4f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + w = src.getW(); + return this; + } + + /** + * Set this quaternion to the multiplication identity. + * @return this + */ + public Quaternion setIdentity() { + return setIdentity(this); + } + + /** + * Set the given quaternion to the multiplication identity. + * @param q The quaternion + * @return q + */ + public static Quaternion setIdentity(Quaternion q) { + q.x = 0; + q.y = 0; + q.z = 0; + q.w = 1; + return q; + } + + /** + * @return the length squared of the quaternion + */ + public float lengthSquared() { + return x * x + y * y + z * z + w * w; + } + + /** + * Normalise the source quaternion and place the result in another quaternion. + * + * @param src + * The source quaternion + * @param dest + * The destination quaternion, or null if a new quaternion is to be + * created + * @return The normalised quaternion + */ + public static Quaternion normalise(Quaternion src, Quaternion dest) { + float inv_l = 1f/src.length(); + + if (dest == null) + dest = new Quaternion(); + + dest.set(src.x * inv_l, src.y * inv_l, src.z * inv_l, src.w * inv_l); + + return dest; + } + + /** + * Normalise this quaternion and place the result in another quaternion. + * + * @param dest + * The destination quaternion, or null if a new quaternion is to be + * created + * @return the normalised quaternion + */ + public Quaternion normalise(Quaternion dest) { + return normalise(this, dest); + } + + /** + * The dot product of two quaternions + * + * @param left + * The LHS quat + * @param right + * The RHS quat + * @return left dot right + */ + public static float dot(Quaternion left, Quaternion right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w + * right.w; + } + + /** + * Calculate the conjugate of this quaternion and put it into the given one + * + * @param dest + * The quaternion which should be set to the conjugate of this + * quaternion + */ + public Quaternion negate(Quaternion dest) { + return negate(this, dest); + } + + /** + * Calculate the conjugate of this quaternion and put it into the given one + * + * @param src + * The source quaternion + * @param dest + * The quaternion which should be set to the conjugate of this + * quaternion + */ + public static Quaternion negate(Quaternion src, Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + + dest.x = -src.x; + dest.y = -src.y; + dest.z = -src.z; + dest.w = src.w; + + return dest; + } + + /** + * Calculate the conjugate of this quaternion + */ + public Vector negate() { + return negate(this, this); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.Vector#load(java.nio.FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + w = buf.get(); + return this; + } + + /* + * (non-Javadoc) + * + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + return scale(scale, this, this); + } + + /** + * Scale the source quaternion by scale and put the result in the destination + * @param scale The amount to scale by + * @param src The source quaternion + * @param dest The destination quaternion, or null if a new quaternion is to be created + * @return The scaled quaternion + */ + public static Quaternion scale(float scale, Quaternion src, Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + dest.x = src.x * scale; + dest.y = src.y * scale; + dest.z = src.z * scale; + dest.w = src.w * scale; + return dest; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.ReadableVector#store(java.nio.FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + buf.put(x); + buf.put(y); + buf.put(z); + buf.put(w); + + return this; + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + /* + * (Overrides) + * + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + /** + * Set W + * + * @param w + */ + public void setW(float w) { + this.w = w; + } + + /* + * (Overrides) + * + * @see org.lwjgl.vector.ReadableVector3f#getW() + */ + public float getW() { + return w; + } + + public String toString() { + return "Quaternion: " + x + " " + y + " " + z + " " + w; + } + + /** + * Sets the value of this quaternion to the quaternion product of + * quaternions left and right (this = left * right). Note that this is safe + * for aliasing (e.g. this can be left or right). + * + * @param left + * the first quaternion + * @param right + * the second quaternion + */ + public static Quaternion mul(Quaternion left, Quaternion right, + Quaternion dest) { + if (dest == null) + dest = new Quaternion(); + dest.set(left.x * right.w + left.w * right.x + left.y * right.z + - left.z * right.y, left.y * right.w + left.w * right.y + + left.z * right.x - left.x * right.z, left.z * right.w + + left.w * right.z + left.x * right.y - left.y * right.x, + left.w * right.w - left.x * right.x - left.y * right.y + - left.z * right.z); + return dest; + } + + /** + * + * Multiplies quaternion left by the inverse of quaternion right and places + * the value into this quaternion. The value of both argument quaternions is + * preservered (this = left * right^-1). + * + * @param left + * the left quaternion + * @param right + * the right quaternion + */ + public static Quaternion mulInverse(Quaternion left, Quaternion right, + Quaternion dest) { + float n = right.lengthSquared(); + // zero-div may occur. + n = (n == 0.0 ? n : 1 / n); + // store on stack once for aliasing-safty + if (dest == null) + dest = new Quaternion(); + dest + .set((left.x * right.w - left.w * right.x - left.y + * right.z + left.z * right.y) + * n, (left.y * right.w - left.w * right.y - left.z + * right.x + left.x * right.z) + * n, (left.z * right.w - left.w * right.z - left.x + * right.y + left.y * right.x) + * n, (left.w * right.w + left.x * right.x + left.y + * right.y + left.z * right.z) + * n); + + return dest; + } + + /** + * Sets the value of this quaternion to the equivalent rotation of the + * Axis-Angle argument. + * + * @param a1 + * the axis-angle: (x,y,z) is the axis and w is the angle + */ + public final void setFromAxisAngle(Vector4f a1) { + x = a1.x; + y = a1.y; + z = a1.z; + float n = (float) Math.sqrt(x * x + y * y + z * z); + // zero-div may occur. + float s = (float) (Math.sin(0.5 * a1.w) / n); + x *= s; + y *= s; + z *= s; + w = (float) Math.cos(0.5 * a1.w); + } + + /** + * Sets the value of this quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The matrix + * @return this + */ + public final Quaternion setFromMatrix(Matrix4f m) { + return setFromMatrix(m, this); + } + + /** + * Sets the value of the source quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + * @param q + * The destination quaternion, or null if a new quaternion is to be created + * @return q + */ + public static Quaternion setFromMatrix(Matrix4f m, Quaternion q) { + return q.setFromMat(m.m00, m.m01, m.m02, m.m10, m.m11, m.m12, m.m20, + m.m21, m.m22); + } + + /** + * Sets the value of this quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + */ + public final Quaternion setFromMatrix(Matrix3f m) { + return setFromMatrix(m, this); + } + + /** + * Sets the value of the source quaternion using the rotational component of the + * passed matrix. + * + * @param m + * The source matrix + * @param q + * The destination quaternion, or null if a new quaternion is to be created + * @return q + */ + public static Quaternion setFromMatrix(Matrix3f m, Quaternion q) { + return q.setFromMat(m.m00, m.m01, m.m02, m.m10, m.m11, m.m12, m.m20, + m.m21, m.m22); + } + + /** + * Private method to perform the matrix-to-quaternion conversion + */ + private Quaternion setFromMat(float m00, float m01, float m02, float m10, + float m11, float m12, float m20, float m21, float m22) { + + float s; + float tr = m00 + m11 + m22; + if (tr >= 0.0) { + s = (float) Math.sqrt(tr + 1.0); + w = s * 0.5f; + s = 0.5f / s; + x = (m21 - m12) * s; + y = (m02 - m20) * s; + z = (m10 - m01) * s; + } else { + float max = Math.max(Math.max(m00, m11), m22); + if (max == m00) { + s = (float) Math.sqrt(m00 - (m11 + m22) + 1.0); + x = s * 0.5f; + s = 0.5f / s; + y = (m01 + m10) * s; + z = (m20 + m02) * s; + w = (m21 - m12) * s; + } else if (max == m11) { + s = (float) Math.sqrt(m11 - (m22 + m00) + 1.0); + y = s * 0.5f; + s = 0.5f / s; + z = (m12 + m21) * s; + x = (m01 + m10) * s; + w = (m02 - m20) * s; + } else { + s = (float) Math.sqrt(m22 - (m00 + m11) + 1.0); + z = s * 0.5f; + s = 0.5f / s; + x = (m20 + m02) * s; + y = (m12 + m21) * s; + w = (m10 - m01) * s; + } + } + return this; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector.java new file mode 100644 index 000000000..0df4240ff --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.nio.FloatBuffer; + +/** + * @author foo + */ +public interface ReadableVector { + /** + * @return the length of the vector + */ + float length(); + /** + * @return the length squared of the vector + */ + float lengthSquared(); + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + Vector store(FloatBuffer buf); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector2f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector2f.java new file mode 100644 index 000000000..e6850574b --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector2f.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +/** + * @author foo + */ +public interface ReadableVector2f extends ReadableVector { + /** + * @return x + */ + float getX(); + /** + * @return y + */ + float getY(); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector3f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector3f.java new file mode 100644 index 000000000..240c6f482 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector3f.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +/** + * @author foo + */ +public interface ReadableVector3f extends ReadableVector2f { + /** + * @return z + */ + float getZ(); +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector4f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector4f.java new file mode 100644 index 000000000..5dee3e3ba --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/ReadableVector4f.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +/** + * @author foo + */ +public interface ReadableVector4f extends ReadableVector3f { + + /** + * @return w + */ + float getW(); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector.java new file mode 100644 index 000000000..a0b407aac --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Base class for vectors. + * + * @author cix_foo + * @version $Revision: 3418 $ + * $Id: Vector.java 3418 2010-09-28 21:11:35Z spasi $ + */ +public abstract class Vector implements Serializable, ReadableVector { + + /** + * Constructor for Vector. + */ + protected Vector() { + super(); + } + + /** + * @return the length of the vector + */ + public final float length() { + return (float) Math.sqrt(lengthSquared()); + } + + + /** + * @return the length squared of the vector + */ + public abstract float lengthSquared(); + + /** + * Load this vector from a FloatBuffer + * @param buf The buffer to load it from, at the current position + * @return this + */ + public abstract Vector load(FloatBuffer buf); + + /** + * Negate a vector + * @return this + */ + public abstract Vector negate(); + + + /** + * Normalise this vector + * @return this + */ + public final Vector normalise() { + float len = length(); + if (len != 0.0f) { + float l = 1.0f / len; + return scale(l); + } else + throw new IllegalStateException("Zero length vector"); + } + + + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + public abstract Vector store(FloatBuffer buf); + + + /** + * Scale this vector + * @param scale The scale factor + * @return this + */ + public abstract Vector scale(float scale); + + + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector2f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector2f.java new file mode 100644 index 000000000..d06422e2c --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector2f.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 2-tuple vector. + * + * @author cix_foo + * @version $Revision: 3418 $ + * $Id: Vector2f.java 3418 2010-09-28 21:11:35Z spasi $ + */ + +public class Vector2f extends Vector implements Serializable, ReadableVector2f, WritableVector2f { + + private static final long serialVersionUID = 1L; + + public float x, y; + + /** + * Constructor for Vector3f. + */ + public Vector2f() { + super(); + } + + /** + * Constructor + */ + public Vector2f(ReadableVector2f src) { + set(src); + } + + /** + * Constructor + */ + public Vector2f(float x, float y) { + set(x, y); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /** + * Load from another Vector2f + * @param src The source vector + * @return this + */ + public Vector2f set(ReadableVector2f src) { + x = src.getX(); + y = src.getY(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector2f translate(float x, float y) { + this.x += x; + this.y += y; + return this; + } + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector2f negate(Vector2f dest) { + if (dest == null) + dest = new Vector2f(); + dest.x = -x; + dest.y = -y; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector2f normalise(Vector2f dest) { + float l = length(); + + if (dest == null) + dest = new Vector2f(x / l, y / l); + else + dest.set(x / l, y / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector2f left, Vector2f right) { + return left.x * right.x + left.y * right.y; + } + + + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector2f a, Vector2f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector2f add(Vector2f left, Vector2f right, Vector2f dest) { + if (dest == null) + return new Vector2f(left.x + right.x, left.y + right.y); + else { + dest.set(left.x + right.x, left.y + right.y); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector2f sub(Vector2f left, Vector2f right, Vector2f dest) { + if (dest == null) + return new Vector2f(left.x - right.x, left.y - right.y); + else { + dest.set(left.x - right.x, left.y - right.y); + return dest; + } + } + + /** + * Store this vector in a FloatBuffer + * @param buf The buffer to store it in, at the current position + * @return this + */ + public Vector store(FloatBuffer buf) { + buf.put(x); + buf.put(y); + return this; + } + + /** + * Load this vector from a FloatBuffer + * @param buf The buffer to load it from, at the current position + * @return this + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + + x *= scale; + y *= scale; + + return this; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(64); + + sb.append("Vector2f["); + sb.append(x); + sb.append(", "); + sb.append(y); + sb.append(']'); + return sb.toString(); + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector3f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector3f.java new file mode 100644 index 000000000..9adab570a --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector3f.java @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 3-tuple vector. + * + * @author cix_foo + * @version $Revision: 3418 $ + * $Id: Vector3f.java 3418 2010-09-28 21:11:35Z spasi $ + */ + +public class Vector3f extends Vector implements Serializable, ReadableVector3f, WritableVector3f { + + private static final long serialVersionUID = 1L; + + public float x, y, z; + + /** + * Constructor for Vector3f. + */ + public Vector3f() { + super(); + } + + /** + * Constructor + */ + public Vector3f(ReadableVector3f src) { + set(src); + } + + /** + * Constructor + */ + public Vector3f(float x, float y, float z) { + set(x, y, z); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Load from another Vector3f + * @param src The source vector + * @return this + */ + public Vector3f set(ReadableVector3f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y + z * z; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector3f translate(float x, float y, float z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector3f add(Vector3f left, Vector3f right, Vector3f dest) { + if (dest == null) + return new Vector3f(left.x + right.x, left.y + right.y, left.z + right.z); + else { + dest.set(left.x + right.x, left.y + right.y, left.z + right.z); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector3f sub(Vector3f left, Vector3f right, Vector3f dest) { + if (dest == null) + return new Vector3f(left.x - right.x, left.y - right.y, left.z - right.z); + else { + dest.set(left.x - right.x, left.y - right.y, left.z - right.z); + return dest; + } + } + + /** + * The cross product of two vectors. + * + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination result, or null if a new vector is to be created + * @return left cross right + */ + public static Vector3f cross( + Vector3f left, + Vector3f right, + Vector3f dest) + { + + if (dest == null) + dest = new Vector3f(); + + dest.set( + left.y * right.z - left.z * right.y, + right.x * left.z - right.z * left.x, + left.x * right.y - left.y * right.x + ); + + return dest; + } + + + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + z = -z; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector3f negate(Vector3f dest) { + if (dest == null) + dest = new Vector3f(); + dest.x = -x; + dest.y = -y; + dest.z = -z; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector3f normalise(Vector3f dest) { + float l = length(); + + if (dest == null) + dest = new Vector3f(x / l, y / l, z / l); + else + dest.set(x / l, y / l, z / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector3f left, Vector3f right) { + return left.x * right.x + left.y * right.y + left.z * right.z; + } + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector3f a, Vector3f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#load(FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + + x *= scale; + y *= scale; + z *= scale; + + return this; + + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#store(FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + + buf.put(x); + buf.put(y); + buf.put(z); + + return this; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder sb = new StringBuilder(64); + + sb.append("Vector3f["); + sb.append(x); + sb.append(", "); + sb.append(y); + sb.append(", "); + sb.append(z); + sb.append(']'); + return sb.toString(); + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector4f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector4f.java new file mode 100644 index 000000000..712dc0a1b --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/Vector4f.java @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +import java.io.Serializable; +import java.nio.FloatBuffer; + +/** + * + * Holds a 4-tuple vector. + * + * @author cix_foo + * @version $Revision: 2983 $ + * $Id: Vector4f.java 2983 2008-04-07 18:36:09Z matzon $ + */ + +public class Vector4f extends Vector implements Serializable, ReadableVector4f, WritableVector4f { + + private static final long serialVersionUID = 1L; + + public float x, y, z, w; + + /** + * Constructor for Vector4f. + */ + public Vector4f() { + super(); + } + + /** + * Constructor + */ + public Vector4f(ReadableVector4f src) { + set(src); + } + + /** + * Constructor + */ + public Vector4f(float x, float y, float z, float w) { + set(x, y, z, w); + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector2f#set(float, float) + */ + public void set(float x, float y) { + this.x = x; + this.y = y; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector3f#set(float, float, float) + */ + public void set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /* (non-Javadoc) + * @see org.lwjgl.util.vector.WritableVector4f#set(float, float, float, float) + */ + public void set(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + /** + * Load from another Vector4f + * @param src The source vector + * @return this + */ + public Vector4f set(ReadableVector4f src) { + x = src.getX(); + y = src.getY(); + z = src.getZ(); + w = src.getW(); + return this; + } + + /** + * @return the length squared of the vector + */ + public float lengthSquared() { + return x * x + y * y + z * z + w * w; + } + + /** + * Translate a vector + * @param x The translation in x + * @param y the translation in y + * @return this + */ + public Vector4f translate(float x, float y, float z, float w) { + this.x += x; + this.y += y; + this.z += z; + this.w += w; + return this; + } + + /** + * Add a vector to another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return the sum of left and right in dest + */ + public static Vector4f add(Vector4f left, Vector4f right, Vector4f dest) { + if (dest == null) + return new Vector4f(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + else { + dest.set(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); + return dest; + } + } + + /** + * Subtract a vector from another vector and place the result in a destination + * vector. + * @param left The LHS vector + * @param right The RHS vector + * @param dest The destination vector, or null if a new vector is to be created + * @return left minus right in dest + */ + public static Vector4f sub(Vector4f left, Vector4f right, Vector4f dest) { + if (dest == null) + return new Vector4f(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + else { + dest.set(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); + return dest; + } + } + + + /** + * Negate a vector + * @return this + */ + public Vector negate() { + x = -x; + y = -y; + z = -z; + w = -w; + return this; + } + + /** + * Negate a vector and place the result in a destination vector. + * @param dest The destination vector or null if a new vector is to be created + * @return the negated vector + */ + public Vector4f negate(Vector4f dest) { + if (dest == null) + dest = new Vector4f(); + dest.x = -x; + dest.y = -y; + dest.z = -z; + dest.w = -w; + return dest; + } + + + /** + * Normalise this vector and place the result in another vector. + * @param dest The destination vector, or null if a new vector is to be created + * @return the normalised vector + */ + public Vector4f normalise(Vector4f dest) { + float l = length(); + + if (dest == null) + dest = new Vector4f(x / l, y / l, z / l, w / l); + else + dest.set(x / l, y / l, z / l, w / l); + + return dest; + } + + /** + * The dot product of two vectors is calculated as + * v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w + * @param left The LHS vector + * @param right The RHS vector + * @return left dot right + */ + public static float dot(Vector4f left, Vector4f right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + } + + /** + * Calculate the angle between two vectors, in radians + * @param a A vector + * @param b The other vector + * @return the angle between the two vectors, in radians + */ + public static float angle(Vector4f a, Vector4f b) { + float dls = dot(a, b) / (a.length() * b.length()); + if (dls < -1f) + dls = -1f; + else if (dls > 1.0f) + dls = 1.0f; + return (float)Math.acos(dls); + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#load(FloatBuffer) + */ + public Vector load(FloatBuffer buf) { + x = buf.get(); + y = buf.get(); + z = buf.get(); + w = buf.get(); + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#scale(float) + */ + public Vector scale(float scale) { + x *= scale; + y *= scale; + z *= scale; + w *= scale; + return this; + } + + /* (non-Javadoc) + * @see org.lwjgl.vector.Vector#store(FloatBuffer) + */ + public Vector store(FloatBuffer buf) { + + buf.put(x); + buf.put(y); + buf.put(z); + buf.put(w); + + return this; + } + + public String toString() { + return "Vector4f: " + x + " " + y + " " + z + " " + w; + } + + /** + * @return x + */ + public final float getX() { + return x; + } + + /** + * @return y + */ + public final float getY() { + return y; + } + + /** + * Set X + * @param x + */ + public final void setX(float x) { + this.x = x; + } + + /** + * Set Y + * @param y + */ + public final void setY(float y) { + this.y = y; + } + + /** + * Set Z + * @param z + */ + public void setZ(float z) { + this.z = z; + } + + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getZ() { + return z; + } + + /** + * Set W + * @param w + */ + public void setW(float w) { + this.w = w; + } + + /* (Overrides) + * @see org.lwjgl.vector.ReadableVector3f#getZ() + */ + public float getW() { + return w; + } + + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector2f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector2f.java new file mode 100644 index 000000000..9b48a42e0 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector2f.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +/** + * Writable interface to Vector2fs + * @author $author$ + * @version $revision$ + * $Id: WritableVector2f.java 3418 2010-09-28 21:11:35Z spasi $ + */ +public interface WritableVector2f { + + /** + * Set the X value + * @param x + */ + void setX(float x); + + /** + * Set the Y value + * @param y + */ + void setY(float y); + + /** + * Set the X,Y values + * @param x + * @param y + */ + void set(float x, float y); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector3f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector3f.java new file mode 100644 index 000000000..1f2cae15d --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector3f.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +/** + * Writable interface to Vector3fs + * @author $author$ + * @version $revision$ + * $Id: WritableVector3f.java 3418 2010-09-28 21:11:35Z spasi $ + */ +public interface WritableVector3f extends WritableVector2f { + + /** + * Set the Z value + * @param z + */ + void setZ(float z); + + /** + * Set the X,Y,Z values + * @param x + * @param y + * @param z + */ + void set(float x, float y, float z); + +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector4f.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector4f.java new file mode 100644 index 000000000..f398982bf --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/util/vector/WritableVector4f.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2008 LWJGL Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'LWJGL' nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.lwjgl.util.vector; + +/** + * Writable interface to Vector4fs + * @author $author$ + * @version $revision$ + * $Id: WritableVector4f.java 3418 2010-09-28 21:11:35Z spasi $ + */ +public interface WritableVector4f extends WritableVector3f { + + /** + * Set the W value + * @param w + */ + void setW(float w); + + /** + * Set the X,Y,Z,W values + * @param x + * @param y + * @param z + * @param w + */ + void set(float x, float y, float z, float w); + +} diff --git a/jre_securitymanager/src/main/java/net/pojavlauncher/security/PojavSecurityManager.java b/jre_securitymanager/src/main/java/net/pojavlauncher/security/PojavSecurityManager.java deleted file mode 100644 index f657e4dbf..000000000 --- a/jre_securitymanager/src/main/java/net/pojavlauncher/security/PojavSecurityManager.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.pojavlauncher.security; -import java.security.*; - -public class PojavSecurityManager extends SecurityManager -{ - @Override - public void checkPermission(Permission perm, Object obj) { - super.checkPermission(perm, obj); - } -} diff --git a/settings.gradle b/settings.gradle index fa903d3fb..1e810efdd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,4 @@ rootProject.name='PojavLauncher' -include ':jre_securitymanager' +include ':jre_lwjgl3glfw' include ':app_pojavlauncher'