#region OpenTK

OpenTKがGitHubで更新されるようになりました。NuGetから手に入れることができるようになりました。
現在は.NET Coreに対応する機運があるようです。

マルチテクスチャ

テクスチャを何枚も貼る

今までは、一枚のポリゴンには一枚のテクスチャを貼っていました。しかし、実際には複数枚貼る(マッピングを行う)こともできます。

一枚のポリゴンに複数のテクスチャを貼る技法をマルチテクスチャと呼びます。

今回はこれらの画像を重ねて表示させます。

Texture1Texture2Texture3

マルチテクスチャは重要!

MultiTexture
例だけ見れば、一枚のテクスチャが貼ってあるように見えますが…

ソースコードは、テクスチャを扱う部分が大きく変わりました。

※コードは明示しませんが、int型の配列(3個)である変数texturesを用意しています。

			//テクスチャ用バッファの生成
			GL.GenTextures(textures.Length, textures);

			for (int i = 0; i < textures.Length; i++)
			{
				//テクスチャ用バッファのひもづけ
				GL.BindTexture(TextureTarget.Texture2D, textures[i]);

				//テクスチャの設定
				GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
				GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);

				//picture.pngの読み込み
				Bitmap file = new Bitmap("02-06_picture[" + i + "].png");

				//png画像の反転を直す
				file.RotateFlip(RotateFlipType.RotateNoneFlipY);

				//データ読み込み
				BitmapData data = file.LockBits(new Rectangle(0, 0, file.Width, file.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

				//テクスチャ用バッファに色情報を流し込む
				GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
			}

複数枚のテクスチャ用バッファを同時に確保する場合は、GenTexturesを使います。

また、ひもづけ毎にテクスチャの設定(TexParameterなど)を行う必要があります。

			//各テクスチャユニットの設定
			GL.ActiveTexture(TextureUnit.Texture0);
			GL.BindTexture(TextureTarget.Texture2D, textures[0]);
			GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Decal);
			GL.Enable(EnableCap.Texture2D);

			GL.ActiveTexture(TextureUnit.Texture1);
			GL.BindTexture(TextureTarget.Texture2D, textures[1]);
			GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Decal);
			GL.Enable(EnableCap.Texture2D);

			GL.ActiveTexture(TextureUnit.Texture2);
			GL.BindTexture(TextureTarget.Texture2D, textures[2]);
			GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Decal);
			GL.Enable(EnableCap.Texture2D);

			//テクスチャユニットをデフォルトのものに設定
			GL.ActiveTexture(TextureUnit.Texture0);

テクスチャを一枚だけ使う場合は、ひもづけをするだけで終わっていました。しかし、マルチテクスチャの場合はテクスチャユニットというものを別に設定しなければなりません。

テクスチャユニットの設定手順は、ActiveTextureでユニットを選択し、テクスチャ用バッファをひも付けし、各種設定というものです。TexEnvだけではなくEnableまでユニット毎に分かれているので、注意する必要があります。Enableをコメントアウトして実行してみればよくわかるかと思います。

			//メインのポリゴン表示
			GL.Color4(Color4.White);
			GL.Begin(BeginMode.Quads);

			GL.MultiTexCoord2(TextureUnit.Texture0, 1.0, 1.0);
			GL.MultiTexCoord2(TextureUnit.Texture1, 1.0, 1.0);
			GL.MultiTexCoord2(TextureUnit.Texture2, 1.0, 1.0);
			GL.Vertex3(1, 1, 0);

			GL.MultiTexCoord2(TextureUnit.Texture0, 0.0, 1.0);
			GL.MultiTexCoord2(TextureUnit.Texture1, 0.0, 1.0);
			GL.MultiTexCoord2(TextureUnit.Texture2, 0.0, 1.0);
			GL.Vertex3(-1, 1, 0);
			
			GL.MultiTexCoord2(TextureUnit.Texture0, 0.0, 0.0);
			GL.MultiTexCoord2(TextureUnit.Texture1, 0.0, 0.0);
			GL.MultiTexCoord2(TextureUnit.Texture2, 0.0, 0.0);
			GL.Vertex3(-1, -1, 0);
			
			GL.MultiTexCoord2(TextureUnit.Texture0, 1.0, 0.0);
			GL.MultiTexCoord2(TextureUnit.Texture1, 1.0, 0.0);
			GL.MultiTexCoord2(TextureUnit.Texture2, 1.0, 0.0);
			GL.Vertex3(1, -1, 0);

			GL.End();

テクスチャを一枚だけ使う場合はTexCoord?を使っていましたが、マルチテクスチャの場合はMultiTexCoord?を使います。

MultiCoord?は、TexCoord?にテクスチャユニットを指定する引数を追加したものだと考えられます。ちなみに、テクスチャユニットのデフォルトがTexture0ということで、Texture0に対する指定はTexCoord?で指定できます。(やるべきではありませんが…)

記事

外部リンク

Thanks