Совместное использование GL_TEXTURE_2D и GL_TEXTURE_3D - PullRequest
1 голос
/ 03 августа 2011

Введение

У меня есть тестовое приложение, которое рисует следующее:

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();
            }
        }
    }
}

1 Ответ

7 голосов
/ 03 августа 2011

OpenGL имеет приоритет текстурных целей: GL_TEXTURE_3D переопределяет GL_TEXTURE_2D, который переопределяет GL_TEXTURE_1D.Поскольку в текстурном блоке одновременно может быть активна только одна цель, текстурная цель с наивысшим приоритетом будет предоставлять данные выборки.

Чтобы использовать несколько текстур одновременно (независимо от их цели), необходимоиспользовать мультитекстурирование.Посмотрите учебники по мультитекстурированию, чтобы понять, как их использовать.Есть некоторые тонкие различия между тем, как вы используете мультитекстурирование в фиксированном конвейере, и программируемыми (= шейдерами) конвейерами.http://www.clockworkcoders.com/oglsl/tutorial8.htm

...