2011-08-03 63 views
1

前言

我有一個測試應用程序,得出如下:使用GL_TEXTURE_2D和GL_TEXTURE_3D一起

GL.glBegin(GL.GL_TRIANGLES); 
{ 
    for (int i = 0; i < 50; i++) 
    { 
     GL.glColor4d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); 
     GL.glVertex2d(rand.NextDouble(), rand.NextDouble()); 
     GL.glColor4d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); 
     GL.glVertex2d(rand.NextDouble(), rand.NextDouble()); 
     GL.glColor4d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); 
     GL.glVertex2d(rand.NextDouble(), rand.NextDouble()); 
    } 
} 
GL.glEnd(); 

直角三角形是:

enter image description here

左三角形通過繪製繪製:

GL.glBindTexture(GL.GL_TEXTURE_2D, texture); 

GL.glBegin(GL.GL_QUADS); 
{ 
    GL.glTexCoord2f(0, 1); GL.glVertex2f(0, 1); 
    GL.glTexCoord2f(0, 0); GL.glVertex2f(0, 0); 
    GL.glTexCoord2f(1, 0); GL.glVertex2f(1, 0); 
    GL.glTexCoord2f(1, 1); GL.glVertex2f(1, 1); 
} 
GL.glEnd(); 

紋理通過FBO呈現。

問題

我也很難使GL_TEXTURE_2D和GL_TEXTURE_3D一起玩。一切都很正常,直到我去掉下面的代碼段:

GL.glEnable(GL.GL_TEXTURE_2D); 
// GL.glEnable(GL.GL_TEXTURE_3D); 

結果我得到以下圖像(2D紋理停止工作):

None

有沒有一種方法,使2D和3D紋理一起工作?我需要通過FBO將3D紋理渲染成2D紋理。有沒有辦法做到這一點?

完整的源代碼

using System; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.Threading; 
using System.Drawing.Imaging; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 

using OpenTK; 
using OpenTK.Graphics; 

using ManOCL; 
using Monobjc.OpenGL; 

using TextureTarget = OpenTK.Graphics.OpenGL.TextureTarget; 

namespace Test 
{ 
    class Program 
    {  
     static void InitViewport(INativeWindow wnd, IGraphicsContext ctx) 
     { 
      GL.glViewport(0, 0, wnd.Width, wnd.Height); 
      GL.glMatrixMode(GL.GL_PROJECTION); 
      GL.glLoadIdentity(); 
      GL.glMatrixMode(GL.GL_MODELVIEW); 
      GL.glLoadIdentity(); 

      Double aspect = 1; 

      if (wnd.Height > 0) 
      { 
       aspect = wnd.Width/(double)wnd.Height; 
      } 

      Double square = 2; 

      Double realWidth = square * aspect; 

      GL.glOrtho(-realWidth * 0.5, realWidth * 0.5, -square * 0.5, square * 0.5, -1, 1); 

      ctx.Update(wnd.WindowInfo); 
     } 

     static void InitGL(INativeWindow wnd, IGraphicsContext ctx) 
     { 
      GL.glShadeModel(GL.GL_SMOOTH); 

      GL.glEnable(GL.GL_TEXTURE_2D); 
//   GL.glEnable(GL.GL_TEXTURE_3D); 

      GL.glEnable(GL.GL_BLEND); 
      GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); 

      GL.glDisable(GL.GL_DEPTH_TEST); 

      GL.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 
      GL.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
     } 

