Tutorial memberi teksture pada sphere

on Sabtu, 12 Desember 2015
1. Bukalah codeblock kalian dan buat file seperti biasa.
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