MULTIMEDIA

iPhone 3D Programming : Adding Textures to ModelViewer (part 2) - Generating Texture Coordinates

1/21/2011 7:41:25 PM

2. Generating Texture Coordinates

To control how the texture gets applied to the models, we need to add a 2D texture coordinate attribute to the vertices. The natural place to generate texture coordinates is in the ParametricSurface class. Each subclass should specify how many repetitions of the texture get tiled across each axis of domain. Consider the torus: its outer circumference is much longer than the circumference of its cross section. Since the x-axis in the domain follows the outer circumference and the y-axis circumscribes the cross section, it follows that more copies of the texture need to be tiled across the x-axis than the y-axis. This prevents the grid pattern from being stretched along one axis.

Recall that each parametric surface describes its domain using the ParametricInterval structure, so that’s a natural place to store the number of repetitions; see Example 4. Note that the repetition counts for each axis are stored in a vec2.

Example 4. Texture support in ParametricSurface.hpp
#include "Interfaces.hpp"

struct ParametricInterval {
ivec2 Divisions;
vec2 UpperBound;
vec2 TextureCount;
};

class ParametricSurface : public ISurface {
...
private:
vec2 ComputeDomain(float i, float j) const;
ivec2 m_slices;
ivec2 m_divisions;
vec2 m_upperBound;
vec2 m_textureCount;
};

The texture counts that I chose for the cone and sphere are shown in bold in Example 5.

Example 5. Texture support in ParametricEquations.hpp
#include "ParametricSurface.hpp"

class Cone : public ParametricSurface {
public:
Cone(float height, float radius) : m_height(height), m_radius(radius)
{
ParametricInterval interval = { ivec2(20, 20), vec2(TwoPi, 1), vec2(30,20) };
SetInterval(interval);
}
...
};

class Sphere : public ParametricSurface {
public:
Sphere(float radius) : m_radius(radius)
{
ParametricInterval interval = { ivec2(20, 20), vec2(Pi, TwoPi), vec2(20, 35) };
SetInterval(interval);
}
...
};



Next we need to flesh out a couple methods in ParametericSurface (Example 6). Recall that we’re passing in a set of flags to GenerateVertices to request a set of vertex attributes; until now, we’ve been ignoring the VertexFlagsTexCoords flag.

Example 6. Texture support in ParametricSurface.cpp
void ParametricSurface::SetInterval(const ParametricInterval& interval)
{
m_divisions = interval.Divisions;
m_slices = m_divisions - ivec2(1, 1);
m_upperBound = interval.UpperBound;
m_textureCount = interval.TextureCount;
}

...

void ParametricSurface::GenerateVertices(vector<float>& vertices,
unsigned char flags) const
{
int floatsPerVertex = 3;
if (flags & VertexFlagsNormals)
floatsPerVertex += 3;
if (flags & VertexFlagsTexCoords)
floatsPerVertex += 2;

vertices.resize(GetVertexCount() * floatsPerVertex);
float* attribute = &vertices[0];

for (int j = 0; j < m_divisions.y; j++) {
for (int i = 0; i < m_divisions.x; i++) {

// Compute Position
vec2 domain = ComputeDomain(i, j);
vec3 range = Evaluate(domain);
attribute = range.Write(attribute);

// Compute Normal
if (flags & VertexFlagsNormals) {
...
}

// Compute Texture Coordinates
if (flags & VertexFlagsTexCoords) {
float s = m_textureCount.x * i / m_slices.x;
float t = m_textureCount.y * j / m_slices.y;
attribute = vec2(s, t).Write(attribute);
}
}
}
}



In OpenGL, texture coordinates are normalized such that (0,0) maps to one corner of the image and (1, 1) maps to the other corner, regardless of its size. The inner loop in Example 6 computes the texture coordinates like this:

float s = m_textureCount.x * i / m_slices.x;
float t = m_textureCount.y * j / m_slices.y;

Since the s coordinate ranges from zero up to m_textureCount.x (inclusive), OpenGL horizontally tiles m_textureCount.x repetitions of the texture across the surface.

Note that if you were loading the model data from an OBJ file or other 3D format, you’d probably obtain the texture coordinates directly from the model file rather than computing them like we’re doing here.
Other  
  •  Programming with DirectX : Shading and Surfaces - Implementing Texture Mapping (part 2) - Multi Texture Demo
  •  Programming with DirectX : Shading and Surfaces - Implementing Texture Mapping (part 1) - 2D Texture Mapping Demo
  •  Building Out Of Browser Silverlight Applications - Using COM Interoperability and File System Access
  •  Building Out Of Browser Silverlight Applications - Controlling the Application Window
  •  iPhone 3D Programming : Adding Depth and Realism - Loading Geometry from OBJ Files
  •  iPhone 3D Programming : Adding Depth and Realism - Better Wireframes Using Polygon Offset
  •  Programming with DirectX : Textures in Direct3D 10 (part 2)
  •  Programming with DirectX : Textures in Direct3D 10 (part 1) - Textures Coordinates
  •  Programming with DirectX : Shading and Surfaces - Types of Textures
  •  iPhone 3D Programming : Adding Shaders to ModelViewer (part 2)
  •  iPhone 3D Programming : Adding Shaders to ModelViewer (part 1) - New Rendering Engine
  •  iPhone 3D Programming : Adding Depth and Realism - Shaders Demystified
  •  Programming with DirectX : Transformation Demo
  •  Programming with DirectX : View Transformations
  •  Programming with DirectX : World Transformations
  •  Programming with DirectX : Projection Transformations
  •  iPhone 3D Programming : Adding Depth and Realism - Lighting Up (part 2)
  •  iPhone 3D Programming : Adding Depth and Realism - Lighting Up (part 1)
  •  iPhone 3D Programming : Adding Depth and Realism - Surface Normals (part 2)
  •  iPhone 3D Programming : Adding Depth and Realism - Surface Normals (part 1)
  •  
    Most View
    Installing HP-UX : Loading Patches
    LG LM9600 47” Smart TV - A New Direction
    HP Photosmart 7520 e-All-in-One
    Acer CloudMobile - Ambitious Android Phone (Part 2)
    What To Do With An Old Mac (Part 1)
    Deploying to an iPhone, Debugging, and Testing : Distributing Your Application
    How To Choose A Printer (Part 2)
    Nvidia GeForce GTX Titan 6 GB Graphics Card Review (Part 1)
    Appetizing Art - The Complete Picture (Part 2)
    How To Deal With Windows And Network-Related Problems (Part 2)
    Top 10
    The NZXT Kraken X40 Compact Liquid Cooler Review (Part 3)
    The NZXT Kraken X40 Compact Liquid Cooler Review (Part 2)
    T-Mobile’s Samsung Galaxy Note II Review (Part 6)
    T-Mobile’s Samsung Galaxy Note II Review (Part 5)
    T-Mobile’s Samsung Galaxy Note II Review (Part 4)
    T-Mobile’s Samsung Galaxy Note II Review (Part 3)
    T-Mobile’s Samsung Galaxy Note II Review (Part 2)
    T-Mobile’s Samsung Galaxy Note II Review (Part 1)
    Sony Cybershot DSC-TF1 - Affordable Water-Resistant Camera
    Buffalo MiniStation Slim 500GB External Hard Drive