Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region --- License ---
2
/* Licensed under the MIT/X11 license.
3
 * Copyright (c) 2006-2008 the OpenTK Team.
4
 * This notice may not be removed from any source distribution.
5
 * See license.txt for licensing details.
6
 */
7
#endregion
8
 
9
using System;
10
using System.Diagnostics;
11
using System.Drawing;
12
 
13
using OpenTK;
14
using OpenTK.Input;
15
using OpenTK.Graphics;
16
using OpenTK.Graphics.OpenGL;
17
 
18
namespace Examples.Tutorial
19
{
20
    [Example("Framebuffer Objects", ExampleCategory.OpenGL, "1.x", Documentation="FramebufferObject")]
21
    public class SimpleFBO : GameWindow
22
    {
23
        public SimpleFBO()
24
            : base(800, 600)
25
        {
26
        }
27
 
28
        Font sans = new Font(System.Drawing.FontFamily.GenericSansSerif, 16.0f);
29
 
30
        uint ColorTexture;
31
        uint DepthTexture;
32
        uint FBOHandle;
33
 
34
        const int TextureSize = 512;
35
 
36
        #region Randoms
37
 
38
        Random rnd = new Random();
39
        public const float scale = 3f;
40
 
41
        /// <summary>Returns a random Float in the range [-0.5*scale..+0.5*scale]</summary>
42
        public float GetRandom()
43
        {
44
            return (float)(rnd.NextDouble() - 0.5) * scale;
45
        }
46
 
47
        /// <summary>Returns a random Float in the range [0..1]</summary>
48
        public float GetRandom0to1()
49
        {
50
            return (float)rnd.NextDouble();
51
        }
52
 
53
        #endregion Randoms
54
 
55
        protected override void OnLoad(EventArgs e)
56
        {
57
            if (!GL.GetString(StringName.Extensions).Contains("EXT_framebuffer_object"))
58
            {
59
                System.Windows.Forms.MessageBox.Show(
60
                     "Your video card does not support Framebuffer Objects. Please update your drivers.",
61
                     "FBOs not supported",
62
                     System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation);
63
                Exit();
64
            }
65
 
66
            GL.Enable(EnableCap.DepthTest);
67
            GL.ClearDepth(1.0f);
68
            GL.DepthFunc(DepthFunction.Lequal);
69
 
70
            GL.Disable(EnableCap.CullFace);
71
            GL.PolygonMode(MaterialFace.Back, PolygonMode.Line);
72
 
73
            // Create Color Tex
74
            GL.GenTextures(1, out ColorTexture);
75
            GL.BindTexture(TextureTarget.Texture2D, ColorTexture);
76
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, TextureSize, TextureSize, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
77
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
78
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
79
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
80
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
81
            // GL.Ext.GenerateMipmap( GenerateMipmapTarget.Texture2D );
82
 
83
            // Create Depth Tex
84
            GL.GenTextures(1, out DepthTexture);
85
            GL.BindTexture(TextureTarget.Texture2D, DepthTexture);
86
            GL.TexImage2D(TextureTarget.Texture2D, 0, (PixelInternalFormat)All.DepthComponent32, TextureSize, TextureSize, 0, PixelFormat.DepthComponent, PixelType.UnsignedInt, IntPtr.Zero);
87
            // things go horribly wrong if DepthComponent's Bitcount does not match the main Framebuffer's Depth
88
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
89
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
90
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
91
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
92
            // GL.Ext.GenerateMipmap( GenerateMipmapTarget.Texture2D );
93
 
94
            // Create a FBO and attach the textures
95
            GL.Ext.GenFramebuffers(1, out FBOHandle);
96
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, FBOHandle);
97
            GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, ColorTexture, 0);
98
            GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachmentExt, TextureTarget.Texture2D, DepthTexture, 0);
99
 
100
            #region Test for Error
101
 
102
            switch (GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt))
