File: DrawableShape.cs

package info (click to toggle)
opentk 1.1.4c%2Bdfsg-2.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 68,640 kB
  • sloc: cs: 525,501; xml: 277,501; ansic: 3,597; makefile: 41
file content (181 lines) | stat: -rw-r--r-- 6,255 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
 * See license.txt for license info
 */
#endregion

using System;

using OpenTK;
using OpenTK.Graphics.OpenGL;

namespace Examples.Shapes
{
    // Abstract base class for procedurally generated geometry
    // 
    // All classes derived from it must produce Counter-Clockwise (CCW) primitives.
    // Derived classes must create a single VBO and IBO, without primitive restarts for strips. 
    // Uses an double-precision all-possible-attributes VertexT2dN3dV3d Array internally.
    // Cannot directly use VBO, but has Get-methods to retrieve VBO-friendly data.
    // Can use a Display List to prevent repeated immediate mode draws.
    //

    public abstract class DrawableShape: IDisposable
    {
        protected PrimitiveType PrimitiveMode;
        protected VertexT2dN3dV3d[] VertexArray;
        protected uint[] IndexArray;

        public int GetTriangleCount
        {
            get
            {
                switch ( PrimitiveMode )
                {
                    case PrimitiveType.Triangles:
                    if ( IndexArray != null )
                    {
                        return IndexArray.Length / 3;
                    } else
                    {
                        return VertexArray.Length / 3;
                    }
                  //  break;
                default: throw new NotImplementedException("Unknown primitive type.");
                }
            }
        }

        #region Display List

        private bool UseDisplayList;
        private int DisplayListHandle = 0;

        #endregion Display List

        public DrawableShape( bool useDisplayList )
        {
            UseDisplayList = useDisplayList;
            PrimitiveMode = PrimitiveType.Triangles;
            VertexArray = null;
            IndexArray = null;
        }

        #region Convert to VBO

        public void GetArraysforVBO(out PrimitiveType primitives, out VertexT2dN3dV3d[] vertices, out uint[] indices)
        {
            primitives = PrimitiveMode;

            vertices = new VertexT2dN3dV3d[VertexArray.Length];
            for (uint i = 0; i < VertexArray.Length; i++)
            {
                vertices[i].TexCoord = VertexArray[i].TexCoord;
                vertices[i].Normal = VertexArray[i].Normal;
                vertices[i].Position = VertexArray[i].Position;
            }

            indices = IndexArray;
        }

        public void GetArraysforVBO(out PrimitiveType primitives, out VertexT2fN3fV3f[] vertices, out uint[] indices)
        {
            primitives = PrimitiveMode;

            vertices = new VertexT2fN3fV3f[VertexArray.Length];
            for (uint i = 0; i < VertexArray.Length; i++)
            {
                vertices[i].TexCoord = (Vector2)VertexArray[i].TexCoord;
                vertices[i].Normal = (Vector3)VertexArray[i].Normal;
                vertices[i].Position = (Vector3)VertexArray[i].Position;
            }

            indices = IndexArray;
        }

        public void GetArraysforVBO(out PrimitiveType primitives, out VertexT2hN3hV3h[] vertices, out uint[] indices)
        {
            primitives = PrimitiveMode;

            vertices = new VertexT2hN3hV3h[VertexArray.Length];
            for (uint i = 0; i < VertexArray.Length; i++)
            {
                vertices[i].TexCoord = (Vector2h)VertexArray[i].TexCoord;
                vertices[i].Normal = (Vector3h)VertexArray[i].Normal;
                vertices[i].Position = (Vector3h)VertexArray[i].Position;
            }

            indices = IndexArray;
        }

        #endregion Convert to VBO

        private void DrawImmediateMode()
        {
            GL.Begin( PrimitiveMode );
            {
                if ( IndexArray == null )
                    foreach ( VertexT2dN3dV3d v in VertexArray )
                    {
                        GL.TexCoord2( v.TexCoord.X, v.TexCoord.Y );
                        GL.Normal3( v.Normal.X, v.Normal.Y, v.Normal.Z );
                        GL.Vertex3( v.Position.X, v.Position.Y, v.Position.Z );
                    } else
                {
                    for ( uint i = 0; i < IndexArray.Length; i++ )
                    {
                        uint index = IndexArray[i];
                        GL.TexCoord2( VertexArray[index].TexCoord.X, VertexArray[index].TexCoord.Y );
                        GL.Normal3( VertexArray[index].Normal.X, VertexArray[index].Normal.Y, VertexArray[index].Normal.Z );
                        GL.Vertex3( VertexArray[index].Position.X, VertexArray[index].Position.Y, VertexArray[index].Position.Z );
                    }
                }
            }
            GL.End();
        }

        /// <summary>
        /// Does not touch any state/matrices. Does call Begin/End and Vertex&Co.
        /// Creates and compiles a display list if not present yet. Requires an OpenGL context.
        /// </summary>
        public void Draw()
        {
            if ( !UseDisplayList )
                DrawImmediateMode();
            else
                if ( DisplayListHandle == 0 )
                {
                    if ( VertexArray == null )
                        throw new Exception("Cannot draw null Vertex Array.");
                    DisplayListHandle = GL.GenLists( 1 );
                    GL.NewList( DisplayListHandle, ListMode.CompileAndExecute );
                    DrawImmediateMode();
                    GL.EndList();
                } else
                    GL.CallList( DisplayListHandle );
        }

        #region IDisposable Members

        /// <summary>
        /// Removes reference to VertexArray and IndexArray.
        /// Deletes the Display List, so it requires an OpenGL context.
        /// The instance is effectively destroyed.
        /// </summary>
        public void Dispose()
        {
            if ( VertexArray != null )
                VertexArray = null;
            if ( IndexArray != null )
                IndexArray = null;
            if ( DisplayListHandle != 0 )
            {
                GL.DeleteLists( DisplayListHandle, 1 );
                DisplayListHandle = 0;
            }
        }

        #endregion
    }

}