Opentk/Source/Examples/Tutorial/T08_VBO.cs

247 lines
7 KiB
C#

#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
#region --- Using directives ---
using System;
using System.Collections.Generic;
using System.Text;
using OpenTK;
using OpenTK.OpenGL;
using OpenTK.Platform;
using System.Threading;
#endregion
namespace Examples.Tutorial
{
public class T08_VBO : OpenTK.GameWindow /*, IExample */
{
#region --- Private Fields ---
int vbo, ibo, nbo; // vertex, index and normal buffer objects.
float angle;
// Cube vertices
float[] vdata =
{
-1.0f, -1.0f, 1.0f ,
1.0f, -1.0f, 1.0f ,
1.0f, 1.0f, 1.0f ,
-1.0f, 1.0f, 1.0f ,
-1.0f, -1.0f, -1.0f ,
1.0f, -1.0f, -1.0f ,
1.0f, 1.0f, -1.0f ,
-1.0f, 1.0f, -1.0f ,
};
// Cube normals
float[,] ndata =
{
{ 1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f },
{ -1.0f, 0.0f, 0.0f },
{ 0.0f, -1.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f },
};
// Indices
ushort[] idata =
{
// front face
0, 1, 2, 3,
// top face
3, 4, 6, 7,
// back face
7, 6, 5, 4,
// left face
4, 0, 3, 7,
// bottom face
0, 1, 5, 4,
// right face
1, 5, 6, 2,
};
#endregion
#region --- Constructor ---
public T08_VBO()
{
this.CreateWindow(new DisplayMode(800, 600));
}
#endregion
#region OnLoad
public override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!GL.SupportsExtension("VERSION_1_4"))
{
System.Windows.Forms.MessageBox.Show("You need at least OpenGL 1.4 to run this example. Aborting.", "VBOs not supported",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation);
this.Exit();
}
GL.ClearColor(0.1f, 0.1f, 0.5f, 0.0f);
GL.Enable(GL.Enums.EnableCap.DEPTH_TEST);
GL.EnableClientState(GL.Enums.EnableCap.VERTEX_ARRAY);
GL.EnableClientState(GL.Enums.EnableCap.INDEX_ARRAY);
LoadCube();
this.OnResize(new ResizeEventArgs(this.Width, this.Height));
}
#endregion
#region OnResize
protected override void OnResize(OpenTK.Platform.ResizeEventArgs e)
{
base.OnResize(e);
GL.Viewport(0, 0, Width, Height);
double ratio = e.Width / (double)e.Height;
GL.MatrixMode(GL.Enums.MatrixMode.PROJECTION);
GL.LoadIdentity();
Glu.Perspective(45.0, ratio, 1.0, 64.0);
}
#endregion
#region OnUpdateFrame
/// <summary>
/// Prepares the next frame for rendering.
/// </summary>
/// <remarks>
/// Place your control logic here. This is the place to respond to user input,
/// update object positions etc.
/// </remarks>
public override void OnUpdateFrame(UpdateFrameEventArgs e)
{
if (Keyboard[OpenTK.Input.Key.Escape])
{
this.Exit();
return;
}
GL.MatrixMode(GL.Enums.MatrixMode.MODELVIEW);
GL.LoadIdentity();
Glu.LookAt(
0.0, 5.0, 5.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0
);
//GL.Rotatef(angle, 0.0f, 1.0f, 0.0f);
//angle += 0.5f;
}
#endregion
#region OnRenderFrame
public override void OnRenderFrame(RenderFrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Clear(
GL.Enums.ClearBufferMask.COLOR_BUFFER_BIT |
GL.Enums.ClearBufferMask.DEPTH_BUFFER_BIT);
GL.BindBuffer(GL.Enums.VERSION_1_5.ARRAY_BUFFER, vbo);
GL.VertexPointer(3, GL.Enums.VertexPointerType.FLOAT, 0, 0);
GL.BindBuffer(GL.Enums.VERSION_1_5.ELEMENT_ARRAY_BUFFER, ibo);
GL.IndexPointer(GL.Enums.IndexPointerType.FLOAT, 0, 0);
GL.Color3(1.0f, 1.0f, 1.0f);
GL.DrawElements(
GL.Enums.BeginMode.QUADS,
idata.Length,
GL.Enums.All.UNSIGNED_SHORT,
idata);
GL.BindBuffer(GL.Enums.VERSION_1_5.ARRAY_BUFFER, 0);
GL.BindBuffer(GL.Enums.VERSION_1_5.ELEMENT_ARRAY_BUFFER, 0);
Context.SwapBuffers();
Thread.Sleep(0);
}
#endregion
#region LoadCube
private void LoadCube()
{
int size; // To check whether the buffers were uploaded correctly.
//GL.
// First, generate the buffer objects
GL.GenBuffers(1, out vbo);
GL.GenBuffers(1, out ibo);
// Upload the vertex data
GL.BindBuffer(GL.Enums.VERSION_1_5.ARRAY_BUFFER, vbo);
GL.BufferData(
GL.Enums.VERSION_1_5.ARRAY_BUFFER,
(IntPtr)(vdata.Length * 4),
vdata,
GL.Enums.VERSION_1_5.STATIC_DRAW);
GL.GetBufferParameter(
GL.Enums.VERSION_1_5.ARRAY_BUFFER,
GL.Enums.VERSION_1_5.BUFFER_SIZE,
out size);
if (vdata.Length * 4 != size)
{
throw new ApplicationException("Vertex array not uploaded correctly");
}
// Upload the index data
GL.BindBuffer(GL.Enums.VERSION_1_5.ELEMENT_ARRAY_BUFFER, ibo);
GL.BufferData(
GL.Enums.VERSION_1_5.ELEMENT_ARRAY_BUFFER,
(IntPtr)(idata.Length * 2),
idata,
GL.Enums.VERSION_1_5.STATIC_DRAW
);
GL.GetBufferParameter(
GL.Enums.VERSION_1_5.ELEMENT_ARRAY_BUFFER,
GL.Enums.VERSION_1_5.BUFFER_SIZE,
out size);
if (idata.Length * 2 != size)
{
throw new ApplicationException("Index array not uploaded correctly");
}
}
#endregion
#region public void Launch()
/// <summary>
/// Launches this example.
/// </summary>
/// <remarks>
/// Provides a simple way for the example launcher to launch the examples.
/// </remarks>
public void Launch()
{
Run(60.0, 60.0);
}
#endregion
}
}