     static uint CreateTexture2D(Int32 width, Int32 height) 
     { 
      uint texture; 

      GL.glGenTextures(1, out texture); 
      GL.glBindTexture(GL.GL_TEXTURE_2D, texture); 
      GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, IntPtr.Zero); 
      GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); 
      GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); 
      GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP); 
      GL.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP); 
      GL.glBindTexture(GL.GL_TEXTURE_2D, 0); 

      return texture; 
     } 

     static uint CreateFBO() 
     { 
      uint fbo; 

      GL.glGenFramebuffers(1, out fbo); 

      return fbo; 
     } 

     [STAThread] 
     static void Main(string[] args) 
     { 
      Int32 strips = 32; 
      Int32 stripComponents = 6; 

      Random rand = new Random(); 

      INativeWindow wnd = new OpenTK.NativeWindow(800, 600, "OpenGL", GameWindowFlags.Default, GraphicsMode.Default, DisplayDevice.Default); 
      IGraphicsContext ctx = new GraphicsContext(GraphicsMode.Default, wnd.WindowInfo); 

      wnd.Visible = true; 
      wnd.Resize += delegate { InitViewport(wnd, ctx); }; 
      wnd.KeyPress += delegate(object sender, OpenTK.KeyPressEventArgs e) { 
       if (e.KeyChar == 'q') 
       { 
        wnd.Close(); 
       } 
       else if (e.KeyChar == '=' || e.KeyChar == '+') 
       { 
        Size size = wnd.Size; 
        Point location = wnd.Location; 

        wnd.Location = new Point(location.X - 16, location.Y); 
        wnd.Size = new Size(size.Width + 32, size.Height + 32); 
       } 
       else if (e.KeyChar == '-') 
       { 
        Size size = wnd.Size; 
        Point location = wnd.Location; 

        wnd.Location = new Point(location.X + 16, location.Y + 44); 
        wnd.Size = new Size(size.Width - 32, size.Height - 32); 
       } 
      }; 

      ctx.MakeCurrent(wnd.WindowInfo); 
      ctx.LoadAll(); 

      InitGL(wnd, ctx);   

      Int32 width = 512; 
      Int32 height = 512; 

      uint fbo = CreateFBO(); 
      uint texture = CreateTexture2D(width, height); 

      GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo); 
      { 
       GL.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0, GL.GL_TEXTURE_2D, texture, 0); 

       GL.glPushAttrib(GL.GL_ALL_ATTRIB_BITS); 
       { 
        GL.glViewport(0, 0, width, height); 

        GL.glMatrixMode(GL.GL_PROJECTION); 
        GL.glLoadIdentity(); 
        GL.glMatrixMode(GL.GL_MODELVIEW); 
        GL.glLoadIdentity(); 

        GL.glOrtho(0, 1, 0, 1, -1, 1); 

        GL.glClearColor(0, 0, 0, 1.0f); 

        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); 

        GL.glBegin(GL.GL_TRIANGLES); 
        { 
         for (int i = 0; i < 50; i++) 
         { 
          GL.glColor4d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); 
          GL.glVertex2d(rand.NextDouble(), rand.NextDouble()); 
          GL.glColor4d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); 
          GL.glVertex2d(rand.NextDouble(), rand.NextDouble()); 
          GL.glColor4d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); 
          GL.glVertex2d(rand.NextDouble(), rand.NextDouble()); 
         } 
        } 
        GL.glEnd(); 
       } 
       GL.glPopAttrib(); 
      } 
      GL.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); 

      InitViewport(wnd, ctx); 

      while (wnd.Exists) 
      { 
       GL.glClear(GL.GL_COLOR_BUFFER_BIT); 

       GL.glPushMatrix(); 
       GL.glPushAttrib(GL.GL_TEXTURE_BIT | GL.GL_CURRENT_BIT); 
       { 
        GL.glTranslatef(-0.5f, -0.5f, 0); 

        GL.glPushMatrix(); 
        GL.glPushAttrib(GL.GL_TEXTURE_BIT | GL.GL_CURRENT_BIT); 
        { 
         GL.glTranslatef(-0.5f, 0f, 0); 

         for (int strip = 0; strip < strips; strip++) 
         { 
          GL.glBegin(GL.GL_TRIANGLE_STRIP); 
          { 
           for (int stripComponent = 0; stripComponent < stripComponents; stripComponent++) 
           { 
            GL.glColor4d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); 
            GL.glVertex2d(rand.NextDouble(), rand.NextDouble()); 
           } 
          } 
          GL.glEnd(); 
         } 
        } 
        GL.glPopAttrib(); 
        GL.glPopMatrix(); 

        GL.glPushMatrix(); 
        GL.glPushAttrib(GL.GL_TEXTURE_BIT | GL.GL_CURRENT_BIT); 
        { 
         GL.glTranslatef(0.5f, 0f, 0); 

         GL.glColor4f(1, 1, 1, 1); 

         GL.glBindTexture(GL.GL_TEXTURE_2D, texture); 

         GL.glBegin(GL.GL_QUADS); 
         { 
          GL.glTexCoord2f(0, 1); GL.glVertex2f(0, 1); 
          GL.glTexCoord2f(0, 0); GL.glVertex2f(0, 0); 
          GL.glTexCoord2f(1, 0); GL.glVertex2f(1, 0); 
          GL.glTexCoord2f(1, 1); GL.glVertex2f(1, 1); 
         } 
         GL.glEnd(); 
        } 
        GL.glPopAttrib(); 
        GL.glPopMatrix(); 
       } 
       GL.glPopAttrib();    
       GL.glPopMatrix(); 

       ctx.SwapBuffers(); 
       wnd.ProcessEvents(); 
      } 
     } 
    } 
} 

回答

7

OpenGL的具有紋理目標的優先級:GL_TEXTURE_3D覆蓋GL_TEXTURE_2D,它覆蓋GL_TEXTURE_1D。由於一次只能有一個目標在紋理單元中處於活動狀態,因此具有最高優先級的紋理目標將提供採樣數據。

要同時使用多個紋理(與目標無關),必須使用多紋理。查看多紋理教程,瞭解如何使用它們。在固定流水線中使用多紋理與可編程(=着色器)流水線之間存在一些細微的差異。 http://www.clockworkcoders.com/oglsl/tutorial8.htm