画像に指定の色を重ね合わせて描画

Android用2Dゲームで画像を高速で描画するために、
OpenGL ESのDraw Texture Extensionが使用できる。
基本的な使い方はこの本のサンプルコードあたりが参考になる。

初歩からわかるAndroid最新プログラミング

元画像…というかテクスチャの、「どの部分を切り取って使うか」が
int型でimgX,imgY,imgW,imgHと与えられているとする。
そして切り取った画像を画面上のどの位置に配置するかが
float型でx,yと与えられているとする。拡大縮小もできるけどここでは省略。

そうすると、普通にDraw Texture Extensionを使って描画する場合は

// 元画像からトリミング
int[ ] rect = { imgX, imgY+imgH, imgW, -imgH };
((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
    GL11Ext.GL_TEXTURE_CROP_RECT_OES, rect, 0);

// 色は変えない
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);

// 描画
((GL11Ext) gl).glDrawTexfOES(x,y,0.0f,(float)imgW,(float)imgH);


となる。


で、ここから本題。
光る表現なんかのために、画像に任意の色を重ね合わせて描画したいときがある。
白色以外の光源が当てられていると言えばいいのか。
こんな感じ。

f:id:boredbone:20140105223959p:plain


重ね合わせる色とその透明度が
float型でR,G,B,Aと与えられているとする。
たとえば上の画像なら、R=1.0f,G=0.0f,B=0.0f,A=0.5fとか。


テクスチャのトリミングまでは同じ。
で、まず混合する色の方を先に描画する。

    // 色をセット
	gl.glColor4f(R,G,B,1.0f);

	// テクスチャアルファをブレンドに
	gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_BLEND);


	// 混合する色の設定 
	float[] color={R,G,B,1.0f};
	gl.glTexEnvfv(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_COLOR, color,0);


	//設定色だけで描画
	((GL11Ext) gl).glDrawTexfOES(x,y,0.0f,(float)imgW,(float)imgH);


こうすると、画像の透明部分以外が色(R,G,B)で塗られて描画される。
影の描画なんかにも使えそう。


この上に、オリジナルの画像を透かして描画する。

    //オリジナル画像を透かして描画
	gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_MODULATE);
	gl.glColor4f(1.0f,1.0f,1.0f,A);

	((GL11Ext) gl).glDrawTexfOES(x,y,0.0f,(float)imgW,(float)imgH);


glTexEnvfで乗算を指定してやるとα成分が掛け合わされて、
オリジナル画像が指定した色にほんのり色づいて見える。
色変化の度合いは透明度パラメータAで変えられる。
A=1.0fなら普通に描画するのと同じ、A=0.0fなら指定した色だけでベタ塗り。


引き続き普通に画像の描画を行う際は、合成方法を元に戻しておく。

    gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
		GL10.GL_REPLACE);