2014-03-02 3 views
0

Итак, в моей программе есть функция для рисования куба. Я использую C# с monodevelop в linux. Вот функция:opentk несколько текстур на кубе не работают

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 сверху и снизу. Теперь проблема в том, что он рисует куб только с одной текстурой! боковая текстура. Я не знаю, в чем проблема. Должен ли я развязывать текстуры? все остальное в коде работает отлично, как я уже сказал, есть эта неприятность с текстурами. Любая помощь приветствуется.

+0

о, пожалуйста? никто? –

ответ

2

Вы не можете позвонить в GL.BindTexture() в начальном регионе. From the documentation:

только подмножество команд GL может использоваться между glBegin и glEnd. Эти команды 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 
} 
+0

+1 спасибо! :-) –

1

О да для тех, кто это может быть полезно, я использовал неправильные стороны с текстурами. Верхняя текстура была действительно прикреплена к основанию, 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); 
     } 

и refrences вы должны использовать:

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

EDIT: В новой версии OpenTK я считаю, что вам придется использовать PrimitiveType.Quad i nstead of BeginMode.Quad

Смежные вопросы