IMPORTANT NOTE: Done with claude AI.
A high-performance OpenGL 4.6 viewer designed for visualizing large CAD models. Built with modern C++17 and optimized for rendering complex geometry.
- Modern OpenGL 4.6 - Uses Direct State Access (DSA) for efficient GPU resource management
- OBJ Mesh Loading - Load multiple OBJ files simultaneously with automatic normal handling
- Texture Mapping - Diffuse textures via MTL files (PNG, JPG, TGA, BMP) with T key toggle
- Built-in Textures - Default grid, checker, UV test, brushed metal, wood, concrete patterns
- Object Picking - Click to select objects with visual highlight feedback
- Mesh Subdivision - Loop subdivision (smooth) and midpoint subdivision. Refines all edges by default; use
--anglefor crease preservation. Only subdivides visible objects when none selected. - Parallel Processing - OpenMP-accelerated subdivision for large meshes (4-5x speedup)
- Background Tessellation - Non-blocking subdivision with real-time progress indicators. UI stays responsive during computation.
- GPU Double-Buffering - Fence-synchronized buffer swapping for smooth geometry updates
- Back-face Culling - Toggleable culling for ~50% faster rendering on closed meshes
- Orbit Camera - Intuitive camera controls with mouse and arrow keys
- Blinn-Phong Lighting - Realistic shading with directional light
- Rim Lighting - Fresnel-based edge highlighting for better shape visibility
- Gradient Background - Professional dark blue gradient backdrop
- Wireframe Mode - Toggle wireframe rendering for mesh inspection
- Help Overlay - In-window keyboard shortcut reference with toggle indicators (H key)
- Progress Overlay - Shows subdivision/LOD progress with phase name, percentage, and queued task count
- Frustum Culling - Skip rendering objects outside camera view (G key)
- LOD System - Automatic Level of Detail with QEM-based mesh simplification
- 6 LOD Levels - 100% → 70% → 50% → 35% → 25% → 15% triangle reduction (gentler for smooth meshes)
- Screen-Space LOD Selection - Automatic detail adjustment based on object screen size
- LOD Debug Colors - Visualize LOD levels with color coding (K key)
- G+Smo Multipatch Support - Load NURBS/B-spline multipatch geometries from XML files
- View-Dependent Tessellation - Automatic refinement of patches based on screen-space size (4→128 samples)
- Camera Animation - JSON-based keyframe animations with cubic easing and pingpong looping
Coming soon
- CMake 3.16+
- OpenGL 4.6 compatible GPU and drivers
- GLFW3
- OpenMP (usually included with GCC/Clang)
- G+Smo (optional, for multipatch NURBS/B-spline support)
sudo apt install cmake libgl-dev libglfw3-dev libomp-devFor multipatch geometry support, G+Smo is detected automatically from:
- Environment variable
GISMO_ROOTorGISMO_DIR - CMake option
-DGISMO_ROOT=/path/to/gismo - System paths (
/usr/local,/usr,/opt/gismo) - Sibling directory
../gismo
To build G+Smo from source:
git clone https://github.com/gismo/gismo.git
cd gismo && mkdir build && cd build
cmake .. && make -j$(nproc)CMake options:
cmake -DWITH_GISMO=OFF .. # Disable G+Smo support
cmake -DGISMO_ROOT=/path/to/gismo .. # Specify G+Smo locationgit clone https://github.com/weinmueller/opengl-viewer.git
cd opengl-viewer
mkdir build && cd build
cmake ..
make# Run with a single mesh file
./MeshViewer path/to/mesh.obj
# Load multiple mesh files
./MeshViewer mesh1.obj mesh2.obj mesh3.obj
# Run with included samples
./MeshViewer ../assets/meshes/sphere.obj ../assets/meshes/torus.obj
# Set crease angle threshold to preserve sharp edges (default: 180 = smooth all)
./MeshViewer --angle 30 mesh.obj
# Load textured OBJ (requires MTL with map_Kd)
./MeshViewer assets/meshes/textured/textured_cube.obj
# Use a specific default texture for all objects
./MeshViewer --texture checker cube.obj # Built-in checker pattern
./MeshViewer --texture wood sphere.obj # Built-in wood texture
./MeshViewer --texture /path/to/custom.png mesh.obj # Custom texture file
# Built-in texture options: default_grid, checker, uv_test, brushed_metal, wood, concrete
# Load G+Smo multipatch geometry (requires G+Smo)
./MeshViewer assets/gismo/teapot.xml
# Load with camera animation
./MeshViewer -a assets/animations/drone_flythrough.json assets/meshes/cube_{1..100}.obj
# Show help
./MeshViewer --help| Option | Description |
|---|---|
--angle <degrees> |
Crease angle threshold for subdivision (default: 180). Edges with dihedral angle greater than this are kept sharp. Use lower values (e.g., 30) to preserve sharp edges on cubes, etc. |
--texture <path> |
Default texture for all objects. Can be a full path or built-in name: default_grid, checker, uv_test, brushed_metal, wood, concrete |
--animation <file> |
Load camera animation from JSON file. Use -a as shorthand. |
--help |
Show help message |
| Input | Action |
|---|---|
| Left Mouse Drag | Orbit camera |
| Middle Mouse Drag | Pan camera |
| Right Click | Select object (click background to deselect) |
| Scroll Wheel | Zoom in/out |
| Arrow Keys | Orbit camera |
| A | Toggle camera animation playback |
| S | Subdivide mesh (Loop - smooth) |
| D | Subdivide mesh (midpoint - keeps shape) |
| W | Toggle wireframe |
| T | Toggle textures |
| C | Toggle back-face culling |
| G | Toggle frustum culling |
| L | Toggle LOD system |
| K | Toggle LOD debug colors |
| F | Focus on scene |
| H | Show help overlay (keyboard shortcuts) |
| ESC | Stop animation / Cancel subdivision / Exit |
Mesh statistics (vertices, triangles) are printed to the terminal after loading and subdivision.
OpenGL/
├── src/
│ ├── app/ # Application layer
│ │ ├── main.cpp # Entry point
│ │ └── Application.h/cpp # Main application
│ ├── core/ # Window, Shader, Timer
│ ├── util/ # Utilities (Result, TextRenderer)
│ ├── async/ # Background task system
│ │ ├── TaskManager.h # Template base for background tasks
│ │ ├── Progress.h # Unified progress tracking
│ │ ├── SubdivisionTask.h # Subdivision task data
│ │ ├── LODTask.h # LOD generation task data
│ │ └── TessellationTask.h # Tessellation task data
│ ├── animation/ # Camera animation system
│ ├── renderer/ # Camera, Renderer
│ ├── scene/ # Scene graph, Objects
│ ├── mesh/ # Mesh loading and GPU resources
│ ├── geometry/ # Subdivision algorithms
│ ├── lod/ # Level of Detail system
│ ├── multipatch/ # G+Smo multipatch support
│ │ ├── GismoLoader.h/cpp # G+Smo XML file loader
│ │ ├── PatchObject.h/cpp # Patch with dynamic tessellation
│ │ ├── MultiPatchManager.h/cpp # View-dependent refinement
│ │ └── TessellationManager.h/cpp # Background tessellation
│ └── ui/ # User interface overlays
├── shaders/
│ ├── mesh.vert/frag # Main mesh rendering
│ ├── picking.vert/frag # Object picking
│ ├── text.vert/frag # Text rendering
│ └── background.vert/frag # Gradient background
├── assets/
│ ├── meshes/ # Sample OBJ files
│ ├── textures/ # Built-in textures (grid, checker, wood, etc.)
│ ├── animations/ # Camera animation JSON files
│ └── gismo/ # Sample G+Smo multipatch files
└── external/ # Third-party libraries (GLAD, GLM, tinyobjloader)
- Object picking and selection
- Mesh subdivision (Loop and midpoint)
- Parallel subdivision with OpenMP
- GPU double-buffering for geometry updates
- Back-face culling with toggle
- Cached normal matrix optimization
- In-window help overlay (H key)
- Rim lighting for better mesh visibility
- Gradient background
- Object-level frustum culling (G key)
- Background tessellation with progress indicators
- LOD (Level of Detail) system with QEM mesh simplification
- Code refactoring (TaskManager template, shared TextRenderer, unified Progress)
- G+Smo multipatch support with view-dependent tessellation
- Texture mapping with MTL support and built-in textures
- Camera animation with JSON keyframes and pingpong looping
- GPU-based subdivision (compute shaders)
- GLFW - Windowing and input
- GLAD - OpenGL loader
- GLM - Mathematics library
- tinyobjloader - OBJ file parsing
- stb_image - Image loading (PNG, JPG, TGA, BMP)
- nlohmann/json - JSON parsing for animations
- OpenMP - Parallel processing
- G+Smo - Geometry + Simulation Modules (optional, for multipatch support)
MIT License - See LICENSE for details.
Contributions are welcome! Please feel free to submit a Pull Request.