「DDS画像を表示する」の編集履歴(バックアップ)一覧はこちら
「DDS画像を表示する」(2015/01/03 (土) 22:04:27) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>DDS画像を読み込みます。<br />
DDS画像とは Direct Draw Surface ファイルの事です。<br />
GLEW を使うと S3TC(DXTC)圧縮 を解凍できるようです。<br />
↓こちらのサイトに読み込みプログラムがありましたので使わせて頂きます。</strong><br /><a href="http://asura.iaigiri.com/OpenGL/gl7.html"><strong>http://asura.iaigiri.com/OpenGL/gl7.html</strong></a><br /><strong>ちょこっと改変してGLEWの初期化位置を変えてみました。</strong></p>
<p> <img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=59&file=dds.png" /></p>
<table border="1" cellpadding="1" cellspacing="1" style="width:100px;"><tbody><tr><td>ファイル</td>
</tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=59&file=main.cpp">
main.cpp</a></td>
</tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=59&file=sample.dds">
sample.dds</a></td>
</tr></tbody></table><p>main.cpp</p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#pragma comment(lib, "glew32.lib")<br />
#include <GL/glew.h><br />
#include <GL/freeglut/freeglut.h><br />
#include <string></p>
<p>#define WIDTH 320<br />
#define HEIGHT 240<br />
//各種構造体<br />
typedef struct _DDPixelFormat<br />
{<br />
GLuint size;<br />
GLuint flgas;<br />
GLuint fourCC;<br />
GLuint bpp;<br />
GLuint redMask;<br />
GLuint greenMask;<br />
GLuint blueMask;<br />
GLuint alphaMask;<br />
} DDPixelFormat;</p>
<p>typedef struct _DDSCaps<br />
{<br />
GLuint caps;<br />
GLuint caps2;<br />
GLuint caps3;<br />
GLuint caps4;<br />
} DDSCaps;</p>
<p>typedef struct _DDColorKey<br />
{<br />
GLuint lowVal;<br />
GLuint highVal;<br />
} DDColorKey;</p>
<p>typedef struct _DDSurfaceDesc<br />
{<br />
GLuint size;<br />
GLuint flags;<br />
GLuint height;<br />
GLuint width;<br />
GLuint pitch;<br />
GLuint depth;<br />
GLuint mipMapLevels;<br />
GLuint alphaBitDepth;<br />
GLuint reserved;<br />
GLuint surface;</p>
<p> DDColorKey ckDestOverlay;<br />
DDColorKey ckDestBlt;<br />
DDColorKey ckSrcOverlay;<br />
DDColorKey ckSrcBlt;</p>
<p> DDPixelFormat format;<br />
DDSCaps caps;</p>
<p> GLuint textureStage;<br />
} DDSurfaceDesc;</p>
<p>//DDSクラス<br />
class DDSImage<br />
{<br />
protected:<br />
GLenum format;<br />
GLuint internalFormat;<br />
GLuint bpp;<br />
GLuint numMipmaps;<br />
public:<br />
GLuint ID;<br />
GLuint imageSize;<br />
GLubyte *imageData;<br />
GLuint width;<br />
GLuint height;<br />
DDSImage();<br />
~DDSImage();<br />
void DecompressDDS();<br />
bool ReadDDS(const char *filename);<br />
GLuint Load(const char *filename);<br />
};<br />
//コンストラクタ<br />
DDSImage::DDSImage()<br />
{<br />
imageSize = 0;<br />
imageData = NULL;<br />
format = GL_RGB;<br />
internalFormat = GL_RGB;<br />
width = 0;<br />
height = 0;<br />
bpp = 0;<br />
ID = 0;<br />
numMipmaps = 0;<br />
}<br />
//デストラクタ<br />
DDSImage::~DDSImage()<br />
{<br />
if ( imageData )<br />
{<br />
delete [] imageData;<br />
imageData = NULL;<br />
}<br />
}<br />
//DDSファイルの読み込み<br />
bool DDSImage::ReadDDS(const char *filename)<br />
{<br />
FILE *fp;<br />
char magic[4];<br />
int mipmapFactor;<br />
long curr, end;<br />
DDSurfaceDesc ddsd;<br />
// ファイルを開く<br />
fp = fopen(filename, "rb");<br />
if ( !fp )<br />
{<br />
printf("ファイルを開けませんでした\n");<br />
return false;<br />
}<br />
// マジックを読み取り<br />
fread(&magic, sizeof(char), 4, fp);<br />
// マジックをチェック<br />
if ( strncmp(magic, "DDS ", 4 ) != 0 )<br />
{<br />
printf("DDSファイルではありません\n");<br />
fclose(fp);<br />
return false;<br />
}<br />
// ヘッダーを読み取り<br />
fread(&ddsd, sizeof(ddsd), 1, fp);<br />
// 幅・高さを格納<br />
height = ddsd.height;<br />
width = ddsd.width;<br />
numMipmaps = ddsd.mipMapLevels;<br />
// フォーマット判別<br />
switch ( ddsd.format.fourCC )<br />
{<br />
case '1TXD':<br />
// DXT1<br />
format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;<br />
internalFormat = 3;<br />
mipmapFactor = 2;<br />
break;<br />
case '3TXD':<br />
// DXT3<br />
format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;<br />
internalFormat = 4;<br />
mipmapFactor = 4;<br />
break;<br />
case '5TXD':<br />
// DXT5<br />
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;<br />
internalFormat = 4;<br />
mipmapFactor = 4;<br />
break;<br />
default:<br />
printf("未対応の形式です\n");<br />
return false;<br />
}<br />
// テクセルデータのサイズを算出<br />
curr = ftell(fp);<br />
fseek(fp, 0, SEEK_END);<br />
end = ftell(fp);<br />
fseek(fp, curr, SEEK_SET);<br />
imageSize = end - curr;<br />
imageData = new GLubyte [imageSize];<br />
// ピクセルデータの読み込み<br />
fread(imageData, sizeof(GLubyte), imageSize, fp);<br />
// ファイルを閉じる<br />
fclose(fp);<br />
return true;<br />
}<br />
//S3TC圧縮の解凍作業<br />
void DDSImage::DecompressDDS()<br />
{<br />
int blockSize;<br />
int offset = 0;<br />
GLsizei mWidth = width, mHeight = height, mSize = 0;<br />
// DXT1<br />
if ( format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )<br />
blockSize = 8;<br />
// DXT3, DXT5<br />
else<br />
blockSize = 16;<br />
// 解凍<br />
for ( int i=0; i<(int)numMipmaps; i++ )<br />
{<br />
mSize = ( (mWidth+3)/4 ) * ( (mHeight+3)/4 ) * blockSize;<br />
glCompressedTexImage2D(GL_TEXTURE_2D, i, format, mWidth, mHeight, 0,
mSize, imageData + offset );<br />
if ( mWidth >> 1 ) mWidth = (mWidth >> 1);<br />
else mWidth = 1;<br />
if ( mHeight >> 1 ) mHeight = (mHeight >> 1);<br />
else mHeight = 1;<br />
offset += mSize;<br />
}<br />
}<br />
//DDSファイルを読み込み,テクスチャを生成する<br />
GLuint DDSImage::Load(const char *filename)<br />
{<br />
// ファイルの読み込み<br />
if ( !ReadDDS(filename) )<br />
return 0;<br />
// テクスチャを生成<br />
glGenTextures(1, &ID);<br />
// テクスチャをバインド<br />
glBindTexture(GL_TEXTURE_2D, ID);<br />
// 拡大・縮小する方法の指定<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);<br />
// テクスチャ環境の設定<br />
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);<br />
// 解凍作業<br />
DecompressDDS();<br />
if ( imageData )<br />
{<br />
delete [] imageData;<br />
imageData = NULL;<br />
}<br />
glBindTexture(GL_TEXTURE_2D, 0);<br />
// 生成したテクスチャ番号を返す<br />
return ID;<br />
}</p>
<p>DDSImage texture;<br />
void display(void)<br />
{<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);</p>
<p> glEnable(GL_TEXTURE_2D);//テクスチャ有効<br />
glBindTexture(GL_TEXTURE_2D, texture.ID);<br />
glEnable(GL_ALPHA_TEST);//アルファテスト開始<br />
glBegin(GL_POLYGON);<br />
glTexCoord2f(0.0f, 1.0f); glVertex2d(10 , 230);//左下<br />
glTexCoord2f(0.0f, 0.0f); glVertex2d(10 , 10);//左上<br />
glTexCoord2f(1.0f, 0.0f); glVertex2d( 310 , 10);//右上<br />
glTexCoord2f(1.0f, 1.0f); glVertex2d( 310 , 230);//右下<br />
glEnd();<br />
glDisable(GL_ALPHA_TEST);//アルファテスト終了<br />
glDisable(GL_TEXTURE_2D);//テクスチャ無効</p>
<p> glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
glutPostRedisplay();<br />
}<br />
void Init(){<br />
//GLEWの初期化<br />
if(glewInit() != GLEW_OK)printf("GLEWの初期化に失敗しました\n");<br />
glClearColor(0.0, 0.0, 0.0, 1.0);<br />
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);<br />
texture.Load("sample.dds");<br />
}<br />
int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("画像を読み込んで表示");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
</td>
</tr></tbody></table><p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p><strong>DDS画像を読み込みます。<br />
DDS画像とは Direct Draw Surface ファイルの事です。<br />
GLEW を使うと S3TC(DXTC)圧縮 を解凍できるようです。<br />
↓こちらのサイトに読み込みプログラムがありましたので使わせて頂きます。</strong><br /><a href="http://asura.iaigiri.com/OpenGL/gl7.html"><strong>http://asura.iaigiri.com/OpenGL/gl7.html</strong></a><br /><strong>ちょこっと改変してGLEWの初期化位置を変えてみました。</strong></p>
<p> <img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=59&file=dx.png" /></p>
<table border="1" cellpadding="1" cellspacing="1" style="width:100px;"><tbody><tr><td>ファイル</td>
</tr><tr><td><a href="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=59&file=main.cpp">
main.cpp</a></td>
</tr><tr><td><a href="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=59&file=sample.dds">
sample.dds</a></td>
</tr></tbody></table><p>main.cpp</p>
<table border="1" cellpadding="1" cellspacing="1" width="600"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#pragma comment(lib, "glew32.lib")<br />
#include <GL/glew.h><br />
#include <GL/freeglut/freeglut.h><br />
#include <string></p>
<p>#define WIDTH 320<br />
#define HEIGHT 240<br />
//各種構造体<br />
typedef struct _DDPixelFormat<br />
{<br />
GLuint size;<br />
GLuint flgas;<br />
GLuint fourCC;<br />
GLuint bpp;<br />
GLuint redMask;<br />
GLuint greenMask;<br />
GLuint blueMask;<br />
GLuint alphaMask;<br />
} DDPixelFormat;</p>
<p>typedef struct _DDSCaps<br />
{<br />
GLuint caps;<br />
GLuint caps2;<br />
GLuint caps3;<br />
GLuint caps4;<br />
} DDSCaps;</p>
<p>typedef struct _DDColorKey<br />
{<br />
GLuint lowVal;<br />
GLuint highVal;<br />
} DDColorKey;</p>
<p>typedef struct _DDSurfaceDesc<br />
{<br />
GLuint size;<br />
GLuint flags;<br />
GLuint height;<br />
GLuint width;<br />
GLuint pitch;<br />
GLuint depth;<br />
GLuint mipMapLevels;<br />
GLuint alphaBitDepth;<br />
GLuint reserved;<br />
GLuint surface;</p>
<p> DDColorKey ckDestOverlay;<br />
DDColorKey ckDestBlt;<br />
DDColorKey ckSrcOverlay;<br />
DDColorKey ckSrcBlt;</p>
<p> DDPixelFormat format;<br />
DDSCaps caps;</p>
<p> GLuint textureStage;<br />
} DDSurfaceDesc;</p>
<p>//DDSクラス<br />
class DDSImage<br />
{<br />
protected:<br />
GLenum format;<br />
GLuint internalFormat;<br />
GLuint bpp;<br />
GLuint numMipmaps;<br />
public:<br />
GLuint ID;<br />
GLuint imageSize;<br />
GLubyte *imageData;<br />
GLuint width;<br />
GLuint height;<br />
DDSImage();<br />
~DDSImage();<br />
void DecompressDDS();<br />
bool ReadDDS(const char *filename);<br />
GLuint Load(const char *filename);<br />
};<br />
//コンストラクタ<br />
DDSImage::DDSImage()<br />
{<br />
imageSize = 0;<br />
imageData = NULL;<br />
format = GL_RGB;<br />
internalFormat = GL_RGB;<br />
width = 0;<br />
height = 0;<br />
bpp = 0;<br />
ID = 0;<br />
numMipmaps = 0;<br />
}<br />
//デストラクタ<br />
DDSImage::~DDSImage()<br />
{<br />
if ( imageData )<br />
{<br />
delete [] imageData;<br />
imageData = NULL;<br />
}<br />
}<br />
//DDSファイルの読み込み<br />
bool DDSImage::ReadDDS(const char *filename)<br />
{<br />
FILE *fp;<br />
char magic[4];<br />
int mipmapFactor;<br />
long curr, end;<br />
DDSurfaceDesc ddsd;<br />
// ファイルを開く<br />
fp = fopen(filename, "rb");<br />
if ( !fp )<br />
{<br />
printf("ファイルを開けませんでした\n");<br />
return false;<br />
}<br />
// マジックを読み取り<br />
fread(&magic, sizeof(char), 4, fp);<br />
// マジックをチェック<br />
if ( strncmp(magic, "DDS ", 4 ) != 0 )<br />
{<br />
printf("DDSファイルではありません\n");<br />
fclose(fp);<br />
return false;<br />
}<br />
// ヘッダーを読み取り<br />
fread(&ddsd, sizeof(ddsd), 1, fp);<br />
// 幅・高さを格納<br />
height = ddsd.height;<br />
width = ddsd.width;<br />
numMipmaps = ddsd.mipMapLevels;<br />
// フォーマット判別<br />
switch ( ddsd.format.fourCC )<br />
{<br />
case '1TXD':<br />
// DXT1<br />
format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;<br />
internalFormat = 3;<br />
mipmapFactor = 2;<br />
break;<br />
case '3TXD':<br />
// DXT3<br />
format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;<br />
internalFormat = 4;<br />
mipmapFactor = 4;<br />
break;<br />
case '5TXD':<br />
// DXT5<br />
format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;<br />
internalFormat = 4;<br />
mipmapFactor = 4;<br />
break;<br />
default:<br />
printf("未対応の形式です\n");<br />
return false;<br />
}<br />
// テクセルデータのサイズを算出<br />
curr = ftell(fp);<br />
fseek(fp, 0, SEEK_END);<br />
end = ftell(fp);<br />
fseek(fp, curr, SEEK_SET);<br />
imageSize = end - curr;<br />
imageData = new GLubyte [imageSize];<br />
// ピクセルデータの読み込み<br />
fread(imageData, sizeof(GLubyte), imageSize, fp);<br />
// ファイルを閉じる<br />
fclose(fp);<br />
return true;<br />
}<br />
//S3TC圧縮の解凍作業<br />
void DDSImage::DecompressDDS()<br />
{<br />
int blockSize;<br />
int offset = 0;<br />
GLsizei mWidth = width, mHeight = height, mSize = 0;<br />
// DXT1<br />
if ( format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )<br />
blockSize = 8;<br />
// DXT3, DXT5<br />
else<br />
blockSize = 16;<br />
// 解凍<br />
for ( int i=0; i<(int)numMipmaps; i++ )<br />
{<br />
mSize = ( (mWidth+3)/4 ) * ( (mHeight+3)/4 ) * blockSize;<br />
glCompressedTexImage2D(GL_TEXTURE_2D, i, format, mWidth, mHeight, 0,
mSize, imageData + offset );<br />
if ( mWidth >> 1 ) mWidth = (mWidth >> 1);<br />
else mWidth = 1;<br />
if ( mHeight >> 1 ) mHeight = (mHeight >> 1);<br />
else mHeight = 1;<br />
offset += mSize;<br />
}<br />
}<br />
//DDSファイルを読み込み,テクスチャを生成する<br />
GLuint DDSImage::Load(const char *filename)<br />
{<br />
// ファイルの読み込み<br />
if ( !ReadDDS(filename) )<br />
return 0;<br />
// テクスチャを生成<br />
glGenTextures(1, &ID);<br />
// テクスチャをバインド<br />
glBindTexture(GL_TEXTURE_2D, ID);<br />
// 拡大・縮小する方法の指定<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);<br />
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);<br />
// テクスチャ環境の設定<br />
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);<br />
// 解凍作業<br />
DecompressDDS();<br />
if ( imageData )<br />
{<br />
delete [] imageData;<br />
imageData = NULL;<br />
}<br />
glBindTexture(GL_TEXTURE_2D, 0);<br />
// 生成したテクスチャ番号を返す<br />
return ID;<br />
}</p>
<p>DDSImage texture;<br />
void display(void)<br />
{<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);</p>
<p> glEnable(GL_TEXTURE_2D);//テクスチャ有効<br />
glBindTexture(GL_TEXTURE_2D, texture.ID);<br />
glEnable(GL_ALPHA_TEST);//アルファテスト開始<br />
glBegin(GL_POLYGON);<br />
glTexCoord2f(0.0f, 1.0f); glVertex2d(10 , 230);//左下<br />
glTexCoord2f(0.0f, 0.0f); glVertex2d(10 , 10);//左上<br />
glTexCoord2f(1.0f, 0.0f); glVertex2d( 310 , 10);//右上<br />
glTexCoord2f(1.0f, 1.0f); glVertex2d( 310 , 230);//右下<br />
glEnd();<br />
glDisable(GL_ALPHA_TEST);//アルファテスト終了<br />
glDisable(GL_TEXTURE_2D);//テクスチャ無効</p>
<p> glutSwapBuffers();<br />
}<br />
void idle(void)<br />
{<br />
glutPostRedisplay();<br />
}<br />
void Init(){<br />
//GLEWの初期化<br />
if(glewInit() != GLEW_OK)printf("GLEWの初期化に失敗しました\n");<br />
glClearColor(0.0, 0.0, 0.0, 1.0);<br />
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);<br />
texture.Load("sample.dds");<br />
}<br />
int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("画像を読み込んで表示");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
</td>
</tr></tbody></table><p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>