2. Lalu buatlah file imageloader.h untuk fungsi me load gambar jenis bmp, source codenya seperti dibawah ini
#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
3. Lalu buat file imageloader.cpp nya
#include#include #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 auto_array { private: T* array; mutable bool isReleased; public: explicit auto_array(T* array_ = NULL) : array(array_), isReleased(false) { } auto_array(const auto_array &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 &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 pixels(new char[size]); input.seekg(dataOffset, ios_base::beg); input.read(pixels.get(), size); //Get the data into the right format auto_array 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); }
4.Setelah tahap itu buatlah main.cpp yang berisi, dan tampilannya sebagai berikut
#include#include #include #include #include "imageloader.h" using namespace std; void handleKeypress(unsigned char key, int x, int y) { switch (key) { case 27: //Escape key exit(0); } }
//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 textur GLUquadric *quad; float rotate;
void initRendering() { glEnable(GL_DEPTH_TEST); //glEnable(GL_LIGHTING); //glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); quad = gluNewQuadric(); }
void handleResize(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0); }
void drawScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, 1.0f, -16.0f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, _textureId); //Bottom 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); glRotatef(90,1.0f,0.0f,0.0f); glRotatef(rotate,0.0f,0.0f,1.0f); gluQuadricTexture(quad,1); gluSphere(quad,2,20,20); glutSwapBuffers(); }
void update(int value) { rotate+=2.0f; if(rotate>360.f) { rotate-=360; } glutPostRedisplay(); glutTimerFunc(25,update,0); }
int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 800); glutCreateWindow("Textures"); initRendering(); glutTimerFunc(25,update,0); glutDisplayFunc(drawScene); glutKeyboardFunc(handleKeypress); glutReshapeFunc(handleResize); glutMainLoop(); return 0; }maka tampilannya akan seperti berikut
5. Tambahkan fungsi berikut pada void initRendering(), simpan di paling bawah void tersebut
Image* image = loadBMP("D:\\bumi.bmp"); _textureId = loadTexture(image); delete image;maka tampilannya akan seperti berikut
download file untuk gambarnya disini yah Click here
Simpan file bumi.bmp nya di direktori D:
0 komentar:
Posting Komentar