繁体   English   中英

一起使用GL_TEXTURE_2D和GL_TEXTURE_3D

[英]Using GL_TEXTURE_2D and GL_TEXTURE_3D together

前言

我有一个测试应用程序,它绘制了以下内容:

在此处输入图片说明

左三角形通过以下方式绘制:

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纹理停止工作):

没有

有没有办法使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();
            }
        }
    }
}

OpenGL具有纹理目标优先级:GL_TEXTURE_3D覆盖GL_TEXTURE_2D,后者覆盖GL_TEXTURE_1D。 由于一次只能在一个纹理单元中激活一个目标,因此具有最高优先级的纹理目标将提供采样数据。

要同时使用多个纹理(与目标无关),必须使用多重纹理。 查看多纹理教程,以了解如何使用它们。 在固定管线中使用多重纹理的方式与可编程(着色器)管线的使用方式之间有一些细微的差异。 http://www.clockworkcoders.com/oglsl/tutorial8.htm

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM