16. OpenGL Texturing

Because it is so much simpler at the moment, I am going to show you how to use
 textures under Windows only, the only thing is the actual, The original loading
 code I was using had it’s limitations so I have reworked it to make it more general.

 But back to the actual texturing, because it is under windows we have to include
 the windows header file, then we also need to add the stdio header file.

 using GLuint we create a variable for the texture, called ‘texture’, but you can call it
 whatever you wish.

 in the ‘display’ function we first set the variable ‘texture’ to the actual
 loaded image using:
 texture = LoadTexture( “texture.raw”, 256, 256 );
 where 256, 256 is the width and the height of the file respectively.
 then we enable the 2D Texturing, this is done with:
 glEnable( GL_TEXTURE_2D );
 and bind the texture with:
 glBindTexture( GL_TEXTURE_2D, texture );

 then after drawing everything we need with the texture, we clear it to save
 system resources.

 ——————————————————————————
 Section 1: The loading of the texture:

GLuint LoadTexture( const char * filename, int width, int height )
{
    GLuint texture;
    unsigned char * data;
    FILE * file;

 The following code will read in our RAW file
    file = fopen( filename, “rb” );  We need to open our file
    if ( file == NULL ) return 0;  If our file is empty, set our texture to empty


    data = (unsigned char *)malloc( width * height * 3 ); assign the nessecary memory for the texture


    fread( data, width * height * 3, 1, file );  read in our file
    fclose( file ); close our file, no point leaving it open

    glGenTextures( 1, &texture ); then we need to tell OpenGL that we are generating a texture
    glBindTexture( GL_TEXTURE_2D, texture ); now we bind the texture that we are working with
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); set texture environment parameters
 The parameter GL_MODULATE will blend the texture with whatever is underneath, setting it to GL_DECAL
 will tell the texture to replace whatever is on the object.

here we are setting what textures to use and when. The MIN filter is which quality to show
when the texture is near the view, and the MAG filter is which quality to show when the texture
is far from the view.

The qualities are (in order from worst to best)
GL_NEAREST
GL_LINEAR
GL_LINEAR_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_LINEAR

 The two mipmap variables only work in textures with generated mipmaps, so you will see that in action
 in a later tutorial.

And if you go and use extensions, you can use Anisotropic filtering textures which are of an
even better quality, but this will do for now.

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

Here we are setting the parameter to repeat the texture instead of clamping the texture
to the edge of our shape.

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

Generate the texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);

    free( data ); free the texture
    return texture; return the texture data
}

——————————————————————————–
Section 2: Cleaning Up:

If we decide not to clean up after our work, you will find that the program will inevitably
slow down your computer, taking more and more memory.
void FreeTexture( GLuint texture )
{
  glDeleteTextures( 1, &texture );  Delete our texture, simple enough.
}

——————————————————————————-
Section 3: Texture Coordinates

This is how texture coordinates are arranged

  0,1   —–   1,1
       |     |
       |     |
       |     |
  0,0   —–   1,0

 With 0,0 being the bottom left and 1,1 being the top right.

 Now the point of using the value 0,1 instead of 0,10, is so that it is mapping 1 texture to the
 coordinates. Changing that to 10 would then try to map 10 textures to the one quad. Which because
 I have the repeat parameter set in our texture, it would draw 10 across and 10 down, if we had
 it clamped, we would be still drawing 1. The repeat function is good for things like
 brick walls.

 To assign texture coordinates to a vertex look at the following code:
glBegin (GL_QUADS);

glTexCoord2d(0.0,0.0);
with our vertices we have to assign a texcoord so that our texture has some points to draw to
glVertex2d(-1.0,-1.0);

glTexCoord2d(1.0,0.0);
glVertex2d(+1.0,-1.0);

glTexCoord2d(1.0,1.0);
glVertex2d(+1.0,+1.0);

glTexCoord2d(0.0,1.0);
glVertex2d(-1.0,+1.0);

glEnd();

For every vertex, we are assigning a texture coordinate that corresponds with it. Keep in mind
that this does not mean that if a vertex is a -10, 20, the texture coordinates will be -10, 20.
They will infact be something along the lines of 0,1.

———————————————————————

