首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同时使用GL_TEXTURE_2D和GL_TEXTURE_3D

同时使用GL_TEXTURE_2D和GL_TEXTURE_3D
EN

Stack Overflow用户
提问于 2011-08-03 18:03:17
回答 1查看 5.1K关注 0票数 1

前言

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

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

代码语言:javascript
复制
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();

右边的三角形是用以下方式绘制的:

代码语言:javascript
复制
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在一起玩。在我取消注释下面这段代码之前,一切都很正常:

代码语言:javascript
复制
GL.glEnable(GL.GL_TEXTURE_2D);
// GL.glEnable(GL.GL_TEXTURE_3D);

结果,我得到了以下图像(2D纹理停止工作):

有没有一种方法可以让2D和3D纹理一起工作?我需要通过FBO将3D纹理渲染成2D纹理。有没有办法做到这一点?

完整的源代码

代码语言:javascript
复制
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();
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-03 18:11:41

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

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

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6924737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档