103
            {
104
                case FramebufferErrorCode.FramebufferCompleteExt:
105
                    {
106
                        Console.WriteLine("FBO: The framebuffer is complete and valid for rendering.");
107
                        break;
108
                    }
109
                case FramebufferErrorCode.FramebufferIncompleteAttachmentExt:
110
                    {
111
                        Console.WriteLine("FBO: One or more attachment points are not framebuffer attachment complete. This could mean there’s no texture attached or the format isn’t renderable. For color textures this means the base format must be RGB or RGBA and for depth textures it must be a DEPTH_COMPONENT format. Other causes of this error are that the width or height is zero or the z-offset is out of range in case of render to volume.");
112
                        break;
113
                    }
114
                case FramebufferErrorCode.FramebufferIncompleteMissingAttachmentExt:
115
                    {
116
                        Console.WriteLine("FBO: There are no attachments.");
117
                        break;
118
                    }
119
                /* case  FramebufferErrorCode.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
120
                     {
121
                         Console.WriteLine("FBO: An object has been attached to more than one attachment point.");
122
                         break;
123
                     }*/
124
                case FramebufferErrorCode.FramebufferIncompleteDimensionsExt:
125
                    {
126
                        Console.WriteLine("FBO: Attachments are of different size. All attachments must have the same width and height.");
127
                        break;
128
                    }
129
                case FramebufferErrorCode.FramebufferIncompleteFormatsExt:
130
                    {
131
                        Console.WriteLine("FBO: The color attachments have different format. All color attachments must have the same format.");
132
                        break;
133
                    }
134
                case FramebufferErrorCode.FramebufferIncompleteDrawBufferExt:
135
                    {
136
                        Console.WriteLine("FBO: An attachment point referenced by GL.DrawBuffers() doesn’t have an attachment.");
137
                        break;
138
                    }
139
                case FramebufferErrorCode.FramebufferIncompleteReadBufferExt:
140
                    {
141
                        Console.WriteLine("FBO: The attachment point referenced by GL.ReadBuffers() doesn’t have an attachment.");
142
                        break;
143
                    }
144
                case FramebufferErrorCode.FramebufferUnsupportedExt:
145
                    {
146
                        Console.WriteLine("FBO: This particular FBO configuration is not supported by the implementation.");
147
                        break;
148
                    }
149
                default:
150
                    {
151
                        Console.WriteLine("FBO: Status unknown. (yes, this is really bad.)");
152
                        break;
153
                    }
154
            }
155
 
156
            // using FBO might have changed states, e.g. the FBO might not support stereoscopic views or double buffering
157
            int[] queryinfo = new int[6];
158
            GL.GetInteger(GetPName.MaxColorAttachmentsExt, out queryinfo[0]);
159
            GL.GetInteger(GetPName.AuxBuffers, out queryinfo[1]);
160
            GL.GetInteger(GetPName.MaxDrawBuffers, out queryinfo[2]);
161
            GL.GetInteger(GetPName.Stereo, out queryinfo[3]);
162
            GL.GetInteger(GetPName.Samples, out queryinfo[4]);
163
            GL.GetInteger(GetPName.Doublebuffer, out queryinfo[5]);
164
            Console.WriteLine("max. ColorBuffers: " + queryinfo[0] + " max. AuxBuffers: " + queryinfo[1] + " max. DrawBuffers: " + queryinfo[2] +
165
                               "\nStereo: " + queryinfo[3] + " Samples: " + queryinfo[4] + " DoubleBuffer: " + queryinfo[5]);
166
 
167
            Console.WriteLine("Last GL Error: " + GL.GetError());
168
 
169
            #endregion Test for Error
170
 
171
            GL.PushAttrib(AttribMask.ViewportBit);
172
            {
173
                GL.Viewport(0, 0, TextureSize, TextureSize);
174
 
175
                // clear the screen in red, to make it very obvious what the clear affected. only the FBO, not the real framebuffer
176
                GL.ClearColor(1f, 0f, 0f, 0f);
177
                GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
178
 
179
                // smack 50 random triangles into the FBO's textures
180
                GL.Begin(BeginMode.Triangles);
181
                {
182
                    for (int i = 0; i < 50; i++)
183
                    {
184
                        GL.Color3(GetRandom0to1(), GetRandom0to1(), GetRandom0to1());
185
                        GL.Vertex3(GetRandom(), GetRandom(), GetRandom());
186
                        GL.Color3(GetRandom0to1(), GetRandom0to1(), GetRandom0to1());
187
                        GL.Vertex3(GetRandom(), GetRandom(), GetRandom());
188
                        GL.Color3(GetRandom0to1(), GetRandom0to1(), GetRandom0to1());
189
                        GL.Vertex3(GetRandom(), GetRandom(), GetRandom());
190
                    }
191
                }
192
                GL.End();
193
            }
