Hi ,
I am able to create a model with a single texture mapping image. via using imageloader.
But I am not able to use multiple images. I am using bmp file extension and image loader.
Please help me…
The below is my code.
// Main cpp file
// FOr compiling this code I used code of
//OpenGL Video Tutorial - Textures
#include<iostream>
#include<stdlib.h>
#include <glut.h>
#include<math.h>
#include “imageloader.h”
float value = 0.;
GLfloat white_light_diff[] = { 2,0,0,1 };
GLfloat white_light_amb[] = { 1,2,2, 2 };
GLfloat light_posn[] = { -0.5,10,-0.25, 1 };
GLfloat spot_posn[] = { 0.5, 5, 2, 1 };
GLfloat spot_direcn[] = { .2, -1., 2.15 };
GLfloat spot_spec[] = { 0.6, 0.6, 0.6, 1. };
float spot_cutoff = 60.;
float spot_expo = 0.0;
// For Pyramid sphere balls of Red purple color
GLfloat mat_diffuse0[] = { 0.4, 0.2,0.1, 1.0 };
GLfloat mat_ambient0[] = { 0.2, 0.1,0.1 , 1.0 };
// for Square Grids blue color
GLfloat mat_diffuse1[] = { 0.1, 0.0, 2, 1.0 };
GLfloat mat_specular1[] = { 0.1, 0., 1., 1.0 };
GLfloat mat_ambient1[] = { 0.1, 0., 0.3, 1.0 };
// for Ball primitives extruded ones
GLfloat mat_diffuse3[] = { 0.3, 0.4, 0.1, 1.0 };
GLfloat mat_specular3[] = { 0.1, 0.4, 0.1, 1.0 };
GLfloat mat_ambient3[] = { 0.1, 0.2, 0.1, 1.0 };
// for Square primitives extruded ones
GLfloat mat_diffuse2[] = { 0.5, 0.1, 0.2, 1.0 };
GLfloat mat_ambient2[] = { 0.3, 0.1, 0.2, 1.0 };
bool animate = false;
// for texturing stuff
//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId); //Make room for our texture
glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D
0, //0 for now
GL_RGB, //Format OpenGL uses for image
image->width, image->height, //Width and height
0, //The border of the image
GL_RGB, //GL_RGB, because pixels are stored in RGB format
GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
//as unsigned numbers
image->pixels); //The actual pixel data
return textureId; //Returns the id of the texture
}
GLuint _textureId; //The id of the texture
//…
void init(void)
{
glClearColor (1.0, 1.0, 1.0, 0.0);
glShadeModel (GL_SMOOTH);
glClearColor( .46, .53, .6, 0. );
// Enable depth testing
glEnable( GL_DEPTH_TEST );
// We keep our light within the display func so that we can influence its properties
// Create the first white light (made largely ambient and diffuse (source at infinity)
glLightfv( GL_LIGHT0, GL_POSITION, light_posn );
glLightfv( GL_LIGHT0, GL_DIFFUSE, white_light_diff );
glLightfv( GL_LIGHT0, GL_AMBIENT, white_light_amb );
//// Second light is a white spotlight
glLightfv( GL_LIGHT1, GL_DIFFUSE, white_light_diff );
glLightfv( GL_LIGHT1, GL_SPECULAR, spot_spec);
glLightfv( GL_LIGHT1, GL_POSITION, spot_posn );
glLightfv( GL_LIGHT1, GL_SPOT_DIRECTION, spot_direcn );
glLightfv( GL_LIGHT1, GL_SPOT_CUTOFF, &spot_cutoff );
glLightfv( GL_LIGHT1, GL_SPOT_EXPONENT, &spot_expo );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHT1 );
// for texture stuff
Image* image = loadBMP("tiger.bmp");
_textureId = loadTexture(image);
delete image;
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glColor3f (1,1,1);
gluLookAt(3,-2,1.3,1,-0.4,0.6,0,1,0);
glScalef (1,1,1); /* modeling transformation */
glDisable( GL_LIGHTING );
glDisable( GL_LIGHTING );
glBegin(GL_QUADS); // X-Z PLane
glColor4f(1,1,1,1);
glVertex3f(0,-0.5, 0.0);
glVertex3f(0,-0.5,-7.0);
glVertex3f(11,-0.5,-7.0);
glVertex3f(11, -0.5, 0.0);
glEnd();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);
// trial for texture working
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();
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS); // XZ PLane
glColor3f(0,1,0);
glVertex3f(0,-0.5, 0.0);
glVertex3f(0,-0.5,7.0);
glVertex3f(11,-0.5,7.0);
glVertex3f(11, -0.5, 0.0);
glEnd();
glBegin(GL_QUADS);// Z-X PLane
glColor4f(0.98,0.85,.12,1);
glVertex3f(-11,-0.5, 7.0);
glVertex3f(-11, -0.5, 0.0);
glVertex3f(0,-0.5, 0.0);
glVertex3f(0,-0.5,7.0);
glEnd();
glDisable( GL_LIGHTING );
glPushMatrix();
glTranslatef (2, 5, 0.0);
glColor3f (1,0,0.0);
glutSolidCube(4);
glPopMatrix();
glutSwapBuffers();
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0,0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(-14, 14, -14,14, 16, -14);
glMatrixMode (GL_MODELVIEW);
}
using namespace std;
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
// imageloader.cpp file
#include <assert.h>
#include <fstream>
#include “imageloader.h”
using namespace std;
Image::Image(char* ps, int w, int h) : pixels(ps), width(w), height(h) {
}
Image::~Image() {
delete[] pixels;
}
namespace {
//Converts a four-character array to an integer, using little-endian form
int toInt(const char* bytes) {
return (int)(((unsigned char)bytes[3] << 24) |
((unsigned char)bytes[2] << 16) |
((unsigned char)bytes[1] << 8) |
(unsigned char)bytes[0]);
}
//Converts a two-character array to a short, using little-endian form
short toShort(const char* bytes) {
return (short)(((unsigned char)bytes[1] << 8) |
(unsigned char)bytes[0]);
}
//Reads the next four bytes as an integer, using little-endian form
int readInt(ifstream &input) {
char buffer[4];
input.read(buffer, 4);
return toInt(buffer);
}
//Reads the next two bytes as a short, using little-endian form
short readShort(ifstream &input) {
char buffer[2];
input.read(buffer, 2);
return toShort(buffer);
}
//Just like auto_ptr, but for arrays
template<class T>
class auto_array {
private:
T* array;
mutable bool isReleased;
public:
explicit auto_array(T* array_ = NULL) :
array(array_), isReleased(false) {
}
auto_array(const auto_array<T> &aarray) {
array = aarray.array;
isReleased = aarray.isReleased;
aarray.isReleased = true;
}
~auto_array() {
if (!isReleased && array != NULL) {
delete[] array;
}
}
T* get() const {
return array;
}
T &operator*() const {
return *array;
}
void operator=(const auto_array<T> &aarray) {
if (!isReleased && array != NULL) {
delete[] array;
}
array = aarray.array;
isReleased = aarray.isReleased;
aarray.isReleased = true;
}
T* operator->() const {
return array;
}
T* release() {
isReleased = true;
return array;
}
void reset(T* array_ = NULL) {
if (!isReleased && array != NULL) {
delete[] array;
}
array = array_;
}
T* operator+(int i) {
return array + i;
}
T &operator[](int i) {
return array[i];
}
};
}
Image* loadBMP(const char* filename) {
ifstream input;
input.open(filename, ifstream::binary);
assert(!input.fail() || !“Could not find file”);
char buffer[2];
input.read(buffer, 2);
assert(buffer[0] == ‘B’ && buffer[1] == ‘M’ || !“Not a bitmap file”);
input.ignore(8);
int dataOffset = readInt(input);
//Read the header
int headerSize = readInt(input);
int width;
int height;
switch(headerSize) {
case 40:
//V3
width = readInt(input);
height = readInt(input);
input.ignore(2);
assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");
assert(readShort(input) == 0 || !"Image is compressed");
break;
case 12:
//OS/2 V1
width = readShort(input);
height = readShort(input);
input.ignore(2);
assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");
break;
case 64:
//OS/2 V2
assert(!"Can't load OS/2 V2 bitmaps");
break;
case 108:
//Windows V4
assert(!"Can't load Windows V4 bitmaps");
break;
case 124:
//Windows V5
assert(!"Can't load Windows V5 bitmaps");
break;
default:
assert(!"Unknown bitmap format");
}
//Read the data
int bytesPerRow = ((width * 3 + 3) / 4) * 4 - (width * 3 % 4);
int size = bytesPerRow * height;
auto_array<char> pixels(new char[size]);
input.seekg(dataOffset, ios_base::beg);
input.read(pixels.get(), size);
//Get the data into the right format
auto_array<char> pixels2(new char[width * height * 3]);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
for(int c = 0; c < 3; c++) {
pixels2[3 * (width * y + x) + c] =
pixels[bytesPerRow * y + 3 * x + (2 - c)];
}
}
}
input.close();
return new Image(pixels2.release(), width, height);
}
// Image loader.h header file
#ifndef IMAGE_LOADER_H_INCLUDED
#define IMAGE_LOADER_H_INCLUDED
//Represents an image
class Image {
public:
Image(char* ps, int w, int h);
~Image();
/* An array of the form (R1, G1, B1, R2, G2, B2, ...) indicating the
* color of each pixel in image. Color components range from 0 to 255.
* The array starts the bottom-left pixel, then moves right to the end
* of the row, then moves up to the next column, and so on. This is the
* format in which OpenGL likes images.
*/
char* pixels;
int width;
int height;
};
//Reads a bitmap image from file.
Image* loadBMP(const char* filename);
#endif
// the below is the link of bmp image which i have used for this model
Regards