Part of the Graphics Log series:
- Intro into Computer Graphics
- Animated Clock using 2D Graphics
- Creating an Animated Barber Pole with OpenGL
- Basic TexturingThis post!
- Creating a flag using Bezier Curves
- Understanding Subdivision Surfaces in Computer Graphics
- Lighting in Computer Graphics : A Practical Guide with OpenGL
- Techniques for Object Creation
- Practical tips for efficient development with OpenGL
- Computer Graphics: Top Learning Resources for beginners
Introduction
In computer graphics, textures play a pivotal role in bringing life and realism to 3D scenes. Texturing is simply the process of applying images or patterns to the surfaces of 3D models.
Why Textures Matter
Textures provide a way to mimic real-world surfaces, adding depth, complexity, and richness to our digital creations. Whether it’s the grain of wood, the roughness of a stone wall, or the intricate details of fabric, textures enable us to recreate these visual elements in a virtual space. By applying textures, we can transform a simple sphere into a realistic planet, a plain cube into a weathered brick wall, or a flat surface into a lush field of grass.
Texture Coordinates: Mapping 2D Images onto 3D Surfaces
Before we dive into OpenGL and SOIL2, let’s touch on texture coordinates. These are the coordinates used to map a 2D image onto a 3D surface. Each vertex in a 3D model has associated texture coordinates, determining how the texture is wrapped around the surface. Texture coordinates range from (0,0) to (1,1), with (0,0) typically representing the bottom-left corner of the texture and (1,1) representing the top-right corner.
Implementation with OpenGL and SOIL2: Bringing Textures to Life
Now, let’s look into the practical side of texturing using OpenGL and the SOIL2 library. Below is a straightforward code snippet that demonstrates how to apply a texture to a sphere. The SOIL2 library simplifies the process of loading textures.
Loading the textures
c++ 1#include <SOIL.h>
2#include <GL/glut.h>
3
4GLuint texture_wooden, texture_metallic, texture_mars;
5
6void loadTexture()
7{
8 // Load wooden texture
9 texture_wooden = SOIL_load_OGL_texture(
10 "wooden.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y
11 );
12
13 // Load metallic texture
14 texture_metallic = SOIL_load_OGL_texture(
15 "metallic.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y
16 );
17
18 // Load mars texture
19 texture_mars = SOIL_load_OGL_texture(
20 "mars.jpg", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y
21 );
22
23 // Error handling
24 if (!texture_wooden || !texture_metallic || !texture_mars)
25 {
26 printf("Texture loading failed: %s\n", SOIL_last_result());
27 }
28}
Rendering Textured Objects
c++ 1void drawSphereWithTexture(float radius, GLuint texture)
2{
3 GLUquadric* quad = gluNewQuadric();
4
5 gluQuadricTexture(quad, GL_TRUE); //gluQuadricTexture handles texture cordinate mapping in this case ,no need of specifying them manually
6
7 glBindTexture(GL_TEXTURE_2D, texture); // binds the texture to the object
8
9 gluSphere(quad, radius, 32, 32);
10
11 gluDeleteQuadric(quad);
12}
13
14void drawScene()
15{
16
17 glPushMatrix();
18 drawSphereWithTexture(2, texture_metallic);
19 glPopMatrix();
20
21 glPushMatrix();
22 glTranslatef(3, 0, -3);
23 drawSphereWithTexture(2, texture_wooden);
24 glPopMatrix();
25
26 glPushMatrix();
27 glTranslatef(3, 0, 3);
28 drawSphereWithTexture(2, texture_mars);
29 glPopMatrix();
30}