Texture Mapping – Comprehensive Study Notes

Introduction

  • Texture mapping = apply a 2-D image to a 3-D surface to add visual detail without adding polygons.

  • Saves geometric complexity: e.g., a brick wall can be 1 quad + texture instead of thousands of brick polygons.

  • Works under perspective transformation: bricks shrink correctly with distance.

  • Can simulate reflective/shiny surfaces by texturing environment maps.

  • Applicable to polygonal meshes and curved surfaces; textures may indicate contours or material properties.

Texture Fundamentals

  • Texture = 2-D bitmap (PNG, JPG…) made of texels (texture pixels).

  • Texture axes: U (horizontal) and V (vertical) or s, t in texture space.
    • Names differ from X,Y,Z world axes to avoid confusion.

  • Texture‐coordinate range usually [0,1] for both axes; size-independent.

  • Coordinate meaning:
    • (0,0) → bottom-left texel.
    • (1,1) → top-right texel.
    • Example: (0.5,0.5) maps a vertex to texture center.

Formal Definition

  • Texture mapping = mapping of 2-D coordinate space (u,v) to a 3-D surface in object/world space.

  • Yields higher perceived realism without increasing vertex/triangle count.

Where It Happens in the Pipeline

  • Implemented in the fragment (pixel) shader stage.
    • Vertex shader forwards texture coordinates as varying variables.
    • Rasterizer interpolates them across fragments.
    • Fragment shader samples the bound texture and combines it with lighting to produce final colour.

Assigning Coordinates to Vertices

  • Every mesh vertex stores a pair (u,v) just like colour or normals.

  • Inside primitives, GPU performs barycentric (perspective-correct) interpolation.

  • In legacy OpenGL (1.x):
    • call glTexCoord2f(u,v) just before glVertex*. Current (u,v) latched to that vertex.

  • Example triangle: vertices carry (0.3,0.1), (0.45,0.6), (0.25,0.7) → these points in the image are glued to the triangle corners.

Example – Pyramid Coordinates

  • Each triangular face gets its own 3 vertices and texture-coordinate triplet:
    • Front: (0,0),(1,0),(0.5,1)
    • Right: (0,0),(1,0),(0.5,1)
    • Back, Left … similar.

OpenGL 1.x Workflow (Immediate Mode)

  • Enable & bind:
    • glEnable(GLTEXTURE2D)
    • glBindTexture(GLTEXTURE2D, texID)

  • Draw:

 glBegin(GL_QUADS)
    glTexCoord2f(0,0); glVertex2f(-1,-1);
    glTexCoord2f(1,0); glVertex2f( 1,-1);
    glTexCoord2f(1,1); glVertex2f( 1, 1);
    glTexCoord2f(0,1); glVertex2f(-1, 1);
 glEnd();

JOGL Example (Texture on Quad)

  • Load file with TextureIO, enable texturing, bind & render.

  • Important JOGL snippets:
    • texture = TextureIO.newTexture(is, false, TextureIO.PNG);
    • texture.bind(gl); texture.enable(gl);

  • Use float literals ("0.5f") to match glTexCoord2f / glVertex2f (32-bit floats).

Using Arrays of Textures

  • Store multiple image paths → load → glGenTextures(count, intArray,0).

  • Keep integer IDs in int[] textures.

  • NeHe TextureReader provides helper methods:
    • TextureReader.readTexture(name) returns TextureReader.Texture (width, height, pixel buffer).

  • Binding & uploading each texture:

 glBindTexture(GL_TEXTURE_2D, textures[i]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
              w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
  • Texture environment example: glTexEnvf(GLTEXTUREENV, GLTEXTUREENVMODE, GLDECAL) → replace polygon material with texture (no modulation).

Matrix Stack Helpers

  • glPushMatrix(): push current model-view matrix on stack.

  • glPopMatrix(): restore last saved matrix.

  • Pattern: push → apply local transform → draw → pop; avoids manual undoing and supports hierarchical modelling.

Texture Wrapping (Out-of-Range u,v)

  • Modes set per axis with glTexParameteri(GLTEXTUREWRAPS / T, mode). • GLREPEAT → repeat every integer interval (…-1→0→1→2…)
    • GLMIRROREDREPEAT → mirror every odd interval.
    • GLCLAMPTOEDGE → clamp to last texel. • GLCLAMPTOBORDER + border colour → sample border colour.

  • Example code:

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  • Choosing text_crd = 8.0 and GL_REPEAT maps an 8×8 tile grid onto one quad.

Magnification vs Minification

  • Magnification: texture drawn larger on-screen than native resolution (fewer texels per pixel). Problems → blockiness.

  • Minification: texture appears smaller (many texels per pixel). Problems → aliasing/flicker.

Filters

  • Magnification filter (one of two):
    • GLNEAREST → nearest-texel sample (blocky). • GLLINEAR → bilinear interpolation using 4 nearest texels (smooth).

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  • Minification filter (six choices). Most common:
    • GLLINEARMIPMAP_LINEAR (trilinear) – linear within level + linear between levels.

 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                 GL_LINEAR_MIPMAP_LINEAR);

Mipmapping

  • "Multum in parvo" = many in little.

  • Precompute \frac14, \frac1{16}, \frac1{64},\ldots sized versions of texture.

  • GPU selects level based on projected texel size; ensures constant texel:pixel ratio & cache-friendly.

  • Transitions smoothed by bilinear/trilinear filtering.

  • Benefits: eliminates shimmer/aliasing during minification, accelerates sampling.

Practical Guidelines & Implications

  • Always supply texture coords for every vertex; share vertices when possible to avoid seams.

  • Use GL_LINEAR for magnification and mipmapped filters for minification.

  • Pick wrapping mode consistent with artistic intent (e.g., GL_REPEAT for tiled floors).

  • Store resource images in accessible classpath; ensure correct casing & path for TextureIO.

  • Be mindful of float/double typing in Java bindings; append 'f' for literals.

  • Ethical/practical point: using photographic textures raises licensing concerns; ensure rights for scanned or downloaded images.