So now you should have a rough idea of the basics associated with texturing.
If you have any questions, feel free to email me at swiftless@gmail.com

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
    // Because it is so much simpler at the moment, I am going to show
 you how to use

// textures under Windows only, the only thing is the actual,
 The original loading

// code I was using had it’s limitations so I have reworked it 
to make it more general.

// But back to the actual texturing, because it is under windows
 we have to include

// the windows header file, then we also need to add the stdio 
header file.

// using GLuint we create a variable for the texture, called 
‘texture’, but you can call it

// whatever you wish.

// in the ‘display’ function we first set the variable ‘texture’
 to the actual

// loaded image using:
// texture = LoadTexture( “texture.raw”, 256, 256 );
// where 256, 256 is the width and the height of the file 
respectively.

// then we enable the 2D Texturing, this is done with:
// glEnable( GL_TEXTURE_2D );
// and bind the texture with:
// glBindTexture( GL_TEXTURE_2D, texture );

// then after drawing everything we need with the texture, we
 clear it to save

// system resources.

// ——————————————————————————

// Section 1: The loading of the texture:

//GLuint LoadTexture( const char * filename, int width, int
 height )

//{
//    GLuint texture;
//    unsigned char * data;
//    FILE * file;

// The following code will read in our RAW file
//    file = fopen( filename, “rb” ); // We need to open our file
//    if ( file == NULL ) return 0; // If our file is empty, set our 
texture to empty

//    data = (unsigned char *)malloc( width * height * 3 ); //assign
 the nessecary memory for the texture

//    fread( data, width * height * 3, 1, file ); // read in our file

//    fclose( file ); //close our file, no point leaving it open

//    glGenTextures( 1, &texture ); //then we need to tell OpenGL
 that we are generating a texture

//    glBindTexture( GL_TEXTURE_2D, texture ); //now we bind 
the texture that we are working with

//    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, 
GL_MODULATE ); //set texture environment parameters

// The parameter GL_MODULATE will blend the texture with 
whatever is underneath, setting it to GL_DECAL

// will tell the texture to replace whatever is on the object.

//here we are setting what textures to use and when. The MIN 
filter is which quality to show

//when the texture is near the view, and the MAG filter is which
 quality to show when the texture

//is far from the view.

//The qualities are (in order from worst to best)
//GL_NEAREST
//GL_LINEAR
//GL_LINEAR_MIPMAP_NEAREST
//GL_LINEAR_MIPMAP_LINEAR

// The two mipmap variables only work in textures with generated
 mipmaps, so you will see that in action

// in a later tutorial.

//And if you go and use extensions, you can use Anisotropic 
filtering textures which are of an

//even better quality, but this will do for now.

//    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
 GL_LINEAR );

//    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
 GL_LINEAR );

//Here we are setting the parameter to repeat the texture 
instead of clamping the texture

//to the edge of our shape. 

//    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 
GL_REPEAT );

//    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 
GL_REPEAT );

//Generate the texture
//    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
 0, GL_RGB, GL_UNSIGNED_BYTE, data);

//    free( data ); //free the texture
//    return texture; //return the texture data
//}

//——————————————————————————–

//Section 2: Cleaning Up:

//If we decide not to clean up after our work, you will find that
 the program will inevitably

//slow down your computer, taking more and more memory.
//void FreeTexture( GLuint texture )
//{
//  glDeleteTextures( 1, &texture ); // Delete our texture, 
simple enough.

//}

//——————————————————————————-

//Section 3: Texture Coordinates

//This is how texture coordinates are arranged
//
//  0,1   —–   1,1
//       |     |
//       |     |
//       |     |
//  0,0   —–   1,0

// With 0,0 being the bottom left and 1,1 being the top right.

// Now the point of using the value 0,1 instead of 0,10, is so 
that it is mapping 1 texture to the

// coordinates. Changing that to 10 would then try to map 10 
textures to the one quad. Which because

// I have the repeat parameter set in our texture, it would draw
 10 across and 10 down, if we had

// it clamped, we would be still drawing 1. The repeat function
 is good for things like

// brick walls.

// To assign texture coordinates to a vertex look at the 
following code:

//    glBegin (GL_QUADS);
//    glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0); //with
 our vertices we have to assign a texcoord

