Blame |
Last modification |
View Log
| RSS feed
#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 System.Runtime.InteropServices;
using System.Threading;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform;
using System.Drawing;
#endregion
namespace Examples
.Tutorial
{
[Example
("VBO Static", ExampleCategory
.OpenGL,
"1.x",
3, Documentation
="VBOStatic")]
public class T08_VBO
: GameWindow
{
const float rotation_speed
= 180
.0f
;
float angle
;
struct Vbo
{ public int VboID, EboID, NumElements
; }
Vbo
[] vbo
= new Vbo
[2];
VertexPositionColor
[] CubeVertices
= new VertexPositionColor
[]
{
new VertexPositionColor
(-1
.0f,
-1
.0f, 1
.0f, Color
.DarkRed),
new VertexPositionColor
( 1
.0f,
-1
.0f, 1
.0f, Color
.DarkRed),
new VertexPositionColor
( 1
.0f, 1
.0f, 1
.0f, Color
.Gold),
new VertexPositionColor
(-1
.0f, 1
.0f, 1
.0f, Color
.Gold),
new VertexPositionColor
(-1
.0f,
-1
.0f,
-1
.0f, Color
.DarkRed),
new VertexPositionColor
( 1
.0f,
-1
.0f,
-1
.0f, Color
.DarkRed),
new VertexPositionColor
( 1
.0f, 1
.0f,
-1
.0f, Color
.Gold),
new VertexPositionColor
(-1
.0f, 1
.0f,
-1
.0f, Color
.Gold)
};
readonly short[] CubeElements
= new short[]
{
0,
1,
2,
2,
3,
0,
// front face
3,
2,
6,
6,
7,
3,
// top face
7,
6,
5,
5,
4,
7,
// back face
4,
0,
3,
3,
7,
4,
// left face
0,
1,
5,
5,
4,
0,
// bottom face
1,
5,
6,
6,
2,
1,
// right face
};
public T08_VBO
() : base(800,
600) { }
protected override void OnLoad
(EventArgs e
)
{
base.OnLoad(e
);
string version
= GL
.GetString(StringName
.Version);
int major
= (int)version
[0];
int minor
= (int)version
[2];
if (major
<= 1 && minor
< 5)
{
System.Windows.Forms.MessageBox.Show("You need at least OpenGL 1.5 to run this example. Aborting.",
"VBOs not supported",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Exclamation);
this.Exit();
}
GL
.ClearColor(System.Drawing.Color.MidnightBlue);
GL
.Enable(EnableCap
.DepthTest);
vbo
[0] = LoadVBO
(CubeVertices, CubeElements
);
vbo
[1] = LoadVBO
(CubeVertices, CubeElements
);
}
protected override void OnResize
(EventArgs e
)
{
base.OnResize(e
);
GL
.Viewport(0,
0, Width, Height
);
float aspect_ratio
= Width
/ (float)Height
;
Matrix4 perpective
= Matrix4
.CreatePerspectiveFieldOfView(MathHelper
.PiOver4, aspect_ratio,
1,
64);
GL
.MatrixMode(MatrixMode
.Projection);
GL
.LoadMatrix(ref perpective
);
}
protected override void OnUpdateFrame
(FrameEventArgs e
)
{
base.OnUpdateFrame(e
);
if (Keyboard
[OpenTK
.Input.Key.Escape])
this.Exit();
}
protected override void OnRenderFrame
(FrameEventArgs e
)
{
base.OnRenderFrame(e
);
GL
.Clear(ClearBufferMask
.ColorBufferBit | ClearBufferMask
.DepthBufferBit);
Matrix4 lookat
= Matrix4
.LookAt(0,
5,
5,
0,
0,
0,
0,
1,
0);
GL
.MatrixMode(MatrixMode
.Modelview);
GL
.LoadMatrix(ref lookat
);
angle
+= rotation_speed
* (float)e
.Time;
GL
.Rotate(angle, 0
.0f, 1
.0f, 0
.0f
);
Draw
(vbo
[0]);
SwapBuffers
();
}
Vbo LoadVBO
<TVertex
>(TVertex
[] vertices,
short[] elements
) where TVertex
: struct
{
Vbo handle
= new Vbo
();
int size
;
// To create a VBO:
// 1) Generate the buffer handles for the vertex and element buffers.
// 2) Bind the vertex buffer handle and upload your vertex data. Check that the buffer was uploaded correctly.
// 3) Bind the element buffer handle and upload your element data. Check that the buffer was uploaded correctly.
GL
.GenBuffers(1,
out handle
.VboID);
GL
.BindBuffer(BufferTarget
.ArrayBuffer, handle
.VboID);
GL
.BufferData(BufferTarget
.ArrayBuffer,
(IntPtr
)(vertices
.Length * BlittableValueType
.StrideOf(vertices
)), vertices,
BufferUsageHint
.StaticDraw);
GL
.GetBufferParameter(BufferTarget
.ArrayBuffer, BufferParameterName
.BufferSize,
out size
);
if (vertices
.Length * BlittableValueType
.StrideOf(vertices
) != size
)
throw new ApplicationException
("Vertex data not uploaded correctly");
GL
.GenBuffers(1,
out handle
.EboID);
GL
.BindBuffer(BufferTarget
.ElementArrayBuffer, handle
.EboID);
GL
.BufferData(BufferTarget
.ElementArrayBuffer,
(IntPtr
)(elements
.Length * sizeof(short)), elements,
BufferUsageHint
.StaticDraw);
GL
.GetBufferParameter(BufferTarget
.ElementArrayBuffer, BufferParameterName
.BufferSize,
out size
);
if (elements
.Length * sizeof(short) != size
)
throw new ApplicationException
("Element data not uploaded correctly");
handle
.NumElements = elements
.Length;
return handle
;
}
void Draw
(Vbo handle
)
{
// To draw a VBO:
// 1) Ensure that the VertexArray client state is enabled.
// 2) Bind the vertex and element buffer handles.
// 3) Set up the data pointers (vertex, normal, color) according to your vertex format.
// 4) Call DrawElements. (Note: the last parameter is an offset into the element buffer
// and will usually be IntPtr.Zero).
GL
.EnableClientState(EnableCap
.ColorArray);
GL
.EnableClientState(EnableCap
.VertexArray);
GL
.BindBuffer(BufferTarget
.ArrayBuffer, handle
.VboID);
GL
.BindBuffer(BufferTarget
.ElementArrayBuffer, handle
.EboID);
GL
.VertexPointer(3, VertexPointerType
.Float, BlittableValueType
.StrideOf(CubeVertices
),
new IntPtr
(0));
GL
.ColorPointer(4, ColorPointerType
.UnsignedByte, BlittableValueType
.StrideOf(CubeVertices
),
new IntPtr
(12));
GL
.DrawElements(BeginMode
.Triangles, handle
.NumElements, DrawElementsType
.UnsignedShort, IntPtr
.Zero);
}
/// <summary>
/// Entry point of this example.
/// </summary>
[STAThread
]
public static void Main
()
{
using (T08_VBO example
= new T08_VBO
())
{
Utilities
.SetWindowTitle(example
);
example
.Run(30.0,
0.0);
}
}
}
}