2011-07-22 100 views
0

編輯:好的,這段代碼仍然不允許我在程序中使用兩種不同的紋理。它的行爲就像它應該工作,但是當我告訴它使用第一個紋理時,它與第二個紋理相同,這是最後一次加載的紋理。C#SFML OpenGl多紋理問題

 private int[] iTextures = new int[3]; 

     public void main() 
     { 
      Initialize(); 
      LoadContent(); 

      float Time = 0.0F; 

      // Start game loop 
      while (App.IsOpened()) 
      { 
       // Process events 
       App.DispatchEvents(); 

       // Clear the window 
       App.Clear(); 

       App.Draw(Background); 

       Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT); 

       // Transformations 
       Time += App.GetFrameTime(); 
       Gl.glMatrixMode(Gl.GL_MODELVIEW); 
       Gl.glLoadIdentity(); 
       Gl.glTranslatef(0.0F, 0.0F, -200.0F); 


       Gl.glPushMatrix(); 

       Gl.glScalef(10.0f, 50.0f, 10.0f); 
       DrawCube(50.0f, 50.0f, 50.0f, 0); 

       Gl.glPopMatrix(); 

       //Gl.glRotatef(Time * 50, 1.0F, 0.0F, 0.0F); 
       //Gl.glRotatef(Time * 30, 0.0F, 1.0F, 0.0F); 
       //Gl.glRotatef(Time * 90, 0.0F, 0.0F, 1.0F); 


       /*Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F); 
       Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F); 

       Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F); 
       Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F); 
       Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F); 
       Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F); 

       Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F); 
       Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F); 
       Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F); 

       Gl.glTexCoord2f(0, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F); 
       Gl.glTexCoord2f(0, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F); 
       Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F); 

       Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, -50.0F, 50.0F); 
       Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, -50.0F, 50.0F); 

       Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F); 
       Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 50.0F, -50.0F); 
       Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F); 


       Gl.glVertex3f(50.0f, 50.0f, 50.0f); 
       Gl.glVertex3f(50.0f, 0.0f, 50.0f); 
       Gl.glVertex3f(0.0f, 0.0f, 50.0f); 
       Gl.glVertex3f(0.0f, 50.0f, 50.0f); 

       Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 10.0F, 50.0F); 
       Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 10.0F, -50.0F); 
       Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 10.0F, -50.0F); 
       Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 10.0F, 50.0F); 

       Gl.glEnd();*/ 



       Draw(); 

       // Finally, display the rendered frame on screen 
       App.Display(); 

      } 
      // Don't forget to destroy our texture 
      int tex = 0; 
      Gl.glDeleteTextures(1, ref tex); 
     } 

     public void Initialize() 
     { 
      // Create main window 

      App.PreserveOpenGLStates(true); 

      // Setup event handlers 
      App.Closed += new EventHandler(OnClosed); 
      App.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed); 
      App.Resized += new EventHandler<SizeEventArgs>(OnResized); 
     } 

     private void LoadContent() 
     { 
      BackgroundImage = new Image("background.jpg"); 
      Background = new Sprite(BackgroundImage); 

      Text = new String2D("This is a cube"); 
      Text.Position = new Vector2(0, 0); 
      Text.Color = Color.Black; 

      // Enable Z-buffer read and write 
      Gl.glEnable(Gl.GL_DEPTH_TEST); 
      Gl.glDepthMask(Gl.GL_TRUE); 
      Gl.glClearDepth(1.0F); 

      // Setup a perspective projection 

      Gl.glMatrixMode(Gl.GL_PROJECTION); 
      Gl.glLoadIdentity(); 
      Glu.gluPerspective(90.0F, 1.0F, 1.0F, 500.0F); // I assume this is setting up the camera 

      LoadTexture(new Image("texture.jpg"), 0); 

      LoadTexture(new Image("Otexture.jpg"), 1); 


     } 

     private void Draw() 
     { 
      App.Draw(Text); 
     } 

     private void LoadTexture(Image Texture, int texNum) 
     { 

      using (Image TempImage = Texture) 
      { 

       Gl.glGenTextures(1, out iTextures[texNum]); // Texture name, which is a number 

       Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTextures[texNum]); // Start using the texture 


       Console.WriteLine(texNum + ""); 
       // Texture options and filters and stuff 
       Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); 
       Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR); 

       Glu.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels); 
       //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels); 

      } 
      Gl.glEnable(Gl.GL_TEXTURE_2D); 
     } 
     private void UseTexture(int iTexture) 
     { 


      // Bind our texture for use 
      //Gl.glEnable(Gl.GL_TEXTURE_2D); // Start using the 2D texture 
      Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTexture); // Bind our texture for current use 
      Gl.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); // Set color to..white, I think. 
     } 



     void DrawCube(float xPos, float yPos, float zPos, int texture) 
     { 

      Gl.glPushMatrix(); 

      //UseTexture(1); 
      Gl.glBegin(Gl.GL_QUADS); 
      UseTexture(iTextures[0]); 
      //Gl.glEnable(Gl.GL_TEXTURE_2D); 



      /*  This is the top face*/ 
      Gl.glVertex3f(0.0f, 0.0f, 0.0f); 
      Gl.glVertex3f(0.0f, 0.0f, -1.0f); 
      Gl.glVertex3f(-1.0f, 0.0f, -1.0f); 
      Gl.glVertex3f(-1.0f, 0.0f, 0.0f); 

      /*  This is the front face*/ 
      Gl.glTexCoord2f(0, 1); Gl.glVertex3f(0.0f, 0.0f, 0.0f); 
      Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-1.0f, 0.0f, 0.0f); 
      Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-1.0f, -1.0f, 0.0f); 
      Gl.glTexCoord2f(1, 1); Gl.glVertex3f(0.0f, -1.0f, 0.0f); 

      /*  This is the right face*/ 
      Gl.glVertex3f(0.0f, 0.0f, 0.0f); 
      Gl.glVertex3f(0.0f, -1.0f, 0.0f); 
      Gl.glVertex3f(0.0f, -1.0f, -1.0f); 
      Gl.glVertex3f(0.0f, 0.0f, -1.0f); 

      /*  This is the left face*/ 
      Gl.glVertex3f(-1.0f, 0.0f, 0.0f); 
      Gl.glVertex3f(-1.0f, 0.0f, -1.0f); 
      Gl.glVertex3f(-1.0f, -1.0f, -1.0f); 
      Gl.glVertex3f(-1.0f, -1.0f, 0.0f); 

      /*  This is the bottom face*/ 
      Gl.glVertex3f(0.0f, 0.0f, 0.0f); 
      Gl.glVertex3f(0.0f, -1.0f, -1.0f); 
      Gl.glVertex3f(-1.0f, -1.0f, -1.0f); 
      Gl.glVertex3f(-1.0f, -1.0f, 0.0f); 

      /*  This is the back face*/ 
      Gl.glVertex3f(0.0f, 0.0f, 0.0f); 
      Gl.glVertex3f(-1.0f, 0.0f, -1.0f); 
      Gl.glVertex3f(-1.0f, -1.0f, -1.0f); 
      Gl.glVertex3f(0.0f, -1.0f, -1.0f); 

      Gl.glEnd(); 
      Gl.glPopMatrix(); 
     } 