//  glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0); //so 
that our texture has some points to draw to

//  glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
//  glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
//    glEnd();

//For every vertex, we are assigning a texture coordinate 
that corresponds with it. Keep in mind

//that this does not mean that if a vertex is a -10, 20, the 
texture coordinates will be -10, 20. 

// They will infact be something along the lines of 0,1.

//———————————————————————

//So now you should have a rough idea of the basics associated
 with texturing.

//If you have any questions, feel free to email me at 
swiftless@gmail.com

#include <GL/gl.h>
#include <GL/glut.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

GLuint texture; //the array for our texture

GLfloat angle = 0.0;

//function to load the RAW file

GLuint LoadTexture( const char * filename, int width, int 
height )
{
    GLuint texture;
    unsigned char * data;
    FILE * file;

    //The following code will read in our RAW file
    file = fopen( filename, “rb” );
    if ( file == NULL ) return 0;
    data = (unsigned char *)malloc( width * height * 3 );
    fread( data, width * height * 3, 1, file );
    fclose( file );

    glGenTextures( 1, &texture ); //generate the texture with 
the loaded data

    glBindTexture( GL_TEXTURE_2D, texture ); //bind the texture
 to it’s array

    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, 
GL_MODULATE ); //set texture environment parameters

    //here we are setting what textures to use and when. The MIN 
filter is which quality to show

    //when the texture is near the view, and the MAG filter is which
 quality to show when the texture

    //is far from the view.

    //The qualities are (in order from worst to best)
    //GL_NEAREST
    //GL_LINEAR
    //GL_LINEAR_MIPMAP_NEAREST
    //GL_LINEAR_MIPMAP_LINEAR

    //And if you go and use extensions, you can use Anisotropic 
filtering textures which are of an

    //even better quality, but this will do for now.
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
 GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
 GL_LINEAR );

    //Here we are setting the parameter to repeat the texture 
instead of clamping the texture

    //to the edge of our shape. 
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 
GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 
GL_REPEAT );

    //Generate the texture
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
 GL_RGB, GL_UNSIGNED_BYTE, data);
    free( data ); //free the texture
    return texture; //return whether it was successfull
}

void FreeTexture( GLuint texture )
{
  glDeleteTextures( 1, &texture );
}

void square (void) {
    glBindTexture( GL_TEXTURE_2D, texture ); //bind our texture
 to our shape

    glRotatef( angle, 1.0f, 1.0f, 1.0f );
    glBegin (GL_QUADS);
    glTexCoord2d(0.0,0.0); glVertex2d(1.0,1.0); //with 
our vertices we have to assign a texcoord

    glTexCoord2d(1.0,0.0); glVertex2d(+1.0,1.0); //so that
 our texture has some points to draw to

    glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
    glTexCoord2d(0.0,1.0); glVertex2d(1.0,+1.0);
    glEnd();

//This is how texture coordinates are arranged
//
//  0,1   —–   1,1
//       |     |
//       |     |
//       |     |
//  0,0   —–   1,0

// With 0,0 being the bottom left and 1,1 being the top right.

// Now the point of using the value 0,1 instead of 0,10, is so 
that it is mapping 1 texture to the

// coordinates. Changing that to 10 would then try to map 10 
textures to the one quad. Which because

// I have the repeat parameter set in our texture, it would draw
 10 across and 10 down, if we had

// it clamped, we would be still drawing 1. The repeat function
 is good for things like

// brick walls.
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    glEnable( GL_TEXTURE_2D );
    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    square();
    glutSwapBuffers();
    angle ++;
}
void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0)
;
    glMatrixMode (GL_MODELVIEW);
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE);
    glutInitWindowSize (500, 500);
    glutInitWindowPosition (100, 100);
    glutCreateWindow (“A basic OpenGL Window);
    glutDisplayFunc (display);
    glutIdleFunc (display);
    glutReshapeFunc (reshape);

    //Load our texture
    texture = LoadTexture( “texture.raw”, 256, 256 );

    glutMainLoop ();

    //Free our texture
    FreeTexture( texture );

    return 0;
}

Download Texture(.RAW file)

Download Texture(.BMP file)

  • March 25, 2010
  • 35