EAGL.Examples.LearnOpenGL.GettingStarted.Textures (eagl v0.3.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 robust 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
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.
Summary
Functions
@spec run_example() :: :ok | {:error, term()}