390 likes | 527 Views
Texture Mapping. Texture Mapping. Applying an image (or a texture ) to geometry 2D images (rectangular) 3D images (volumetric – such as a CAT scan) Adds realism to the scene A vertex can have: A 3D position (x, y, z) – 3 floats Normal (x, y, z) – 3 floats Color?
E N D
Texture Mapping Jeff Chastine
Texture Mapping • Applying an image (or a texture) to geometry • 2D images (rectangular) • 3D images (volumetric – such as a CAT scan) • Adds realism to the scene • A vertex can have: • A 3D position (x, y, z) – 3 floats • Normal (x, y, z) – 3 floats • Color? • A UV coordinate (s, t) – a.k.a. texture coordinates – 2 floats Jeff Chastine
The Problem ? Polygon to betextured Jeff Chastine
The Problem (0, 1) (1, 1) (0, 1) (1, 1) Polygon to betextured (0, 0) (1, 0) (0, 0) (1, 0) Jeff Chastine
The Problem (0, 1) (1, 1) (0, 1) (1, 1) Victory is mine! (0, 0) (1, 0) (0, 0) (1, 0) Linear interpolate each pixel! Jeff Chastine
What if it’s stretched? (0, 1) (1, 1) (0, 1) (1, 1) (0, 0) (1, 0) (0, 0) (1, 0) Jeff Chastine
What if it’s stretched? (0, 1) (1, 1) (0, 1) (1, 1) (0, 0) (1, 0) (0, 0) (1, 0) Jeff Chastine
What happens now? (0, 1) (1, 1) (0, 2) (2, 2) Polygon to betextured (0, 0) (2, 0) (0, 0) (1, 0) Jeff Chastine
What happens now? (0, 1) (1, 1) (0, 2) (2, 2) (0, 0) (2, 0) (0, 0) (1, 0) Jeff Chastine
What happens now? (0, 1) (1, 1) (0, 2) (2, 2) (0, 0) (2, 0) (0, 0) (1, 0) (1, 0) (Note: there are other ways to handle UVs > 1.0) Jeff Chastine
Non-Planar Geometry (0, 1) (1, 1) (0, 0) (1, 0) Jeff Chastine
TexTure mapping • In the real world, models come with • Geometry • Normals • UV coordinates • A texture! • Now we must: • Load the positions, normalsand UVs into the buffer • Somehow load a texture from file… Put it into a buffer • Somehow get that texture to the fragment shader! Jeff Chastine
Image Files • Bitmaps (BMP) • Common, and usually aren’t compressed • Contain header/meta info followed by pixel data • Are in BGR format, bottom row first! • Are easy to work with (just use my loader) • Won’t that be inefficient? • No – compression is on file side • Raw pixel data is sent to the buffer anyway! • What about JPEG, TGA, or raw image data? Jeff Chastine
Initializing • More IDs: • GLuinttexBufferID; // OpenGL variable • GLuinttexCoordID, texID; // Shader variables • You’ll need a place to store the actual file data • GLubyte image[width][height][3]; • You’ll need a set of texture coordinates for the object: • GLfloat* uvs; // Load these onto the buffer • You also need to enable GL_TEXTURE_2D • glEnable (GL_TEXTURE_2D); Note: you can also call glDeleteTextures(GLsizei n, GLuint *textures); Jeff Chastine
Binding and Loading • You’ll need to bind the texture (make this the active buffer for future operations) • Then, load the pixel data into the texture buffer glGenTextures(1, &texBufferID); glBindTexture(GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); The type of texture **GL_TEXTURE_1D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP Jeff Chastine
Binding and Loading • You’ll need to bind the texture (make this the active buffer for future operations) • Then, load the pixel data into the buffer glGenTextures(1, &texBufferID); glBindTexture (GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); The level of this texture for “mipmapping” - later Jeff Chastine
Binding and Loading • You’ll need to bind the texture (make this the active buffer for future operations) • Then, load the pixel data into the buffer glGenTextures(1, &texBufferID); glBindTexture (GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); How OpenGL should store this data internally **GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_BGR, GL_RGBA… Jeff Chastine
Binding and Loading • You’ll need to bind the texture (make this the active buffer for future operations) • Then, load the pixel data into the buffer glGenTextures(1, &texBufferID); glBindTexture (GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); Obviously the width and height, but why not size of the buffer? Jeff Chastine
Binding and Loading • You’ll need to bind the texture (make this the active buffer for future operations) • Then, load the pixel data into the buffer glGenTextures(1, &texBufferID); glBindTexture (GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); The width of a border (if you want one) Jeff Chastine
Binding and Loading • You’ll need to bind the texture (make this the active buffer for future operations) • Then, load the pixel data into the buffer glGenTextures(1, &texBufferID); glBindTexture (GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); The format of the pixel data we’re giving it **GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_INT_8_8_8_8, ... Jeff Chastine
Binding and Loading • You’ll need to bind the texture (make this the active buffer for future operations) • Then, load the pixel data into the buffer glGenTextures(1, &texBufferID); glBindTexture (GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); The raw pixel data itself Jeff Chastine
Texture Units • A piece of hardware that has access to a texture image • Select that unit with glActiveTexture (GL_TEXTURE0); • For multiple layers/effects, could activate GL_TEXTURE1, GL_TEXTURE2, … • For now, just stick with GL_TEXTURE0! Jeff Chastine
Known Problems in Texture Mapping • What should you do if a texture coordinate is out of range (e.g. > 1.0)? • We can modify the behavior using glTexParameterf() • GL_CLAMP • GL_REPEAT • GL_CLAMP_TO_BORDER • GL_MIRRORED_REPEAT • Others as well glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); Jeff Chastine
Texture Wrapping(Original 1-to-1 Mapping) 1, 1 0, 0 Jeff Chastine
Texture Wrapping(GL_REPEAT) 4, 4 0, 0 Jeff Chastine
Texture Wrapping(GL_CLAMP) – really not useful… 4, 4 0, 0 Jeff Chastine
Texture Wrapping(GL_CLAMP) AND (GL_REPEAT) 4, 4 0, 0 Jeff Chastine
Texture Wrapping(GL_CLAMP_TO_BORDER) 4, 4 0, 0 Jeff Chastine
Texture WrappingWHY Mirrored? (GL_MIRRORED_REPEAT) (GL_REPEAT) Jeff Chastine
Minification and Magnification • At some depth, one screen pixel == one texel (texture element) • Closer, many screen pixels for few texels (magnification) • Farther, many texels for few screen pixels (minification) • What should you do if a one screen pixel is in between multiple texels? • What happens if several parts of the image map to the same pixel? • Change the GL_TEXTURE_MAG_FILTER to: • GL_NEAREST • GL_LINEAR Jeff Chastine
GL_NEAREST Jeff Chastine
GL_LINEAR Jeff Chastine
Another Approach - MipMapping • Have several images that are pre-rendered • OpenGL picks the most approach one (or interpolates) • glGenerateMipmap (GLenum target); http://en.wikipedia.org/wiki/Mipmap Jeff Chastine
SAMPLERS • In your shaders, textures are accessed using a sampler: • sampler1D • sampler2D ** • sampler3D • samplerCube • Samplers are uniform (which makes sense) • Set that sampler in OpenGL using: texID = glGetUniformLocation(progID, “texture”); glUniform1i (texID, 0); // This is GL_TEXTURE0 Jeff Chastine
glEnable(GL_TEXTURE_2D); glGenTextures(1, &texBufferID); glBindTexture(GL_TEXTURE_2D, texBufferID); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT ); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); texCoordID= glGetAttribLocation(progID, “s_vTexCoord"); glEnableVertexAttribArray(texCoordID); glVertexAttribPointer(texCoordID, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offsetToUVsInBytes); texID = glGetUniformLocation(shaderProgramID, “texture”); glActiveTexture(GL_TEXTURE0); glUniform1i(texID, 0); Jeff Chastine
Your Vertex Shader(TexturING only) #version 150 in vec4 s_vPosition; // From our OpenGL program!! in vec4 s_vNormal; // The normal of the vertex in vec2 s_vTexCoord; // In from OpenGL out vec2 texCoord; // Going out to the shader // Remember, uniforms are the same for a vertices. uniform mat4 p; // This is perspective matrix uniform mat4 mv; // This is the model-view matrix // Other stuff cut… void main () { gl_Position = p*mv*vPosition; texCoord = s_vTexCoord; // Interpolate for frag shader } Jeff Chastine
Fragment Shader #version 150 out vec4 fColor; // Final output in vec2 texCoord; // From the vertex shader uniform sampler2D texture; // How to access the texture void main () { fColor = texture2D (texture, texCoord); } Jeff Chastine