Swiftless Game Programming Site
Home Tutorials Contact
Home
News
OpenGL
GLSL
OpenCL
Maths
Misc
Work in Progress
Resume
 
 

How to generate texture mipmaps in OpenGL

If you would like to see this site updated, please help out and

 Mipmaps are a group of the same image, scaled to different sizes which are then selected according to how far away the viewer is.
 Instead of resizing the texture to fit the object on the fly,
 opengl will pick the mipmap that best fits the shape and textures
 it with that. This fixes dodgy looking textures, and smooths
 out the overall effect. Making a better looking image.

 To do this all we need is this line in our LoadTexture function:
 gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data );
 Instead of the line:
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
 The 'data' being the texture, the width and height being the width and height
 of the texture file.

Then you just bind it like you would a normal texture.

But because we are now using mipmaps, we also want to change:
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
 To
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );


Simply so that we can get better looking textures.

 And wasn't that simple, we now have mipmaps :-D
 If you have any questions, please 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.
  #include <GL/gl.h>
#include <GL/glut.h>
#include <windows.h>
#include <stdio.h>

GLuint texture; //the array for our texture

GLfloat angle = 0.0;

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_MIPMAP_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
 GL_LINEAR_MIPMAP_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 with mipmaps
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, 
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

    glPushMatrix();
    glRotatef( angle, 1.0f, 1.0f, 1.0f );
    glBegin (GL_QUADS);
    glTexCoord2d(0.0,0.0); 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();
    glPopMatrix();
    glPushMatrix();
    glTranslatef( 0,0,-5 );
    glBegin (GL_QUADS);
    glTexCoord2d(0.0,0.0); 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();
    glPopMatrix();
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT);
    glLoadIdentity();  
    glEnable( GL_TEXTURE_2D ); //enable texturing
    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 | GLUT_RGBA);
    glutInitWindowSize (500, 500);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("A basic OpenGL Window");
    glutDisplayFunc (display);
    glutIdleFunc (display);
    glutReshapeFunc (reshape);

    texture = LoadTexture( "texture.raw", 256, 256 ); //load our texture

    glutMainLoop ();

    FreeTexture( texture );

    return 0;
}

Download C++ Source Code for this Tutorial

Download Visual Basic Source Code for this Tutorial


Comments:

Name: hitmaneidos
Date: 2010-02-05 15:09:07
Comment:
Shouldn't the image have mip maps for this to work? This code will not work with a standard image.

Name: Donald Urquhart
Date: 2010-02-05 15:13:34
Comment:
Hi Hitmaneidos,

This code will work with any image file you input into OpenGL, .RAW, .BMP, .JPG, anything.

The line gluBuild2DMipmaps replaces our standard call to build a texture image, and generates the mip map levels automatically. You can even specify how many levels of mipmapping you would like to achieve and it will generate the respective textures.

If you want to do manual mipmapping on the other hand, then yes you will need an image format that supports that.

Cheers,
Donald

Name: hitmaneidos
Date: 2010-02-23 15:25:19
Comment:
Oh, I see. Thanks for the info!
Name   Email


Reload Image

 
     

 

Copyright 2009, Donald Urquhart AKA Swiftless
Check out: http://www.cdadc.com