Texture Mapping in OpenGL

Hi ,
I am learning to implement Texture Mapping on My project.
But I am not able to do it.
I read OpenGL Red Book chapter9.
But none of the code is being executed. It gives some weard error.
I donot know how to upload image and do texture mapping.

Can someone post some basic code that I can run on my system and learn texture mapping.

for the purpose of discussion I am using my old project code…
//…
#include<iostream>
#include<stdlib.h>
#include <gl/glut.h>
using namespace std;

void init(void)
{
glClearColor (1.0, 1.0, 1.0, 0.0);
glShadeModel (GL_FLAT);
}

void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1,1.0);
/* clear the matrix /
/
viewing transformation */
//…
// for front view
//gluLookAt (0,0,12.0, 0.0, 0.0, 0.0, 0,1, 0);

// for Angular view

//gluLookAt (-1, 10, 12.0, 2.0, 2.0, 3.0, 0.0, 1, 0.0);
//…
// for top veiw
//gluLookAt (0,15,0, 0.0,0.0, 0.0, 0.0,0, 1.0);
//…

glScalef (1,1,1); /* modeling transformation */

glBegin(GL_QUADS);
glColor3f (0,1,0);
glVertex3f(10,-0.5, 4.0);
glVertex3f(10, -0.5, -10.0);
glVertex3f(-10,-0.5, -10.0);
glVertex3f(-10,-0.5,4.0);

glEnd();

glPushMatrix();
glColor3f (1,0.5,0.0);
glTranslatef (5.0, 0.0, -0.5);
glutSolidCube(1.5);
glPopMatrix();

glPushMatrix();

glTranslatef (4.0, 1.0, -1.5);
glutSolidCube(1.5);
glPopMatrix();

glPushMatrix();

glTranslatef (3.0, 2.0, -2.5);
glutSolidCube(1.5);
glPopMatrix();

glPushMatrix();

glTranslatef (2.0, 3.0,-3.5);
glutSolidCube(1.5);
glPopMatrix();

glPushMatrix();
glColor3f (0.0, 1.0, 1.0);
glTranslatef (0.0, 0.0, 0.0);
glutSolidSphere(0.5,100,100);
glTranslatef (1.0, 0.0, 0.0);
glutSolidSphere(0.5,100,100);
glTranslatef (1.0, 0.0, 0.0);
glutSolidSphere(0.5,100,100);
glTranslatef (1.0, 0.0, 0.0);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (0.5,0.866, 0.0);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (1.5,0.866, 0.0);
glutSolidSphere(0.5,100,100);
glPopMatrix();

glPushMatrix();
glTranslatef (2.5,0.866, 0.0);
glutSolidSphere(0.5,100,100);
glPopMatrix();

glPushMatrix();
glTranslatef (1.0,1.732, 0.0);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (2.0,1.732, 0.0);
glutSolidSphere(0.5,100,100);
glPopMatrix();

glPushMatrix();
glTranslatef (1.5,2.598, 0.0);
glutSolidSphere(0.5,100,100);
glPopMatrix();

// THis is left side sphere balls building up

glPushMatrix();
glTranslatef (-1.0, 0.0, 0.0);
glColor3f (1,0,0.0);
glutSolidSphere(0.5,100,100);
glTranslatef (0.0, 0.0, -1.0);
glutSolidSphere(0.5,100,100);
glTranslatef (0.0, 0.0, -1.0);
glutSolidSphere(0.5,100,100);
glTranslatef (0.0, 0.0, -1.0);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (-1.0, 0.866, -0.5);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (-1.0, 0.866, -1.5);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (-1.0, 0.866, -2.5);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (-1.0, 1.732, -1);
glutSolidSphere(0.5,100,100);
glPopMatrix();

glPushMatrix();
glTranslatef (-1.0, 1.732, -2);
glutSolidSphere(0.5,100,100);

glPopMatrix();

glPushMatrix();
glTranslatef (-1.0, 2.598, -1.5);
glutSolidSphere(0.5,100,100);
glPopMatrix();

glutSwapBuffers();

glFlush ();
}

