EAGL.Examples.LearnOpenGL.GettingStarted.Textures (eagl v0.7.0)
View SourceLearnOpenGL 4.1 - Textures
This example demonstrates basic texture mapping in OpenGL - applying 2D images to 3D geometry. It corresponds to the Textures tutorial in the LearnOpenGL series and showcases EAGL's comprehensive texture loading capabilities.
Original C++ Source
This example is based on the original LearnOpenGL C++ tutorial: https://github.com/JoeyDeVries/LearnOpenGL/tree/master/src/1.getting_started/4.1.textures
Framework Adaptation Notes
In the original LearnOpenGL C++ tutorial, this example introduces textures:
- Loading image files using stb_image.h library
- Creating OpenGL texture objects
- Setting texture parameters (wrapping, filtering)
- Texture coordinates and sampling
- Binding textures before rendering
EAGL's framework preserves all these concepts while providing enhanced functionality:
- Real Image Loading: Uses the same stb_image library as the original tutorial
- Graceful Degradation: Automatic fallback to checkerboard patterns when images unavailable
- Pixel Alignment Handling: Proper handling of non-4-byte-aligned image widths
- Y-Axis Correction: Automatic Y-flip to match OpenGL coordinate conventions
- Format Detection: Automatic channel detection (RGB, RGBA) and format selection
EAGL vs Original Implementation
Original LearnOpenGL approach: Uses stb_image.h to load container.jpg:
int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
EAGL approach: Enhanced image loading with comprehensive error handling:
{:ok, texture_id, width, height} = load_texture_from_file("priv/images/eagl_logo_black_on_white.png")
- Same underlying library: Uses stb_image (optional dependency)
- Enhanced error handling:
{:ok, result}
tuples and comprehensive fallbacks - Pixel alignment fix:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
for arbitrary image widths - Coordinate system handling: Automatic Y-flip for OpenGL convention
- Educational value: Works with or without external dependencies
Technical Improvements
This implementation includes several technical enhancements over basic texture loading:
Pixel Alignment: Handles images whose width × channels isn't 4-byte aligned
- The 418×418 EAGL logo tests this fix (418 × 4 = 1672 bytes per row)
- Prevents diagonal texture skewing common with arbitrary image dimensions
Y-Axis Handling: Proper coordinate system conversion
- Images typically have (0,0) at top-left
- OpenGL expects (0,0) at bottom-left
- Automatic Y-flip ensures textures appear right-side up
Format Detection: Automatic channel count handling
- 1 channel → GL_RED
- 2 channels → GL_RG
- 3 channels → GL_RGB
- 4 channels → GL_RGBA
Original Tutorial Concepts Demonstrated
- Texture Objects: Creating texture IDs with
create_texture()
- Texture Binding: Binding textures with
:gl.bindTexture()
- Texture Parameters: Setting wrap and filter modes with
set_texture_parameters()
- Texture Data: Loading pixel data with
load_texture_data()
- Mipmaps: Generating mipmaps with
:gl.generateMipmap()
- Texture Coordinates: Adding texture coordinates to vertex data
- Texture Sampling: Using
sampler2D
andtexture()
in fragment shader
Key Learning Points
- Understanding texture coordinates (0,0 to 1,1 mapping)
- Texture wrapping modes (repeat, clamp, etc.)
- Texture filtering (nearest vs linear)
- The relationship between vertex attributes and fragment shader inputs
- How textures are sampled and interpolated across triangles
- Pixel alignment considerations for arbitrary image dimensions
- Coordinate system differences between image formats and OpenGL
State Management Evolution
This example marks change in the LearnOpenGL series implementation. Starting with textures, our OpenGL state becomes more complex as we need to track multiple resources: shader programs, vertex arrays, buffers, and now texture objects.
From 4.1 forward, we transition to map-based state management for better maintainability and readability as examples grow in complexity.
Vertex Data Structure
The rectangle uses interleaved vertex data:
- Position (3 floats): x, y, z coordinates
- Color (3 floats): r, g, b values (for potential mixing)
- Texture coordinates (2 floats): s, t coordinates
Texture Mapping
The rectangle is mapped with texture coordinates:
- Bottom-left: (0.0, 0.0)
- Bottom-right: (1.0, 0.0)
- Top-right: (1.0, 1.0)
- Top-left: (0.0, 1.0)
Dependencies
- Optional:
{:stb_image, "~> 0.6"}
for real image loading - Fallback: Procedural checkerboard generation when stb_image unavailable
- Educational: Works in both scenarios with helpful guidance
Usage
EAGL.Examples.LearnOpenGL.GettingStarted.Textures.run_example()
Press ENTER to exit the example.