任何幫助都會很棒。

回答

0

你不是在談論多紋理;你正在討論在同一個應用程序中使用多個紋理。

嗯,我看到幾個問題。

Gl.glGenTextures(2, out iTexture); // Texture name, which is a number 

我承認,我不是100%熟悉C#的語法,所以我假設out作品有點像傳遞指針在C/C++。因此,您期望glGenTextures將紋理對象編號寫入iTexture

這裏有兩個問題。首先,iTexture是一個整數。但是你告訴glGenTextures你在這個函數調用中生成了兩個紋理,而不是一個。這需要傳入一個整數數組glGenTextures來寫入。所以你冒着摧毀......堆棧的風險?我不知道你是如何將這些調用集合到C++的,但是無論你如何做,glGenTextures都可能寫入隨機內存。你很幸運不會崩潰。

每個調用LoadTexture都應該創建一個OpenGL紋理對象。因此,您不應該嘗試從一個LoadTexture呼叫創建兩個。

另一個問題是iTexture不是返回從您的LoadTexture函數。你不要把它存儲在任何地方。事實上,當你打電話給LoadTexture時,你甚至不會給它一個輸出變量;你給它一個數字文字。再說一遍,我不是C#專家,但我敢肯定你需要一些特殊的語法來使用參數作爲函數輸出,特別是對於像int這樣的基本類型。

您的LoadTexture函數應該返回OpenGL紋理名稱(或將它們存儲在某處),匹配的UseTexture調用應該從它們獲取這些特定的名稱。


新的代碼問題:

// Don't forget to destroy our texture 
int tex = 0; 
Gl.glDeleteTextures(1, ref tex); 

不能刪除質感0。一般就是爲什麼人們不使用質地0存儲在實際的紋理;它通常被視爲「不存在的紋理」,如NULL。

至於實際的繪圖代碼:

Gl.glBegin(Gl.GL_QUADS); 
UseTexture(iTextures[0]); 

不能glBegin/glEnd調用之間調用glBindTexture(或大多數OpenGL函數)。 UseTexture應該在開始四元組之前調用。此外,UseTexture應啓用GL_TEXTURE_2D。我知道你在其他地方使用它,但最好把命令放在他們真正重要的地方。如果要執行無紋理渲染,則必須禁用GL_TEXTURE_2D

此外,當您只給出一個四紋理座標時,您會發生什麼?你期望其他四邊形看起來像什麼?因爲如果你認爲那些四邊形是不固定的,你錯了。

+0

啊,這是有道理的。老實說,我認爲OpenGl在創建它們時存儲了這些名稱,顯然我錯了。 我會給你建議一個鏡頭,非常感謝。 – Elec0

+0

@ Elec0:當然,OpenGL存儲紋理名稱 - 因爲它是內部管理。但它沒有一種水晶球,它無法讀懂你的想法,也不知道你想使用哪種紋理。你必須告訴OpenGL使用哪個紋理,紋理名稱是這個句柄。 – datenwolf

+0

@Nicol Bolas:如果Elec0忽略了對glGenTextures的調用,假設OpenGL-1.x操作,這實際上已經起作用,因爲OpenGL-1允許使用未顯式生成的隱式對象名稱(然後靜默地生成新的紋理對象與請求的名字)。名稱0保留,所以LoadTexture iTexture參數將以1開頭。 – datenwolf