ページ 11

OpenGLESでポリゴンを描画する方法について

Posted: 2011年3月17日(木) 21:42
by 初心者
初めて利用させていただきます。

現在MacOSXでXcode3.2.5を使用して、
OpenGLESを使ったiPhoneアプリを作ろうとしています。

アプリの処理でポリゴンを描画する機能を実装しようとしているのですが
複数個のポリゴンを描画することができずにいます。
(一つなら出来ています。)

コードはサンプルコードとして知人からいただいたものを
流用して作っているところなのですが
その知人が音信不通になり、自分一人では手詰まりになって
ここに行き着きました。

やりたいことは複数(3つ)のポリゴンを同一の画面内に描画することです。
1つなら出来ているので、今出来ている部分のソースを貼らせていただきます。

ES1Renderer.m内

コード:

const GLfloat fSizeX = 3.5f*5.0f*0.3f;
const GLfloat fSizeY = 4.5f;

- (id) init
{
	if (self = [super init])
	{
		context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
        
        if (!context || ![EAGLContext setCurrentContext:context])
		{
            [self release];
            return nil;
        }

		glGenFramebuffersOES(1, &defaultFramebuffer);
		glGenRenderbuffersOES(1, &colorRenderbuffer);
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
	}
	return self;
}

- (void) render
{
    [EAGLContext setCurrentContext:context];

    //ポリゴンを作成する関数    
    [self drawMapPolygon];

    //ここで二つ目のポリゴンを描画する関数を呼ぼうとしています
    //[self drawMapPolygon2];

    [context presentRenderbuffer:GL_RENDERBUFFER_OES];		
}

-(void)drawMapPolygon
{
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

	glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

	glFrustumf(-1.0f, 1.0f, -2.0f, 2.0f, 0.1f, 100.0f);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

	// ポリゴンの色は白で透過
    static const GLubyte squareColors[] = {
		255, 255, 255, 0,
		255, 255, 255, 0,
		255, 255, 255, 0,
		255, 255, 255, 0,
	};
	
	// 矩形の座標
	GLint nSize = 10;
	GLfloat squareVertices[] = {
		-fSizeY*nSize, 0.0 , -fSizeX*0.7*nSize, // 左下の座標
		 fSizeY*nSize, 0.0 , -fSizeX*0.7*nSize, // 右下の座標
		-fSizeY*nSize, 0.0 ,  fSizeX*0.7*nSize, // 左上の座標
		 fSizeY*nSize, 0.0 , fSizeX*0.7*nSize, // 右上の座標
	};
	
	// 配列につめた点が3つ区切りを示す
	glVertexPointer(3, GL_FLOAT, 0, squareVertices);
	// 配列につめた点が4つ区切りを示す
	glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
	
	// 配列を有効にする
	glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);
	
	// ポリゴンの移動処理
	glTranslatef(m_fMoveX,m_fMoveY,0.0f);	
	// 見た目の設定(さらに移動)
	glTranslatef(0.0f,-15.2f,-0.5f);

	// テクスチャ関連 開始
	const GLfloat texCoords[] = {
		0.0f, 1.0f,
		1.0f, 1.0f,
		0.0f, 0.0f,
		1.0f, 0.0f,		
	};
	glTexCoordPointer(2,GL_FLOAT, 0, texCoords);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, earthTexture);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	// テクスチャ関連 終了
	
	// 描画
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glViewport(0, 0, 320, 480);

	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisable(GL_TEXTURE_2D);
}

-(void)drawMapPolygon2
{
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

	glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);

	// ポリゴンの色は白で透過
    static const GLubyte squareColors[] = {
		255, 255, 255, 0,
		255, 255, 255, 0,
		255, 255, 255, 0,
		255, 255, 255, 0,
	};
	
	// 矩形の座標
	GLint nSize = 10;
	GLfloat squareVertices[] = {
		-fSizeY*nSize, 0.0 , -fSizeX*0.7*nSize, // 左下の座標
		 fSizeY*nSize, 0.0 , -fSizeX*0.7*nSize, // 右下の座標
		-fSizeY*nSize, 0.0 ,  fSizeX*0.7*nSize, // 左上の座標
		 fSizeY*nSize, 0.0 , fSizeX*0.7*nSize, // 右上の座標
	};
	
	// 配列につめた点が3つ区切りを示す
	glVertexPointer(3, GL_FLOAT, 0, squareVertices);
	// 配列につめた点が4つ区切りを示す
	glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
	
	// 配列を有効にする
	glEnableClientState(GL_COLOR_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);
	
	// ポリゴンの移動処理
	glTranslatef(0.0f,-15.2f,-0.5f);

	// 描画
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glViewport(0, 300, 120, 100);

	glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisable(GL_TEXTURE_2D);
}
drawMapPolygon2という関数はdrawMapPolygonから作成し、
ポリゴンが配置される位置関係を1つ目のポリゴンとは変えたいと思ったため
glViewportの値を変更しました。
位置関係としては、1つ目を画面いっぱいに表示して、
その足下に矩形を二つほど用意したいと考えています。

また、1つ目のポリゴンにはテクスチャを貼るつもりですが
2つ目には色を付けての表示にしてテクスチャは貼らないつもりです。

このままだと実際にdrawMapPolygon2のコメントを外して動かすと
どちらも描画されなくなります。
コメントをどちらかにつけてあれば、
コメントアウトされていない方が表示されるところまではわかっています。

まだCの経験も浅く、OpenGLESもはっきり言ってよくわからないことだらけで
自分で調べて、こういう意味かと思ったものをコメントに書いております。

見苦しいコードかと思いますが、お気づきの点をご指摘いただけると幸いです。
修正すべき箇所や、サンプルコードが乗っている、参照すべきサイトなどありましたら
ご教授のほど、よろしくお願いいたします。

Re: OpenGLESでポリゴンを描画する方法について

Posted: 2011年3月21日(月) 03:32
by しひ
Objective-CもOpenGLESも知らないので、C++とOpenGLの知識だけで答えます。
間違っているかもしれません。

1つめ、glViewPort()の使い方が違います。ビューポートについて調べてみて下さい。
ポリゴンの移動はglTranslatef()で行って下さい。

2つめ、glFrustumf()の使い方も違う気がします。自信はないです。
射影変換について調べてみて下さい。

3つめ、glClear()を複数回呼ばないで下さい。
これは画面を初期化する関数ですので、ポリゴン描く度に初期化を掛けていたら前に描いたポリゴンが消えてしまいます。
ループ中で一回だけ呼ぶようにして下さい。

ひとまず、以上の点を直してみて下さい。