[ Main Page ]

SDL_imageをOpenGLのTextureで利用する

OpenGL(GL/GLU/GLUT)自体は、殆んどの画像フォーマットをサポートしていないので、 Textureの読込みは骨が折れます。そこで、 OpenGLとSDLの連携 を参考にして、SDLで様々な画像をTextureとして読み込む例を挙げてみます。

TextureImage.h

#ifndef TEXTUREIMAGE_H
#define TEXTUREIMAGE_H

#include <iostream>
#include <GL/glut.h>
#include <SDL/SDL_image.h>
#include <vector>
#include <map>
#include <string>

typedef struct{
  std::string filename;
  GLuint textureID;
  int width;
  int height;
} TextureInfo;

class TextureImage
{
  private:
  std::map<std::string, TextureInfo> Textures;
  public:
  int loadImage(char * filename);
  TextureInfo * getTexture(char * filename);
};

#endif
      

TextureImage.cpp

#include "TextureImage.h"
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int TextureImage::loadImage(char *filename)
{
  SDL_Surface *Image = NULL;
  SDL_Surface *tmpImage;
  GLuint texID = 0;
  TextureInfo texture;

  if(Image = IMG_Load(filename))
  {
    tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, 32, 
        0x000000ff, 
        0x0000ff00, 
        0x00ff0000, 
        0xff000000);
    Image = SDL_ConvertSurface(Image, tmpImage->format, SDL_SWSURFACE);
    SDL_FreeSurface(tmpImage);

    glGenTextures(1, &texID);
    glBindTexture(GL_TEXTURE_2D, texID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // これだと規定のサイズの画像しか読み込めない
    /* glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Image->w, Image->h, 0,
        GL_RGBA, GL_UNSIGNED_BYTE, Image->pixels); */

    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Image->w, Image->h,
        GL_RGBA, GL_UNSIGNED_BYTE, Image->pixels);

    SDL_FreeSurface(Image);

    texture.filename = filename;
    texture.textureID = texID;
    texture.width = Image->w;
    texture.height = Image->h;
    Textures.insert(std::pair<std::string, TextureInfo>(filename, texture));
    return 0;
  }
  return -1;
}

TextureInfo * TextureImage::getTexture(char *filename)
{
  std::map<std::string, TextureInfo>::iterator i = Textures.find(filename);
  if(i != Textures.end())
    {
      return &(i->second);
    }
  if(loadImage(filename) == 0)
    {
      return getTexture(filename);
    }
  return NULL;
}
      

glTexImage2Dの代わりにgluBuild2DMipmapsを使えば、画像Pixelサイズに 左右されずに詠みこめる筈です。もっとも、最近のOpenGLでは、 その問題は解消されたようですが。あとは、以下のようにすれば 一応Textureは使える筈です。

#include "TextureImage.h"
...
TextureImage *texture;
...
texture = new TextureImage();
...
void display(void)
{
  TextureInfo * tex;

  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glRotated(1.1, 0.0, 1.0, 0.0);

  glEnable(GL_LINE_SMOOTH);  
  glEnable(GL_DEPTH_TEST);

  glEnable(GL_TEXTURE_2D);
  if((tex = texture->getTexture("sample.gif")) == NULL)
    exit(-1);
  glBindTexture(GL_TEXTURE_2D, tex->textureID);
  glBegin(GL_POLYGON);
  glTexCoord2f(0, 1);
  glVertex2f(0, 0);
  glTexCoord2f(0, 0);
  glVertex2f(0, tex->height/100);
  glTexCoord2f(1, 0);
  glVertex2f(tex->width/100, tex->height/100);
  glTexCoord2f(1, 1);
  glVertex2f(tex->width/100, 0);
  glEnd();
  glDisable(GL_TEXTURE_2D);

  glEnable(GL_TEXTURE_2D);
  // エラーチェックなし
  glBindTexture(GL_TEXTURE_2D, texture->getTexture("tiles.png")->textureID);
  glBegin(GL_POLYGON);
  glTexCoord2f(0 , 0); glVertex3f(-4.9 ,1,3);
  glTexCoord2f(0 , 1); glVertex3f(-4.9 ,1,-3);
  glTexCoord2f(1 , 1); glVertex3f(3.9 , 1,-3);
  glTexCoord2f(1 , 0); glVertex3f(3.9 , 1,3);
  glEnd();
  glDisable(GL_TEXTURE_2D);
  ...
  glutSwapBuffers();
}
...
      

-lSDL -lSDL_imageをリンクすればいい筈です。

There is no IGLU Cabal. Shlomi Fish has obtained a patent on certain key
technologies essential for existence of IGLU Cabals. He is available for
license negotiations only on February 29th of odd-numbered years, between the
hours 14:15:09-18:28:18.

People, who practice IGLU Cabalism without the appropriate patent licenses,
risk teleportation into the interior of exploding supernovae.

Omer Zak in Hackers-IL message No. 1968
(Re: A TINIC Sequel)

    -- Omer Zak
    -- Hackers-IL
                Message No. 1968 ( http://tech.groups.yahoo.com/group/hackers-il/message/1968 )

Last week, Microsoft published the binary file formats for Office. These
formats appear to be almost completely insane. The Excel 97-2003 file format
is a 349 page PDF file. But wait, thats not all there is to it! This document
includes the following interesting comment:

Each Excel workbook is stored in a compound file.

You see, Excel 97-2003 files are OLE compound documents, which are,
essentially, file systems inside a single file. These are sufficiently
complicated that you have to read another 9 page spec to figure that out. And
these specs look more like C data structures than what we traditionally
think of as a spec. It's a whole hierarchical file system.

If you started reading these documents with the hope of spending a weekend
writing some spiffy code that imports Word documents into your blog system, or
creates Excel-formatted spreadsheets with your personal finance data, the
complexity and length of the spec probably cured you of that desire pretty
darn quickly. A normal programmer would conclude that Offices binary file
formats:

* are deliberately obfuscated

* are the product of a demented Borg mind

* were created by insanely bad programmers

* and are impossible to read or create correctly.

    -- Joel Spolsky
    -- Blog entry for 19 February 2008 ( http://www.joelonsoftware.com/items/2008/02/19.html )


Powered by UNIX fortune(6)
[ Main Page ]