Purpose: Unified graphics abstraction layer for LWJGL supporting OpenGL 1.X, 2.0, and 3.0+ with automatic capability detection and version-dependent rendering paths. Java 8 compatible.
- Multi-version OpenGL support: GL 1.X (fixed-function), GL 2.0 (shaders + extensions), GL 3.0+ (modern core)
- Unified capability detection: Automatically detects available hardware features with ARB/EXT/Core variant checking
- If any variant (ARB/EXT/Core) exists, unified base capability is registered
- Example:
FRAMEBUFFER_OBJECTSavailable if GL_ARB_framebuffer_object OR GL_EXT_framebuffer_object OR GL_FRAMEBUFFER_OBJECT_CORE exists
- Version-dependent GPU matrix application: PoseStack supports multiple rendering approaches
- Fixed-function via
glMultMatrix()/glLoadMatrix() - Shader uniforms via
glUniformMatrix4fv() - Manual GPU access for custom implementations
- Fixed-function via
- Shader binding management: Static tracking of currently bound shader for coordinated rendering
- Matrix abstractions: CPU-side pose/matrix stack for hierarchical transformations
- Framebuffer abstraction: Unified FBO handling across GL versions
- Auto-initialization: GraphicsContext initializes on first use, no manual setup required
CrystalGraphics/
├── build.gradle # Gradle build configuration
├── README.md # This file - Library overview
├── SHADER_GUIDE.md # Shader compilation and usage
└── src/main/java/io/github/somehussar/crystalgraphics/
├── api/
│ └── GraphicsCapability.java # Unified capability enumeration
├── context/
│ └── GraphicsContext.java # Singleton capability detection & context
├── math/
│ ├── Matrix4f.java # 4x4 transformations
│ ├── Matrix3f.java # 3x3 normal matrices
│ ├── PoseStack.java # Hierarchical transform stack with GPU application
│ └── ScissorStack.java # Nested scissor clipping
├── render/
│ ├── shader/
│ │ └── Shader.java # Shader compilation and GPU binding
│ ├── framebuffer/
│ │ └── Framebuffer.java # Multi-version FBO abstraction
│ └── target/
│ ├── StencilBuffer.java # Stencil buffer operations
│ └── MultiRenderTarget.java # Multi-render target support
└── util/
└── GraphicsExample.java # Comprehensive usage examples
// Get singleton context - initializes automatically on first call
GraphicsContext context = GraphicsContext.getInstance();
// Check capabilities
if (context.supports(GraphicsCapability.SHADERS)) {
// Use GL 2.0+ features
}
if (context.supportsAll(GraphicsCapability.FRAMEBUFFER_OBJECTS,
GraphicsCapability.SHADERS)) {
// Use advanced features
}PoseStack poseStack = new PoseStack();
poseStack.pushPose();
poseStack.translate(1.0f, 2.0f, 3.0f);
poseStack.rotateY(45.0f);
poseStack.scale(2.0f, 2.0f, 2.0f);
// Apply to GPU - auto-detects shader, uses appropriate method
poseStack.apply();
poseStack.popPose();Shader shader = new Shader(vertexSource, fragmentSource)
.requires(GraphicsCapability.SHADERS);
if (shader.compile(context)) {
shader.bind(); // Sets as active shader + static tracking
// Render with shader
Shader.unbind(); // Clears active shader
} else {
System.err.println("Shader failed: " + shader.getCompilationError());
}The library automatically maps GL feature variants to a single unified capability:
// These variants all map to FRAMEBUFFER_OBJECTS:
// - GL_ARB_framebuffer_object (GL 2.0+)
// - GL_EXT_framebuffer_object (GL 2.0+)
// - GL_FRAMEBUFFER_OBJECT_CORE (GL 3.0+)
if (context.supports(GraphicsCapability.FRAMEBUFFER_OBJECTS)) {
// Will be true if ANY variant is available
}PoseStack can apply transformations to GPU in multiple ways, depending on available capabilities:
poseStack.apply(); // Smart - auto-detects
poseStack.applyToFixedFunctionGL(); // GL11.glMultMatrix()
poseStack.applyToShaderUniform(programHandle, "uMat"); // GL20 uniform
poseStack.loadToFixedFunctionGL(GL11.GL_MODELVIEW); // GL11.glLoadMatrix()
poseStack.withFixedFunctionGL(renderRunnable); // Auto push/pop wrapperThe Shader class maintains static tracking of the currently bound shader for coordinated rendering:
shader.bind(); // Calls GL20.glUseProgram() + updates static field
Shader boundShader = Shader.getCurrentBoundShader(); // Query current
Shader.unbind(); // Clears active shaderThis allows PoseStack to automatically apply transformations to the correct shader.
| Version | Support | Core Features |
|---|---|---|
| GL 1.3-1.4 | Basic | Fixed-function pipeline |
| GL 1.5+ | Extended | VBO support added |
| GL 2.0-2.1 | Full | Shaders + ARB/EXT extensions |
| GL 3.0+ | Full | Core features + advanced shaders |
- Java 8+ (no lambdas, uses standard collections)
- LWJGL 2.9.4-nightly (compatible with Minecraft 1.7.10)
- No external dependencies beyond LWJGL
- SHADER_GUIDE.md - Detailed shader compilation and usage
Part of CrystalUI project