OpenGL(GL/GLU/GLUT)自体は、殆んどの画像フォーマットをサポートしていないので、 Textureの読込みは骨が折れます。そこで、 OpenGLとSDLの連携 を参考にして、SDLで様々な画像をTextureとして読み込む例を挙げてみます。
#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
#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 hunting like the hunting of man, and those who have hunted
armed men long enough and liked it, never care for anything else thereafter.
-- Ernest Hemingway
<WebDragon> y'all should spell it in uppercase it being an acronym and
all
<reaction> Yes, but we're *lazy*!
* WebDragon *so* noticed ;)
<dkr> WebDragon: people that use CamelCase have no right to
criticize about capitalization. :)
<WebDragon> dkr: I hate underscores
* dkr contemplates a source code filter that does lets you use
spaces in var names by switch them to underscores at compile
time
<preaction> black magic
<mst> dkr: source filters are evil.
<mst> dkr: in a bad way.
<mst> dkr: hacking the compiler is much more fun, and evil in a
useful way :)
<mst> WebDragon: recommended perl style is $var_name
<mst> WebDragon: it's also more readable than $varName or $VarName
<mst> WebDragon: I'd recommend trying it for at least a month
<mst> WebDragon: also note that it'll make life easier because
you'll be consistent with the rest of perl code
<WebDragon> mst: I was thinking more along the lines of filenames and
irc nicknames than perl variables
<mst> WebDragon: ah. fair enough :)
* WebDragon doesn't use camelcase for perlvars
<mst> WebDragon: then I shall cease complaining :)
<avar> ${"Insert a descriptive essay about the variable here"}
<WebDragon> rofl
<rindolf> avar: that won't work with 'use strict 'refs''
<WebDragon> avar: I've seen things like that in RL and had recurring
nightmares about them when I saw similar and sometimes worse
things on thedailywtf.com
<mst> rindolf: ${main::}{"Insert a descriptive essay about the
variable here"} would :)
<mst> rindolf: or you could just use %_ :)
<dkr> my boss still occasionally uses vars like $x. still trying
to beat that behavior out of him
* WebDragon only uses x|y|z for cartesian coordinate math
<WebDragon> which, since I hardly ever do any of that, means the obvious
-- What's in a variable name?
-- #perl, Freenode