/*If the app draws many different kinds of models, reconfiguring the pipeline may become a bottleneck. * Instead, use a vertex array object to store a complete attribute configuration. * Each configuration is independent of the other; each vertex array object can reference a different set of vertex attributes, * which can be stored in the same vertex buffer object or split across several vertex buffer objects. * https://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html#//apple_ref/doc/uid/TP40008793-CH107-SW1 */ public static void ConfigureVertexArrayObject(out int vao, VBOUtil.Vbo vbo) { if (vbo.VertexBufferID == 0 || vbo.ElementBufferID == 0) { vao = 0; return; } // Create and bind the vertex array object. GL.GenVertexArrays(1, out vao); GL.BindVertexArray(vao); // Vertex Array Buffer { // Bind to the Array Buffer ID GL.BindBuffer(BufferTarget.ArrayBuffer, vbo.VertexBufferID); GL.EnableVertexAttribArray(0); //Position GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), IntPtr.Zero); GL.EnableVertexAttribArray(1); //Texture Coordinates GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), (IntPtr)(IntPtr.Zero + 3 * sizeof(float))); GL.EnableVertexAttribArray(2); //Normal GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), (IntPtr)(IntPtr.Zero + 3 * sizeof(float) + 2 * sizeof(float))); //TO BE REMOVED WHEN SHADERS ARE INTRODUCED /* * // Set the Pointer to the current bound array describing how the data ia stored * GL.TexCoordPointer(2, TexCoordPointerType.Float, 8 * sizeof(float), (IntPtr)(IntPtr.Zero + 3 * sizeof(float))); * * // Enable the client state so it will use this array buffer pointer * GL.EnableClientState(ArrayCap.TextureCoordArray); * * // Set the Pointer to the current bound array describing how the data ia stored * GL.NormalPointer(NormalPointerType.Float, 8 * sizeof(float), (IntPtr)(IntPtr.Zero + 3 * sizeof(float) + 2 * sizeof(float))); * * // Enable the client state so it will use this array buffer pointer * GL.EnableClientState(ArrayCap.NormalArray); */ } // Element Array Buffer { // Bind to the Array Buffer ID GL.BindBuffer(BufferTarget.ElementArrayBuffer, vbo.ElementBufferID); } // Bind back to the default state. GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindVertexArray(0); }
int vao; //array buffer object //Constructor to be used with VBO concept. Only single texture used. DisplayList not neaded any longer. public SkyBox(float aSize) { mSize = aSize; if (skyBoxTexturePath != null) { skyBoxSingleTexture = TextureManager.LoadTexture(skyBoxTexturePath); } //Using VBO concept instead of DisplayList // loading Vertex Buffers Shape skyBoxShape = new SkyBoxShape(aSize); vbo = VBOUtil.LoadVBO(skyBoxShape); VBOUtil.ConfigureVertexArrayObject(out vao, vbo); }
public static int labelVao; //VOA for file node's labels public static void LoadVBOs() { //Using VBO concept instead of DisplayList // loading Vertex Buffers Shape fileNodeShape = new FileNodeShape(); Shape dirNodeShape = new DirNodeShape(); Shape driveNodeShape = new DriveNodeShape(); vbo[(int)Node.NodeType.FILE_NODE] = VBOUtil.LoadVBO(fileNodeShape); VBOUtil.ConfigureVertexArrayObject(out vao [(int)Node.NodeType.FILE_NODE], vbo [(int)Node.NodeType.FILE_NODE]); vbo[(int)Node.NodeType.DIR_NODE] = VBOUtil.LoadVBO(dirNodeShape); VBOUtil.ConfigureVertexArrayObject(out vao [(int)Node.NodeType.DIR_NODE], vbo [(int)Node.NodeType.DIR_NODE]); vbo[(int)Node.NodeType.DRIVE_NODE] = VBOUtil.LoadVBO(driveNodeShape); VBOUtil.ConfigureVertexArrayObject(out vao [(int)Node.NodeType.DRIVE_NODE], vbo [(int)Node.NodeType.DRIVE_NODE]); Shape labelShape = new LabelShape(); labelVbo = VBOUtil.LoadVBO(labelShape); VBOUtil.ConfigureVertexArrayObjectForLabels(out labelVao, labelVbo); }
//Draw using VAO and VBO, where VAO stores a complete set of attributes for the given VBO public static void Draw(int vao, VBOUtil.Vbo vbo) { // Push current Array Buffer state so we can restore it later //GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit); if (vao != previouslyUsedVao) //To eliminate unnecessary GL calls. { previouslyUsedVao = vao; GL.BindVertexArray(vao); } // Draw the elements in the element array buffer // Draws up items in the Color, Vertex, TexCoordinate, and Normal Buffers using indices in the ElementArrayBuffer //GL.DrawElements(PrimitiveType.Triangles, vbo.NumElements, DrawElementsType.UnsignedInt, IntPtr.Zero); //GL.DrawRangeElements is slightly better performance-wise than GL.DrawElements GL.DrawRangeElements(PrimitiveType.Triangles, 0, vbo.NumElements - 1, vbo.NumElements, DrawElementsType.UnsignedInt, IntPtr.Zero); // Could also call GL.DrawArrays which would ignore the ElementArrayBuffer and just use primitives // Of course we would have to reorder our data to be in the correct primitive order // Restore the state //GL.PopClientAttrib(); }