1

私は2つのVBOを持っています。1 つにはテクスチャがあり、もう 1 つにはありません。それらを同時に画面に描画することに成功しません。DrawQuad はテクスチャのないものを描画し、DrawQuadTex はテクスチャのあるものを描画します。両方とも以下のようなコードを使用します。

// Enable/Disable GL_TEXTURE_2D depending on which I'm drawing
// Bind/Unbind the texture

GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferId);
GL.VertexPointer(2, VertexPointerType.Float, Vector2.SizeInBytes, IntPtr.Zero);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBufferId);

GL.DrawElements(BeginMode.Triangles, _indices.Length, DrawElementsType.UnsignedByte, 0);

これら 2 つの関数のどちらが先に呼び出されても、その形状が表示されます (つまり、DrawQuad を呼び出すと、テクスチャのないクワッドが表示されます)。

GL_TEXTURE_2D に glDisable を設定し、TexCoordArray をオフにして、テクスチャを 0 にバインドしようとしましたが、何も違いはありませんでした。私が見落としているものはありますか?

SSCCE

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using OpenTK;
using OpenTK.Graphics.OpenGL;

namespace E04
{
    internal class Renderer
    {
        private readonly Int32 _vertexBufferId;
        private readonly Int32 _textureBufferId;
        private readonly Int32 _indexBufferId;
        private readonly Int32 _colorBufferId;
        private readonly Int32 _normalBufferId;

        private readonly Vector2[] _vertices;
        private readonly Vector2[] _textureCoordinates;
        private readonly Byte[] _indices;
        private readonly Vector4[] _colors;
        private readonly Vector3[] _normals;

