概要
XamarinでiOS用のOpenGL描画システムを構築中です。
ポリゴン並びにテクスチャの描画で、作業が詰まってしまいました。
以下にプログラムソースの抜粋を記します。
変数定義
C#
1 private EAGLContext mContext = null; 2 3 private uint mFrameBuffer; 4 private uint mRenderBuffer; 5 6 private int mWidth = -1; 7 private int mHeight = -1; 8 private float mScreenScale = 1.0f; 9 10 private int[] mTextureID; 11 private NSData[] mTextureBitmap; 12 private int[,] mTextureSize; 13
描画処理本体
C#
1 public override void LayoutSubviews() 2 { 3 try 4 { 5 // 画面サイズの取得 6 CGRect size = UIScreen.MainScreen.Bounds; 7 mWidth = (int)size.Width; 8 mHeight = (int)size.Height; 9 10 // カレントコンテキストの設定 11 EAGLContext.SetCurrentContext(mContext); 12 GL.Oes.BindFramebuffer(All.FramebufferOes, mFrameBuffer); 13 14 // 描画の初期化 15 GL.Enable((All)EnableCap.Texture2D); 16 GL.Enable((All)EnableCap.AlphaTest); 17 GL.Enable((All)EnableCap.Blend); 18 GL.BlendFunc((All)BlendingFactorSrc.SrcAlphaSaturate, (All)BlendingFactorDest.OneMinusSrcAlpha); 19 20 // 黄色でクリア 21 GL.ClearColor(1.0f, 1.0f, 0.0f, 1.0f); 22 23 // バッファクリア 24 GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); 25 26 // テクスチャをアクティブ 27 GL.ActiveTexture(All.Texture0); 28 29 // ポリゴンの描画 30 DrawPolygon(0, 0, 100, 100, 1.0f, 0.0f, 0.0f, 1.0f); 31 32 // テクスチャの描画 33 BindTexture(0); 34 DrawTexture(0, 0, 0, mTextureSize[0, _X], mTextureSize[0, _Y], false); 35 36 GL.Oes.BindRenderbuffer(All.RenderbufferOes, mRenderBuffer); 37 mContext.PresentRenderBuffer((uint)All.RenderbufferOes); 38 } 39 catch (Exception e) 40 { 41 } 42 } 43
テクスチャ読み込み
C#
1 2 public void InitTexture(UIImage[] image, int start, int end) 3 { 4 int i; 5 int len = image.Length; 6 7 // 配列の初期化 8 mTextureID = new int[len]; 9 mTextureSize = new int[len, _XYWH]; 10 11 // テクスチャのワークを生成 12 GL.GenTextures(len, mTextureID); 13 14 // ゲーム用テクスチャイメージを取得 15 for (i = start; i < end; i++) 16 { 17 if (i >= len) continue; 18 19 CGDataProvider dp = image[i].CGImage.DataProvider; 20 NSData data = dp.CopyData(); 21 mTextureBitmap[i] = data; 22 23 mTextureSize[i, _X] = 0; 24 mTextureSize[i, _Y] = (int)image[i].CGImage.Height; 25 mTextureSize[i, _W] = (int)image[i].CGImage.Width; 26 mTextureSize[i, _H] = (int)-image[i].CGImage.Height; 27 28 GL.BindTexture(All.Texture2D, mTextureID[i]); 29 GL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)All.Nearest); 30 GL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)All.Nearest); 31 GL.TexImage2D(All.Texture2D, 0, (int)PixelInternalFormat.Palette8Rgba8Oes, mTextureSize[i, _X], mTextureSize[i, _Y], 0, 32 (All)OpenTK.Graphics.ES11.PixelFormat.Rgba, (All)PixelType.UnsignedShort4444, data.Bytes); 33 } 34 } 35
ポリゴン描画
C#
1 public void DrawPolygon(int _x, int _y, int _w, int _h, float rr, float gg, float bb, float aa) 2 { 3 int rx = (int)(((float)(_x - (mWidth / 2)) * mScreenScale) + (mWidth / 2)); 4 int ry = (int)(((float)(_y - (mHeight / 2)) * mScreenScale) + (mHeight / 2)); 5 int rw = (int)((float)_w * mScreenScale); 6 int rh = (int)((float)_h * mScreenScale); 7 8 GL.Disable((All)EnableCap.Texture2D); 9 GL.BindTexture(All.Texture2D, 0); 10 11 // ポリゴン描画 12 GL.Color4(rr, gg, bb, aa); 13 GL.VertexPointer(3, All.Float, 0, MakeVertexBuffer(rx, ry, rw, rh)); 14 GL.TexCoordPointer(2, All.Float, 0, MakeFullSizeUVBuffer()); 15 GL.DrawArrays(All.TriangleStrip, 0, 4); 16 17 // テクスチャを有効に戻す 18 GL.Enable((All)EnableCap.Texture2D); 19 } 20
テクスチャ描画
C#
1 public void DrawTexture(int id, float _x, float _y, float _w, float _h, bool isReverse, bool isAbsPos) 2 { 3 int rx, ry; 4 5 // 絶対座標かの判断 6 if (isAbsPos) 7 { 8 rx = (int)(_x); 9 ry = (int)(_y); 10 } 11 else 12 { 13 rx = (int)(((_x - (mWidth / 2)) * mScreenScale) + (mWidth / 2)); 14 ry = (int)(((_y - (mHeight / 2)) * mScreenScale) + (mHeight / 2)); 15 } 16 17 int rw = (int)((_w * mScreenScale)); 18 int rh = (int)((_h * mScreenScale)); 19 20 int[] tempRect = new int[_XYWH]; 21 tempRect[_X] = mTextureSize[id, _X]; 22 tempRect[_Y] = mTextureSize[id, _Y]; 23 tempRect[_W] = mTextureSize[id, _W]; 24 tempRect[_H] = mTextureSize[id, _H]; 25 26 // 左右反転処理 27 if (isReverse) 28 { 29 tempRect[_X] = tempRect[_W]; 30 tempRect[_W] *= -1; 31 } 32 33 // 切り出しサイズを設定 34 GL.TexParameterx(All.Texture2D, All.TextureCropRectOes, tempRect); 35 36 // 実描画 37 GL.Oes.DrawTex(rx, (mHeight - (ry + rh)), 0, rw, rh); 38 } 39
頂点バッファ、UVバッファの生成
C#
1 2 public float[] MakeVertexBuffer(int _x, int _y, int _w, int _h) 3 { 4 //ウィンドウ座標を正規化デバイス座標に変換 5 float left = ((float)_x / (float)mWidth ) * 2.0f - 1.0f; 6 float top = ((float)_y / (float)mHeight) * 2.0f - 1.0f; 7 float right = ((float)(_x + _w) / (float)mWidth ) * 2.0f - 1.0f; 8 float bottom = ((float)(_y + _h) / (float)mHeight) * 2.0f - 1.0f; 9 10 // 頂点バッファの生成 11 float[] vertexs = 12 { 13 left, top, 0.0f, //頂点0 14 left, bottom, 0.0f, //頂点1 15 right, top, 0.0f, //頂点2 16 right, bottom, 0.0f, //頂点3 17 }; 18 return MakeFloatBuffer(vertexs); 19 } 20 21 public float[] MakeFullSizeUVBuffer() 22 { 23 float[] fullSize = 24 { 25 0.0f, 0.0f, 26 0.0f, 1.0f, 27 1.0f, 0.0f, 28 1.0f, 1.0f, 29 }; 30 return MakeUVBuffer(fullSize); 31 } 32 33 public float[] MakeUVBuffer(float[] uv) 34 { 35 return MakeFloatBuffer(uv); 36 } 37 38 public float[] MakeFloatBuffer(float[] array) 39 { 40 return (array); 41 } 42
詳細
使用しているのは、OpenTK ES1.1です。
これらの元になるソースはAndroidでのOpenGLで基本的に動作した物で、それを移植した物になります。
なお、描画処理本体の『黄色でクリア』の部分までは正常に動作しており、背景は黄色で塗りつぶされています。
必要でしたら、バッファの生成の箇所もアップいたします。
iOSでの詳細な作法が解っていないため、足りない設定などがありましたら、ご指摘をよろしくお願いします。
補足
本プロジェクトは、ES1.1で制作することが前提となっています。
追記 テクスチャのバインド処理
C#
1 public void BindTexture(int id) 2 { 3 GL.BindTexture(All.Texture2D, mTextureID[id]); 4 }
追記 バッファ及びテクスチャの初期化
C#
1 public void CreateBuffer() 2 { 3 BackgroundColor = UIColor.Blue; 4 5 CGRect size = UIScreen.MainScreen.Bounds; 6 mWidth = (int)size.Width; 7 mHeight = (int)size.Height; 8 9 CAEAGLLayer layer = (CAEAGLLayer)Layer; 10 layer.Opaque = true; 11 12 // コンテキストの取得 13 mContext = new EAGLContext(EAGLRenderingAPI.OpenGLES1); 14 EAGLContext.SetCurrentContext(mContext); 15 16 GL.MatrixMode(All.Projection); 17 GL.LoadIdentity(); 18 19 // ビューポートの設定 20 GL.Viewport(0, 0, mWidth, mHeight); 21 GL.Scale(1.0f, -1.0f, 1.0f); // Y軸を反転させる 22 23 GL.Enable((All)EnableCap.Texture2D); 24 GL.Enable((All)EnableCap.AlphaTest); 25 GL.Enable((All)EnableCap.Blend); 26 27 GL.EnableClientState(All.VertexArray); 28 GL.EnableClientState(All.TextureCoordArray); 29 30 // カリング処理の設定 31 GL.Disable((All)EnableCap.CullFace); 32 GL.FrontFace((All)FrontFaceDirection.Cw); 33 34 // 描画バッファの設定 35 GL.Oes.GenFramebuffers(1, out mFrameBuffer); 36 GL.Oes.BindFramebuffer(All.FramebufferOes, mFrameBuffer); 37 38 GL.Oes.GenRenderbuffers(1, out mRenderBuffer); 39 GL.Oes.BindRenderbuffer(All.RenderbufferOes, mRenderBuffer); 40 41 GL.Oes.GetRenderbufferParameter(All.RenderbufferOes, All.RenderbufferWidthOes, out mWidth); 42 GL.Oes.GetRenderbufferParameter(All.RenderbufferOes, All.RenderbufferHeightOes, out mHeight); 43 44 mContext.RenderBufferStorage((uint)All.RenderbufferOes, layer); 45 GL.Oes.FramebufferRenderbuffer(All.FramebufferOes, All.ColorAttachment0Oes, All.RenderbufferOes, mRenderBuffer); 46 47 UIImage image = new UIImage("t_title_logo"); // "t_title_logo"はpngイメージ 48 UIImage[] ImageList = new UIImage[1]; 49 ImageList[0] = image; 50 InitTexture(ImageList, 0, 1); 51 } 52
回答3件
あなたの回答
tips
プレビュー