In this tutorial, you will learn :
- What are UV coordinates
- How to load textures yourself
- How to use them in OpenGL
- What is filtering and mipmapping, and how to use them
- How to load texture more robustly with GLFW
- What is the alpha channel
When texturing a mesh, you need a way to tell to OpenGL which part of the image has to be used for each triangle. This is done with UV coordinates.
Each vertex has, on top of its position, a couple of floats, U and V. These coordinates are used to access the texture, in the following way :
Notice how the texture is distorted on the triangle.
Knowing the BMP file format is not crucial : plenty of libraries can do it for you. But it’s very simple and can help you understand how things work under the hood. So we’ll write a BMP file loader from scratch, so that you know how it works, and never use it again.
Here is the declaration of the loading function :
GLuint loadBMP_custom(const char * imagepath);
so it’s used like this :
GLuint image = loadBMP_custom("./my_texture.bmp");
Let’s see how to read a BMP file, then.
First, we’ll need some data. These variable will be set when reading the file.
// Data read from the header of the BMP file unsigned char header[54]; // Each BMP file begins by a 54-bytes header unsigned int dataPos; // Position in the file where the actual data begins unsigned int width, height; unsigned int imageSize; // = width*height*3 // Actual RGB data unsigned char * data;
We now have to actually open the file
// Open the file FILE * file = fopen(imagepath, "rb"); if (!file) {printf("Image could not be opened\n"); return 0;}
The first thing in the file is a 54-bytes header. It contains information such as “Is this file really a BMP file?”, the size of the image, the number of bits per pixel, etc. So let’s read this header :
if ( fread(header, 1, 54, file)!=54 ){ // If not 54 bytes read : problem printf("Not a correct BMP file\n"); return false; }
The header always begins by BM. As a matter of fact, here’s what you get when you open a .BMP file in a hexadecimal editor :