OpenGL のバックアップ(No.12)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- OpenGL へ行く。
- 1 (2005-05-22 (日) 00:31:38)
- 2 (2005-07-26 (火) 13:35:47)
- 3 (2005-08-11 (木) 02:50:46)
- 4 (2005-09-06 (火) 01:23:54)
- 5 (2005-10-07 (金) 16:46:19)
- 6 (2005-10-09 (日) 03:29:34)
- 7 (2005-11-06 (日) 04:37:11)
- 8 (2007-03-11 (日) 03:02:06)
- 9 (2007-03-11 (日) 03:02:06)
- 10 (2007-10-07 (日) 04:06:31)
- 11 (2007-10-07 (日) 16:27:41)
- 12 (2007-10-08 (月) 04:23:17)
- 13 (2007-10-08 (月) 04:23:17)
- 14 (2007-10-08 (月) 04:23:17)
- 15 (2007-10-08 (月) 22:54:14)
- 16 (2007-10-09 (火) 02:04:56)
- 17 (2007-10-09 (火) 02:04:56)
- 18 (2007-10-09 (火) 02:04:56)
- 19 (2007-10-09 (火) 02:04:56)
Silicon Graphics社が中心となって開発された、グラフィックス処理のためのプログラミングインターフェース(出典:IT用語辞典)。
MacOSXでOpenGLを使う
- xcodeを機動する。
- メニューの[ファイル][新規プロジェクト]から、[Application][Cocoa Application]を選択して[次へ]。
- プロジェクト名を「cocoaGL」にして[完了](ディレクトリはどこか適当な場所へ)。
- [グループとファイル]の[Frameworks][Linked Frameworks]を右クリックして、コンテキストメニューから[追加][既存のフレームワーク]を選択して、以下のフレームワークを追加する。
- OpenGL.framework
- GLUT.framework(必要であれば)
- 続いて、Interface Builderでの作業。
- [グループとファイル]の[Resources][MainMenu?.nib]をダブルクリックして、Interface Builderを機動。
- [MainMenu?.nib(English)]ウインドウの[Classes]タブを選択。
- [NSObject][NSResponder][NSView][NSOpenGLView]を右クリックして、コンテキストメニューから[SubClass? NSOpenGLView]を選択してNSOpenGLViewのサブクラスを作る。
- [MyOpenGLView]を右クリックして、コンテキストメニューから[Crate File for MyOpenGLView]を選択すると、xcodeのプロジェクトにMyOpenGLView.hとMyOpenGLView.mが作成される。
- [MainMenu?.nib(English)]ウインドウの[Instances]タブを選択して、[Window]アイコンをダブルクリックしてアプリケーションウインドウを表示する。
- メニューの[Tools][Palettes][Show Paletts]を選択して、パレットを表示する。
- パレットの[Cocoa-Containers]から[CustomView?]を選択して、先ほど開いたアプリケーションウインドウにドラッグ&ドロップする。
- メニューの[Tools][Show Inspector]を選択して、[Custom Class]から、先ほど作成したMyOpenGLViewを選択して、CustomView?にMyOpenGLViewを割り当てる。
- xcodeの作業に戻る。
- MyOpenGLView.hに次のコードを記述。
#import <Cocoa/Cocoa.h> #import <OpenGL/OpenGL.h> #import <OpenGL/gl.h> #import <OpenGL/glu.h> @interface MyOpenGLView : NSOpenGLView { NSTimer *timer; } - (void) awakeFromNib; - (id) initWithFrame:(NSRect)frameRect; - (void) reshape; - (void) loop; - (void) drawRect:(NSRect)rect; - (void) dealloc; @end
- MyOpenGLView.mに次のコードを記述。
#import "MyOpenGLView.h" @implementation MyOpenGLView - (void)awakeFromNib { timer = [ [ NSTimer scheduledTimerWithTimeInterval: 0.03 target:self selector:@selector(loop) userInfo:nil repeats:YES ] retain ]; } -(id)initWithFrame:(NSRect)frameRect { //OPEN GL draw context NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated, NSOpenGLPFAColorSize, 32.0, NSOpenGLPFADepthSize, 32.0, 0 }; NSOpenGLPixelFormat* pixFmt = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease]; self = [super initWithFrame:frameRect pixelFormat:pixFmt]; [ [ self openGLContext ] makeCurrentContext ]; return self; } - (void)loop { glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt( 0, 0, 1, 0, 0, 0, 0, 1, 0 ); // draw opengl [ [ self openGLContext ] flushBuffer ]; } - (void)drawRect:(NSRect)aRect { [self loop]; } - (void)reshape { NSRect bounds = [self bounds]; glViewport( (int)bounds.origin.x, (int)bounds.origin.y, (int)bounds.size.width, (int)bounds.size.height ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 45, (float)bounds.size.width / (float)bounds.size.height, 1.0, 500.0 ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } - (void) dealloc { [super dealloc]; } @end
- んで、[アクティブなビルド構成]で[Release]を選択して、ビルドして完了。
参考
MacOSX環境のOpenGLで日本語文字列の描画
詳しくは、GLTexString?.hとGLTexString?.mを参照。
こんな↓感じで、日本語文字列の描画が出来る。
GLTexString *texStr;
- (void)initGL {
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClearDepth( 1.0f );
glDisable(GL_CULL_FACE);
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
NSString *string = [NSString stringWithCString:"こんにちは、世界!"];
texStr = [[GLTexString alloc] initWithString:string];
}
- (void)loop {
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt( 0, 0, 8, 0, 0, 0, 0, 1, 0 );
glPushMatrix();
glTranslatef( -4.5, -0.5, 0 );
glColor3f( 1, 1, 1 );
[texStr draw];
glPopMatrix();
[ [ self openGLContext ] flushBuffer ];
}
GLTexString?.h
#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>
#import <OpenGL/OpenGL.h>
#define TEX_WIDTH 128
#define TEX_HEIGHT 128
#define FONT_NAME @"HiraKakuPro-W6"
/*
* HiraKakuPro-W3
* HiraKakuPro-W6
* HiraKakuStd-W8
* HiraMaruPro-W4
* HiraMinPro-W3
* HiraMinPro-W6
*/
@interface GLTexString : NSObject
{
NSString *string;
NSAttributedString *attrString;
GLuint *texId;
}
- (id) initWithString:(NSString*)aString;
- (void) draw;
- (void) dealloc;
@end
GLTexString?.m
#import "GLTexString.h"
@implementation GLTexString
- (id) initWithString:(NSString*)aString {
[super init];
int i, strSize;
float fontSize;
NSFont *font;
NSDictionary *attrsDictionary;
NSAttributedString *singleChar;
NSImage **images;
NSBitmapImageRep **imageReps;
NSImage* img;
NSPoint point;
NSSize size, screenResolution;
// copy to string from aString
string = [NSString stringWithString:aString];
// alloc texture id and image buffer
strSize = [string length];
texId = (GLuint*)malloc( sizeof(GLuint)*strSize );
images = (NSImage**)malloc( sizeof(NSImage*)*strSize );
imageReps = (NSBitmapImageRep**)malloc( sizeof(NSBitmapImageRep*)*strSize );
for( i = 0; i < strSize; i++ ){
images[i] = [[NSImage alloc] initWithSize:NSMakeSize( TEX_WIDTH, TEX_HEIGHT )];
}
// font settings
screenResolution = [[[[NSScreen mainScreen] deviceDescription] objectForKey:NSDeviceResolution] sizeValue];
fontSize = TEX_WIDTH * 72.0/screenResolution.width;
font = [NSFont fontWithName:FONT_NAME size:fontSize];
attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
font, NSFontAttributeName,
[NSColor whiteColor], NSForegroundColorAttributeName,
[NSColor clearColor], NSBackgroundColorAttributeName,
nil
];
// alloc attributed string
attrString = [[NSAttributedString alloc] initWithString:string attributes:attrsDictionary];
// create texture id
glEnable( GL_TEXTURE_2D );
glGenTextures( strSize, texId );
// build texture image
for( i = 0; i < strSize; i++ ){
img = images[i];
singleChar = [attrString attributedSubstringFromRange:NSMakeRange(i,1)];
// setting background color
[img setBackgroundColor:[NSColor clearColor]];
// calc center position
size = [singleChar size];
point = NSMakePoint( (TEX_WIDTH-size.width)/2, (TEX_HEIGHT-size.height)/2 );
// draw character to image
[img lockFocus];
[singleChar drawAtPoint:point];
[img unlockFocus];
// alloc bitmap image from NSImage
imageReps[i] = [[NSBitmapImageRep alloc] initWithData:[img TIFFRepresentation]];
// texture settings
glBindTexture( GL_TEXTURE_2D, texId[i] );
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
TEX_WIDTH, TEX_HEIGHT, 0,
[imageReps[i] hasAlpha] ? GL_RGBA :GL_RGB,
GL_UNSIGNED_BYTE,
[imageReps[i] bitmapData]
);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glBindTexture( GL_TEXTURE_2D, 0 );
}
glDisable( GL_TEXTURE_2D );
// release
for( i = 0; i < strSize; i++ ){
[imageReps[i] release];
[images[i] release];
}
free( imageReps );
free( images );
return self;
}
- (void) draw {
int i, strSize;
strSize = [string length];
glEnable( GL_TEXTURE_2D );
for( i = 0; i < strSize; i++ ){
glBindTexture( GL_TEXTURE_2D, texId[i] );
glBegin(GL_POLYGON);
glTexCoord2f( 0, 1 );
glVertex3f( i*1, 0, 0 );
glTexCoord2f( 1, 1 );
glVertex3f( i*1+1, 0, 0 );
glTexCoord2f( 1, 0 );
glVertex3f( i*1+1, 1, 0 );
glTexCoord2f( 0, 0 );
glVertex3f( i*1, 1, 0 );
glEnd();
}
glDisable( GL_TEXTURE_2D );
}
- (void) dealloc {
glDeleteTextures( [string length], texId );
free( texId );
[attrString release];
[super dealloc];
}
@end
GL_TEXTURE_RECTANGLE_EXTで、テクスチャに使う画像の幅・高さを任意のサイズに
// import library #import <OpenGL/gl.h> #import <OpenGL/glext.h> #import <OpenGL/OpenGL.h> // define (!)texture width and height are not 2^n. #define TEX_WIDTH 163 #define TEX_HEIGHT 97 // build texture glEnable( GL_TEXTURE_2D ); glEnable( GL_TEXTURE_RECTANGLE_EXT ); glBindTexture( GL_TEXTURE_RECTANGLE_EXT, textureId ); glTexImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapData ); glDisable( GL_TEXTURE_RECTANGLE_EXT ); glDisable( GL_TEXTURE_2D ); // draw glEnable( GL_TEXTURE_2D ); glEnable( GL_TEXTURE_RECTANGLE_EXT ); glBindTexture( GL_TEXTURE_RECTANGLE_EXT, textureId ); lBegin(GL_POLYGON); glTexCoord2f( 0, TEX_HEIGHT ); glVertex3f( 0, 0, 0 ); glTexCoord2f( TEX_WIDTH, TEX_HEIGHT ); glVertex3f( 1, 0, 0 ); glTexCoord2f( TEX_WIDTH, 0 ); glVertex3f( 1, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( 0, 1, 0 ); glEnd(); glDisable( GL_TEXTURE_RECTANGLE_EXT ); glDisable( GL_TEXTURE_2D );
参考
テクスチャ関連
テクスチャの置き換え
void glTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels );
アルファ値を利用したポリゴンの切り抜き
TGA画像の読み込み
#define TEX_HEIGHT 256
#define TEX_WIDTH 512
GLubyte image[TEX_HEIGHT][TEX_WIDTH][4];
void initTexture(void)
{
FILE *fp;
int x, z;
/* texture file open */
if((fp=fopen("test.tga", "rb"))==NULL){
fprintf(stderr, "texture file cannot open\n");
return;
}
fseek(fp, 18, SEEK_SET);
for(x=0;x<TEX_HEIGHT;x++){
for(z=0;z<TEX_WIDTH;z++){
image[x][z][2]=fgetc(fp);/* B */
image[x][z][1]=fgetc(fp);/* G */
image[x][z][0]=fgetc(fp);/* R */
image[x][z][3]=fgetc(fp);/* alpha */
}
}
fclose(fp);
}
RAW画像の読み込み
#define TEXWIDTH 256
#define TEXHEIGHT 256
GLubyte texture[TEXHEIGHT][TEXWIDTH][3];
void initTexture(void)
{
if ((fp = fopen("tire.raw", "rb")) != NULL) {
fread(texture, sizeof texture, 1, fp);
fclose(fp);
}
}
フォント関連
glutBitmapCharacter
※テクスチャが有効だと表示されないようだ。
void drawString( void* font, char* str ){
int i = 0;
while( str[i] != '\0' ){
glutBitmapCharacter( font, (int)('a') );
i++;
}
}
glDisable(GL_TEXTURE_2D); glColor3f( 1, 1, 1 ); glRasterPos3f( 0, 0, 0 ); drawString( GLUT_BITMAP_TIMES_ROMAN_10, "hello" );
- GLUT_BITMAP_8_BY_13
- GLUT_BITMAP_9_BY_15
- GLUT_BITMAP_TIMES_ROMAN_10
- GLUT_BITMAP_TIMES_ROMAN_24
- GLUT_BITMAP_HELVETICA_10
- GLUT_BITMAP_HELVETICA_12
- GLUT_BITMAP_HELVETICA_18
wglUseFontBitmap?, wglUseFontOutline?
Bitmap Font Builder
GLUT関連
フルスクリーンにする
glutFullScreen(); /* フルスクリーン表示 */
メモ
チュートリアル(入門にお奨め)
- GLUTによる「手抜き」OpenGL入門
- GLUT on MacOSX
- OpenGL入門
- OpenGL 入門講座
- NuWiki
- OpenGLプログラム
- Xcode on MacOS X 10.3でGLUTのコードをコンパイルする

