1

序文

次のようなテストアプリケーションがあります。

ここに画像の説明を入力してください

左の三角形は次の方法で描画されます。

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

1 に答える 1

7

OpenGL にはテクスチャ ターゲットの優先順位があります。GL_TEXTURE_3D は GL_TEXTURE_2D をオーバーライドし、GL_TEXTURE_1D をオーバーライドします。一度に 1 つのテクスチャ ユニットでアクティブにできるターゲットは 1 つだけなので、優先順位が最も高いテクスチャ ターゲットがサンプリング データを提供します。

複数のテクスチャを同時に (ターゲットに関係なく) 使用するには、マルチテクスチャリングを使用する必要があります。マルチテクスチャリングのチュートリアルを見て、それらの使用方法を理解してください。固定パイプラインでマルチテクスチャリングを使用する方法と、プログラム可能な (=シェーダー) パイプラインで使用する方法の間には、いくつかの微妙な違いがあります。http://www.clockworkcoders.com/oglsl/tutorial8.htm

于 2011-08-03T10:11:41.337 に答える