void reshape (int w, int h)
{
glViewport (0,0, (GLsizei) w, (GLsizei) h);

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();

glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
//glOrtho(-10,20,-10,10,10,-20);
//glOrtho(-15,20,0,0,-15,15);
//glFrustum (-1.0, 1.0, -1.5, 1.2, 1.5, 20.0);

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (-1, 10, 12.0, 2.0, 2.0, 3.0, 0.0, 1, 0.0);
}

void key(unsigned char key, int x, int y) {

switch(key) {
	case 't':
	case 'T':			
		glLoadIdentity();
		gluLookAt (0,15,0, 0.0,0.0, 0.0, 0.0,0, 1.0);
		glutPostRedisplay();
		break;

	case 'a':
	case 'A':
		glLoadIdentity();
		gluLookAt (-1, 10, 12.0, 2.0, 2.0, 3.0, 0.0, 1, 0.0);
		glutPostRedisplay();
		break;

	case 'f':
	case 'F':
		glLoadIdentity();
		gluLookAt (0,0,12.0, 0.0, 0.0, 0.0, 0,1, 0);
		glutPostRedisplay();
		break;
}

}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);

glutMainLoop();
return 0;
}

Hi,
You should use the code tags around the code snippet that u post. For texture mapping, the following steps are needed.

  1. Enable texturing
glEnable(GL_TEXTURE_2D);
  1. Generate the texture id and bind it to the texture 2D target.

glGenTextures(1, &texID);
glBindTexture(Gl_TEXTURE_2D, texID);

  1. Set the texture parameters.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  1. Issue a glTexImage2D call.
glTexImage2D(GL_TEXTURE_2D,0,internal_format,width,height,0,format,data_type, data_pointer);
  1. Send the texture coordinates before sending the vertex like this,

glBegin(GL_QUADS);		
  glTexCoord2f(0,0); glVertex3f(-5,0,-5);
  glTexCoord2f(0,1); glVertex3f(-5,0, 5);
  glTexCoord2f(1,1); glVertex3f(5,0,5);
  glTexCoord2f(1,0); glVertex3f(5,0,-5);
glEnd();

Ok here is a bare minimum texture mapping code that displays a checker textured plane rotating on its y axis. The texture is generated in memory.


#include <gl/glut.h> 
GLuint textureID; 
void init() {
glClearColor(0.5,0.5,1,1);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//create a simple checker texture in memory
GLubyte pData[128*128];
for(int j=0;j<128;j++) {
	for(int i=0;i<128;i++) {
		pData[i+j*128] = (GLubyte)(i<64 && j<64 || i>64 && j>64) * 255;			
	}
}	 
glTexImage2D(GL_TEXTURE_2D,0,GL_INTENSITY,128,128,0,GL_LUMINANCE,GL_UNSIGNED_BYTE, pData); 
}
void display(void)
{
	GLuint error = glGetError();
	glClear (GL_COLOR_BUFFER_BIT);
	glRotatef(0.1,0,1,0);
	glBegin(GL_QUADS);		
		glTexCoord2f(0,0); glVertex3f(-5,0,-5);
		glTexCoord2f(0,1); glVertex3f(-5,0, 5);
		glTexCoord2f(1,1); glVertex3f(5,0,5);
		glTexCoord2f(1,0); glVertex3f(5,0,-5);
	glEnd();
	
	glutSwapBuffers();
	glFlush ();
}
void idle() { 
	glutPostRedisplay();
}
void reshape (int w, int h)
{
	glViewport (0,0, (GLsizei) w, (GLsizei) h);
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	glFrustum (-1.0, 1.0, -1.0, 1.0, 1, 50.0);
	glMatrixMode (GL_MODELVIEW);
	glLoadIdentity ();
	gluLookAt (10, 10, 10, 0, 0, 0, 0, 1, 0);
}
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize (500, 500);
	glutInitWindowPosition (100, 100);	
	glutCreateWindow ("Simple texture demo");	 
	init();
	glutDisplayFunc(display);
	glutReshapeFunc(reshape); 
	glutIdleFunc(idle);
	glutMainLoop();
	return 0;
}

Regards,
Mobeen