194
            GL.PopAttrib();
195
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // disable rendering into the FBO
196
 
197
            GL.ClearColor(.1f, .2f, .3f, 0f);
198
            GL.Color3(1f, 1f, 1f);
199
 
200
            GL.Enable(EnableCap.Texture2D); // enable Texture Mapping
201
            GL.BindTexture(TextureTarget.Texture2D, 0); // bind default texture
202
        }
203
 
204
        protected override void OnUnload(EventArgs e)
205
        {
206
            // Clean up what we allocated before exiting
207
            if (ColorTexture != 0)
208
                GL.DeleteTextures(1, ref ColorTexture);
209
 
210
            if (DepthTexture != 0)
211
                GL.DeleteTextures(1, ref DepthTexture);
212
 
213
            if (FBOHandle != 0)
214
                GL.Ext.DeleteFramebuffers(1, ref FBOHandle);
215
        }
216
 
217
        protected override void OnResize(EventArgs e)
218
        {
219
            GL.Viewport(0, 0, Width, Height);
220
 
221
            double aspect_ratio = Width / (double)Height;
222
 
223
            OpenTK.Matrix4 perspective = OpenTK.Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)aspect_ratio, 1, 64);
224
            GL.MatrixMode(MatrixMode.Projection);
225
            GL.LoadMatrix(ref perspective);
226
 
227
            Matrix4 lookat = Matrix4.LookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
228
            GL.MatrixMode(MatrixMode.Modelview);
229
            GL.LoadMatrix(ref lookat);
230
 
231
            base.OnResize(e);
232
        }
233
 
234
        protected override void OnUpdateFrame(FrameEventArgs e)
235
        {
236
            base.OnUpdateFrame(e);
237
 
238
            if (Keyboard[Key.Escape])
239
                this.Exit();
240
        }
241
 
242
        protected override void OnRenderFrame(FrameEventArgs e)
243
        {
244
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
245
 
246
            GL.PushMatrix();
247
            {
248
                // Draw the Color Texture
249
                GL.Translate(-1.1f, 0f, 0f);
250
                GL.BindTexture(TextureTarget.Texture2D, ColorTexture);
251
                GL.Begin(BeginMode.Quads);
252
                {
253
                    GL.TexCoord2(0f, 1f);
254
                    GL.Vertex2(-1.0f, 1.0f);
255
                    GL.TexCoord2(0.0f, 0.0f);
256
                    GL.Vertex2(-1.0f, -1.0f);
257
                    GL.TexCoord2(1.0f, 0.0f);
258
                    GL.Vertex2(1.0f, -1.0f);
259
                    GL.TexCoord2(1.0f, 1.0f);
260
                    GL.Vertex2(1.0f, 1.0f);
261
                }
262
                GL.End();
263
 
264
                // Draw the Depth Texture
265
                GL.Translate(+2.2f, 0f, 0f);
266
                GL.BindTexture(TextureTarget.Texture2D, DepthTexture);
267
                GL.Begin(BeginMode.Quads);
268
                {
269
                    GL.TexCoord2(0f, 1f);
270
                    GL.Vertex2(-1.0f, 1.0f);
271
                    GL.TexCoord2(0.0f, 0.0f);
272
                    GL.Vertex2(-1.0f, -1.0f);
273
                    GL.TexCoord2(1.0f, 0.0f);
274
                    GL.Vertex2(1.0f, -1.0f);
275
                    GL.TexCoord2(1.0f, 1.0f);
276
                    GL.Vertex2(1.0f, 1.0f);
277
                }
278
                GL.End();
279
            }
280
            GL.PopMatrix();
281
 
282
            this.SwapBuffers();
283
        }
284
 
285
        #region public static void Main()
286
 
287
        /// <summary>
288
        /// Entry point of this example.
289
        /// </summary>
290
        [STAThread]
291
        public static void Main()
292
        {
293
            using (SimpleFBO example = new SimpleFBO())
294
            {
295
                Utilities.SetWindowTitle(example);
296
                example.Run(30.0, 0.0);
297
            }
298
        }
299
 
300
        #endregion
301
    }
302
}