多维数据集上的opentk多个纹理不起作用

时间:2014-03-02 08:03:29

标签: c# opentk

所以在我的程序中有一个绘制立方体的功能。我在linux上使用c#和monodevelop。这是功能:

private int DrawCube(float x, float y, float z, float ori, int SideTexture, int TopTexture, int BottomTexture)
{
    GL.PushMatrix();

    GL.Translate(x, y, z);
    GL.Rotate(ori, 0, 1, 0);

    GL.BindTexture(TextureTarget.Texture2D, SideTexture);

    GL.Begin(BeginMode.Quads);

    GL.Color3(Color.White);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
    //Top
    //GL.ActiveTexture(TextureUnit.Texture0);
    GL.BindTexture(TextureTarget.Texture2D, TopTexture);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
    //Bottom
    GL.BindTexture(TextureTarget.Texture2D, BottomTexture);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, 0);
    GL.BindTexture(TextureTarget.Texture2D, SideTexture);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);

    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 20, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 20, 0);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);

    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);

    GL.End();
    GL.PopMatrix();

return 6;   // Return number of faces drawn
}

您可能已经猜到这个函数会绘制一个位置为x, y, z的多维数据集。方向ori 侧面和SideTexture以及顶部和底部的TopTexture和BottomTexture。 现在的问题是它只用一个纹理绘制立方体!侧面纹理。 我不知道是什么问题。我必须解开纹理吗? 代码中的其他一切工作正常,就像我说已经有纹理的麻烦。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:3)

您无法在开始端区域内呼叫GL.BindTexture()From the documentation

  

只能在glBegin和glEnd之间使用GL命令的子集。   命令是glVertex,glColor,glSecondaryColor,glIndex,   glNormal,glFogCoord,glTexCoord,glMultiTexCoord,glVertexAttrib,   glEvalCoord,glEvalPoint,glArrayElement,glMaterial和glEdgeFlag。   此外,可以使用glCallList或glCallLists来执行   显示仅包含上述命令的列表。 如果有的话   GL命令在glBegin和glEnd之间执行,错误标志是   设置并忽略该命令。

如果您选中GL.GetError(),则会看到您收到InvalidOperation错误。实际上GL.GetError()应该是您在OpenGL中无法按预期呈现某些内容时的第一反应。

解决方案:

private int DrawCube(float x, float y, float z, float ori, int SideTexture, int TopTexture, int BottomTexture)
{
    GL.PushMatrix();

    GL.Translate(x, y, z);
    GL.Rotate(ori, 0, 1, 0);

    GL.BindTexture(TextureTarget.Texture2D, SideTexture);
    GL.Begin(BeginMode.Quads);
    GL.Color3(Color.White);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
    GL.End();

    //Top
    GL.BindTexture(TextureTarget.Texture2D, TopTexture);
    GL.Begin(BeginMode.Quads);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
    GL.End();

    //Bottom
    GL.BindTexture(TextureTarget.Texture2D, BottomTexture);
    GL.Begin(BeginMode.Quads);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, 0);
    GL.End();

    GL.BindTexture(TextureTarget.Texture2D, SideTexture);
    GL.Begin(BeginMode.Quads);
    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);

    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 20, 0);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 20, 0);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);

    GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
    GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
    GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
    GL.End();

    GL.PopMatrix();

    return 6;   // Return number of faces drawn
}

答案 1 :(得分:1)

哦,是的,对于那些可能有用的人我实际上使用了纹理的错误边。 topTexture真的附在底部,e.t.c。这是工作代码。 从路径上传纹理的代码:

static public int UploadTexture(string pathname)
{
    // Create a new OpenGL texture object
    int id = GL.GenTexture();

    // Select the new texture
    GL.BindTexture(TextureTarget.Texture2D, id);

    // Load the image
    Bitmap bmp = new Bitmap(pathname);

    // Lock image data to allow direct access
    BitmapData bmp_data = bmp.LockBits(
            new Rectangle(0, 0, bmp.Width, bmp.Height),
            System.Drawing.Imaging.ImageLockMode.ReadOnly,
            System.Drawing.Imaging.PixelFormat.Format32bppArgb);

    // Import the image data into the OpenGL texture
    GL.TexImage2D(TextureTarget.Texture2D,
                  0,
                  PixelInternalFormat.Rgba,
                  bmp_data.Width,
                  bmp_data.Height,
                  0,
                  OpenTK.Graphics.OpenGL.PixelFormat.Bgra,
                  OpenTK.Graphics.OpenGL.PixelType.UnsignedByte,
                  bmp_data.Scan0);

    // Unlock the image data
    bmp.UnlockBits(bmp_data);

    // Configure minification and magnification filters
    GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMinFilter,
            (int)TextureMinFilter.Linear);
    GL.TexParameter(TextureTarget.Texture2D,
            TextureParameterName.TextureMagFilter,
            (int)TextureMagFilter.Linear);

    // Return the OpenGL object ID for use
    return id;
}

以及使用纹理绘制多维数据集的代码

private int DrawCube(float x, float y, float z, float ori, int TopTexture, int BottomTexture, params int[] SideTextures)
        {
            GL.PushMatrix();

            GL.Translate(x, y, z);
            GL.Rotate(ori, 0, 1, 0);

            GL.BindTexture(TextureTarget.Texture2D, SideTextures[0]);
            GL.Begin(BeginMode.Quads);
            GL.Color3(Color.White);
            GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
            GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
            GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
            GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
            GL.End();

            //Top
            GL.BindTexture(TextureTarget.Texture2D, SideTextures[1]);
            GL.Begin(BeginMode.Quads);
            GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
            GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
            GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
            GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
            GL.End();

            //Bottom
            GL.BindTexture(TextureTarget.Texture2D, BottomTexture);
            GL.Begin(BeginMode.Quads);
            GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
            GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
            GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, -20);
            GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, 0);
            GL.End();

            GL.BindTexture(TextureTarget.Texture2D, SideTextures[2]);
            GL.Begin(BeginMode.Quads);
            GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
            GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
            GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
            GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
            GL.End();
            GL.BindTexture(TextureTarget.Texture2D, TopTexture);
            GL.Begin(BeginMode.Quads);
            GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 20, 0);
            GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 20, 0);
            GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
            GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
            GL.End();
            GL.BindTexture(TextureTarget.Texture2D, SideTextures[3]);
            GL.Begin(BeginMode.Quads);
            GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
            GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
            GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
            GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
            GL.End();

            GL.PopMatrix();

            return 6;   // Return number of faces drawn
        }
        protected override void OnResize(EventArgs e)
        {
            int w = Width;
            int h = Height;
            float aspect = 1;

            // Calculate aspect ratio, checking for divide by zero
            if (h > 0)
            {
                aspect = (float)w / (float)h;
            }

            // Initialise the projection view matrix
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();

            // Setup a perspective view
            float FOVradians = MathHelper.DegreesToRadians(45);
            Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(FOVradians, aspect, 1, 4000);
            GL.MultMatrix(ref perspective);

            // Set the viewport to the whole window
            GL.Viewport(0, 0, w, h);
        }

以及您必须使用的参考资料:

using System;
using System.Drawing;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;

修改 在较新版本的OpenTK中,我相信您必须使用PrimitiveType.Quad而不是BeginMode.Quad