Thanks Mobeen for Replying!!
I am trying to understand the steps…
Please tell me one thing where and How I need to store the bmp images?.
Do I need to store that in project folder ? and if yes where in VC++ express edition:
Header
Resource
Source .
I need to implement images texture on 3d objects.
Till now I only learned about making a scene,lighting,viewing fundamentals.
This is just my second week to OpenGL.:frowning:
If you can provide me a simple basic tutorial I will be really grateful to you or some site reference where I can find some working solve example.
The problem is the sites which are showing texture mapping there codes are not working because I am not able to debug there issues.

You need to place the image in the same folder where you .vcproj file is placed (not the solution .sln file).

Alternately, you can change the working directory in the project settings if u want to lookup a different directory from this directory during the visual studio session but then you have to make note of this directory when deploying the executable.

Well it all depends on the texture images you want to load. You may either write your own loaders from scratch but these will be limited to basic image formats like bmp, jpeg, png, raw, tga, ppm etc. Another alternate is you may resort to an external library like devIL (http://openil.sourceforge.net/) or freeimage (http://freeimage.sourceforge.net/) to make the image loading part easier for u. These will help you obtian the pointer to image data which u may then pass to OpenGL. DevIL goes one step further by providing you a utility toolkit (ilut) that loads the texture in OpenGL directly and binds it and returns its ID in just one function call. Refer to the devIL tutorials for details on this.

To learn more about OpenGL in general and texturing in particular, I highly recommend the official wiki and the topics contained in(http://www.opengl.org/wiki/Texture#Texture_Objects)

My advice to u would be dont just read things try them out. Its practice that will help u learn.

Hope this helps,
Mobeen

I posted a texture mapping demo for Windows a while ago. It includes source code to load and display .bmp images as textures. ‘Marshats’ also contributed a Linux version of it. It’s not as elegant or powerful as using a library like devIl, but it has the advantage of being self-contained (i.e. you don’t have to devote time to learning how to use Devil). All the required files are at:

OpenGL Texture Mapping Demo

MaxH has a really nice sample code for a quick self contained texture example. Quick follow up – The “Linux_Source.cpp” is sort of misnamed since it actually is a DevIL based example that will compile fine on Linux, as well as Windows without any source code change.

Thanks to All by going to these links i have learned a lot!!
And i am able to do texture mapping in primitive objects.
But, I am facing a another subtle issue.
I am able to implement only one image.
How can I implement different Images for different objects in the scene.
and how to call different images.
we use the simple syntax of
void int( void){

Image* image = loadBMP("tiger.bmp");

_textureId = loadTexture(image);

delete image;

}

void display(void)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glNormal3f(0.0, 1.0f, 0.0f);

glBegin(GL_QUADS);// -Z-X PLane

glColor3f(1,1,0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-11,-0.5, -7.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-11, -0.5, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0,-0.5, 0.0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0,-0.5,-7.0);
glEnd();
}

glBindTexture(GL_TEXTURE_2D, <choose_texture>) with the different texture id before drawing should be applied.


void int( void){

Image* image = loadBMP("tiger.bmp");

_textureId = loadTexture(image);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

delete image;

Image* image2 = loadBMP("tiger2.bmp");

_textureId_2 = loadTexture(image2);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId_2);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

delete image2;
}

void display(void)
{
glBindTexture(GL_TEXTURE_2D, _textureId);

glNormal3f(0.0, 1.0f, 0.0f);

glBegin(GL_QUADS);// -Z-X PLane

glColor3f(1,1,0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-11,-0.5, -7.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-11, -0.5, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0,-0.5, 0.0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0,-0.5,-7.0);
glEnd();

// bind second image and draw new primitive
glBindTexture(GL_TEXTURE_2D, _textureId_2);

glTranslatef(-15,-15,15);  // just to move away from previous drawing

glNormal3f(0.0, 1.0f, 0.0f);

glBegin(GL_QUADS);// -Z-X PLane

glColor3f(1,1,0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-11,-0.5, -7.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-11, -0.5, 0.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0,-0.5, 0.0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(0,-0.5,-7.0);
glEnd();
}

No need to glEnable(GL_TEXTURE_2D); twice.