2011-08-03 2 views
1

Введение

У меня есть тест-приложение, которое привлекает следующее:Используя GL_TEXTURE_2D и GL_TEXTURE_3D вместе

enter image description here

левой треугольники рисуются с помощью:

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.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-текстуры работают вместе? Мне нужно визуализировать 3D-текстуру в 2D-текстуре через FBO. Есть ли способ сделать это?

Полный исходный код

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

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