        public Renderer()
        {
            // Create a vertex array
            _vertices = new Vector2[4];

            // Set the coordinate data
            _textureCoordinates = new Vector2[4];
            _textureCoordinates[0].X = 0.0f;
            _textureCoordinates[0].Y = 0.0f;
            _textureCoordinates[1].X = 1.0f;
            _textureCoordinates[1].Y = 0.0f;
            _textureCoordinates[2].X = 0.0f;
            _textureCoordinates[2].Y = 1.0f;
            _textureCoordinates[3].X = 1.0f;
            _textureCoordinates[3].Y = 1.0f;

            // Set the index data
            _indices = new Byte[6];
            _indices[0] = 0;
            _indices[1] = 1;
            _indices[2] = 3;
            _indices[3] = 3;
            _indices[4] = 2;
            _indices[5] = 0;

            // Set the color data
            _colors = new Vector4[4];
            _colors[0] = new Vector4(1.0f, 0.0f, 0.0f, 1.0f);
            _colors[1] = new Vector4(1.0f, 1.0f, 0.0f, 1.0f);
            _colors[2] = new Vector4(0.0f, 1.0f, 0.0f, 1.0f);
            _colors[3] = new Vector4(0.0f, 0.0f, 1.0f, 1.0f);

            // Set the normal data
            _normals = new Vector3[4];
            _normals[0] = new Vector3(0.0f, 0.0f, 1.0f);
            _normals[1] = new Vector3(0.0f, 0.0f, 1.0f);
            _normals[2] = new Vector3(0.0f, 0.0f, 1.0f);
            _normals[3] = new Vector3(0.0f, 0.0f, 1.0f);

            // Bind the texture array buffer
            GL.GenBuffers(1, out _textureBufferId);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _textureBufferId);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (_textureCoordinates.Length*Vector2.SizeInBytes),
                          _textureCoordinates, BufferUsageHint.DynamicDraw);
            GL.TexCoordPointer(2, TexCoordPointerType.Float, 8, IntPtr.Zero);
            GL.EnableClientState(ArrayCap.TextureCoordArray);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            // Bind the normal array buffer
            GL.GenBuffers(1, out _normalBufferId);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _normalBufferId);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (_normals.Length*Vector3.SizeInBytes), _normals,
                          BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            // Bind the color array buffer
            GL.GenBuffers(1, out _colorBufferId);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _colorBufferId);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (_colors.Length*Vector4.SizeInBytes), _colors,
                          BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            // Bind vertex array buffer
            GL.GenBuffers(1, out _vertexBufferId);
            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferId);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr) (_vertices.Length*Vector2.SizeInBytes), _vertices,
                          BufferUsageHint.StreamDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

            // Bind index array buffer
            GL.GenBuffers(1, out _indexBufferId);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBufferId);
            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr) (_indices.Length*sizeof (Byte)), _indices,
                          BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
        }

        public void DrawQuad(Int32 x, Int32 y, Int32 width, Int32 height)
        {
            UpdateQuadVertices(x, y, width, height);

            GL.Disable(EnableCap.Texture2D);
            GL.BindTexture(TextureTarget.Texture2D, 0);

            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.ColorArray);
            GL.EnableClientState(ArrayCap.NormalArray);
            GL.EnableClientState(ArrayCap.TextureCoordArray);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferId);
            GL.VertexPointer(2, VertexPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _colorBufferId);
            GL.ColorPointer(4, ColorPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _normalBufferId);
            GL.NormalPointer(NormalPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _textureBufferId);
            GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBufferId);

            GL.DrawElements(BeginMode.Triangles, _indices.Length, DrawElementsType.UnsignedByte, 0);
        }

        public void DrawQuadTex(Int32 x, Int32 y, Int32 width, Int32 height, Int32 textureId)
        {
            UpdateQuadVertices(x, y, width, height);

            GL.Enable(EnableCap.Texture2D);
            GL.BindTexture(TextureTarget.Texture2D, textureId);

            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.ColorArray);
            GL.EnableClientState(ArrayCap.NormalArray);
            GL.EnableClientState(ArrayCap.TextureCoordArray);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferId);
            GL.VertexPointer(2, VertexPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _colorBufferId);
            GL.ColorPointer(4, ColorPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _normalBufferId);
            GL.NormalPointer(NormalPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ArrayBuffer, _textureBufferId);
            GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBufferId);

            GL.DrawElements(BeginMode.Triangles, _indices.Length, DrawElementsType.UnsignedByte, 0);

            // Removing this has no effect
            GL.DisableClientState(ArrayCap.TextureCoordArray);
        }

        internal void UpdateQuadVertices(Int32 x, Int32 y, Int32 width, Int32 height)
        {
            _vertices[0].X = x;
            _vertices[0].Y = y;
            _vertices[1].X = x + width;
            _vertices[1].Y = y;
            _vertices[2].X = x;
            _vertices[2].Y = y + height;
            _vertices[3].X = x + width;
            _vertices[3].Y = y + height;

            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferId);
            GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, (IntPtr) (_vertices.Length*Vector2.SizeInBytes),
                             _vertices);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }

        public Int32 LoadSimpleTexture()
        {
            Int32 textureObjectId;

            GL.GenTextures(1, out textureObjectId);
            GL.BindTexture(TextureTarget.Texture2D, textureObjectId);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
                            (Int32) TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
                            (Int32)TextureMagFilter.Linear);

            var bitmap = new Bitmap("simple.png");
            BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.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);

            bitmap.UnlockBits(data);

            return textureObjectId;
        }
    }


    class Program
    {
        static void Main()
        {
            Int32 textureObjectId = 0;

            using (var gameWindow = new GameWindow(800, 600))
            {
                var renderer = new Renderer();
                gameWindow.Load += (s, e) =>
                                       {
                                           GL.ClearColor(Color.CornflowerBlue);
                                           GL.Enable(EnableCap.Blend);
                                           GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                                           GL.AlphaFunc(AlphaFunction.Greater, 1.0f);

                                           textureObjectId = renderer.LoadSimpleTexture();

                                       };
                gameWindow.Resize += (s, e) =>
                                         {
                                             GL.Viewport(0, 0, 800, 600);
                                             GL.MatrixMode(MatrixMode.Projection);
                                             GL.LoadIdentity();
                                             GL.Ortho(0, 800, 600, 0, -1, 1);
                                         };
                gameWindow.RenderFrame += (s, e) =>
                                              {
                                                  GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                                                  renderer.DrawQuad(0, 0, 128, 128);
                                                  renderer.DrawQuadTex(128, 0, 128, 128, textureObjectId);

                                                  gameWindow.SwapBuffers();
                                              };

                gameWindow.Run();
            }

        }
    }
}

アップデート

最初に呼び出された関数のうち、形状が表示されている関数が不正確であると言ったとき、実際には、テクスチャのないものだけがテクスチャに取って代わります (つまり、DrawQuad が存在する場合、テクスチャのないものだけが表示されます)。

4

1 に答える 1

2

投稿したサンプルコードは問題なく機能します。そのため、ご説明いただいた問題を再現することはできません。明らかに、画像から、テクスチャのあるクワッドとテクスチャのないクワッドの両方が存在します。ただし、テクスチャード加工されたクワッドは、虹のように見える色によってさらにブレンドされます。これを修正するには、カラーポインタを無効にするか、カラーバッファを白色で塗りつぶします。

お使いのマシンでの結果が以下に投稿した写真と一致しない場合は、他の力が働いていることを示唆している可能性があります。これに関連する可能性のある例は、ビデオカード(-ドライバー)の選択です。

カラー&テクスチャードクワッド カラー&テクスチャードクワッド

于 2013-01-29T10:32:15.453 に答える