From 9a6bc64381434e631c96358cba19159697b873a3 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <coelckers@zdoom.fake>
Date: Tue, 1 Jul 2014 00:51:02 +0200
Subject: [PATCH] - use vertex array objects to manage vertex buffers.

---
 src/gl/data/gl_vertexbuffer.cpp | 42 ++++++++++++++++-----------------
 src/gl/data/gl_vertexbuffer.h   |  6 ++---
 src/gl/models/gl_models.cpp     | 24 +++++--------------
 src/gl/scene/gl_skydome.cpp     | 15 +++++-------
 4 files changed, 34 insertions(+), 53 deletions(-)

diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp
index b6d33dacd..d9d96c855 100644
--- a/src/gl/data/gl_vertexbuffer.cpp
+++ b/src/gl/data/gl_vertexbuffer.cpp
@@ -58,8 +58,10 @@
 
 FVertexBuffer::FVertexBuffer()
 {
-	vbo_id = 0;
+	vao_id = vbo_id = 0;
 	glGenBuffers(1, &vbo_id);
+	glGenVertexArrays(1, &vao_id);
+
 }
 	
 FVertexBuffer::~FVertexBuffer()
@@ -68,6 +70,15 @@ FVertexBuffer::~FVertexBuffer()
 	{
 		glDeleteBuffers(1, &vbo_id);
 	}
+	if (vao_id != 0)
+	{
+		glDeleteVertexArrays(1, &vao_id);
+	}
+}
+
+void FVertexBuffer::BindVBO()
+{
+	glBindVertexArray(vao_id);
 }
 
 //==========================================================================
@@ -100,6 +111,14 @@ FFlatVertexBuffer::FFlatVertexBuffer()
 		glBufferData(GL_ARRAY_BUFFER, 20 * sizeof(FFlatVertex), fill, GL_STATIC_DRAW);
 	}
 	mIndex = mCurIndex = 0;
+
+	glBindVertexArray(vao_id);
+	glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
+	glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x);
+	glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+	glBindVertexArray(0);
 }
 
 FFlatVertexBuffer::~FFlatVertexBuffer()
@@ -370,27 +389,6 @@ void FFlatVertexBuffer::CreateVBO()
 //
 //==========================================================================
 
-void FFlatVertexBuffer::BindVBO()
-{
-	//if (gl.flags & RFL_BUFFER_STORAGE)
-	{
-		glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
-		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-		glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x);
-		glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u);
-		glEnableClientState(GL_VERTEX_ARRAY);
-		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-		glDisableClientState(GL_COLOR_ARRAY);
-		glDisableVertexAttribArray(VATTR_VERTEX2);
-	}
-}
-
-//==========================================================================
-//
-//
-//
-//==========================================================================
-
 void FFlatVertexBuffer::CheckPlanes(sector_t *sector)
 {
 	if (gl.flags & RFL_BUFFER_STORAGE)
diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h
index a183a7a2e..d9e259db6 100644
--- a/src/gl/data/gl_vertexbuffer.h
+++ b/src/gl/data/gl_vertexbuffer.h
@@ -15,11 +15,12 @@ class FVertexBuffer
 {
 protected:
 	unsigned int vbo_id;
+	unsigned int vao_id;
 
 public:
 	FVertexBuffer();
 	virtual ~FVertexBuffer();
-	virtual void BindVBO() = 0;
+	void BindVBO();
 };
 
 struct FFlatVertex
@@ -60,7 +61,6 @@ public:
 	~FFlatVertexBuffer();
 
 	void CreateVBO();
-	void BindVBO();
 	void CheckUpdate(sector_t *sector);
 
 	FFlatVertex *GetBuffer()
@@ -162,7 +162,6 @@ public:
 
 	FSkyVertexBuffer();
 	virtual ~FSkyVertexBuffer();
-	virtual void BindVBO();
 	void RenderDome(FMaterial *tex, int mode);
 
 };
@@ -203,7 +202,6 @@ public:
 	FModelVertexBuffer();
 	~FModelVertexBuffer();
 
-	void BindVBO();
 	unsigned int SetupFrame(unsigned int frame1, unsigned int frame2, float factor);
 };
 
diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp
index f6aad15fa..67ec241e3 100644
--- a/src/gl/models/gl_models.cpp
+++ b/src/gl/models/gl_models.cpp
@@ -109,11 +109,17 @@ FModelVertexBuffer::FModelVertexBuffer()
 		Models[i]->BuildVertexBuffer(this);
 	}
 
+	glBindVertexArray(vao_id);
+
 	glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
 	glBufferData(GL_ARRAY_BUFFER,vbo_shadowdata.Size() * sizeof(FModelVertex), &vbo_shadowdata[0], GL_STATIC_DRAW);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
 	glBufferData(GL_ELEMENT_ARRAY_BUFFER,ibo_shadowdata.Size() * sizeof(unsigned int), &ibo_shadowdata[0], GL_STATIC_DRAW);
 
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+	glEnableVertexAttribArray(VATTR_VERTEX2);
+	glBindVertexArray(0);
 }
 
 FModelVertexBuffer::~FModelVertexBuffer()
@@ -125,24 +131,6 @@ FModelVertexBuffer::~FModelVertexBuffer()
 }
 
 
-//===========================================================================
-//
-//
-//
-//===========================================================================
-
-void FModelVertexBuffer::BindVBO()
-{
-	glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
-	//glVertexPointer(3, GL_FLOAT, sizeof(FModelVertex), &VMO->x);
-	//glTexCoordPointer(2, GL_FLOAT, sizeof(FModelVertex), &VMO->u);
-	glEnableClientState(GL_VERTEX_ARRAY);
-	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-	glDisableClientState(GL_COLOR_ARRAY);
-	glEnableVertexAttribArray(VATTR_VERTEX2);
-}
-
 //===========================================================================
 //
 // Sets up the buffer starts for frame interpolation
diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp
index 0d9026ea6..221f2203b 100644
--- a/src/gl/scene/gl_skydome.cpp
+++ b/src/gl/scene/gl_skydome.cpp
@@ -77,25 +77,22 @@ extern int skyfog;
 FSkyVertexBuffer::FSkyVertexBuffer()
 {
 	CreateDome();
-}
 
-FSkyVertexBuffer::~FSkyVertexBuffer()
-{
-}
-
-void FSkyVertexBuffer::BindVBO()
-{
+	glBindVertexArray(vao_id);
 	glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 	glVertexPointer(3, GL_FLOAT, sizeof(FSkyVertex), &VSO->x);
 	glTexCoordPointer(2, GL_FLOAT, sizeof(FSkyVertex), &VSO->u);
 	glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(FSkyVertex), &VSO->color);
 	glEnableClientState(GL_VERTEX_ARRAY);
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 	glEnableClientState(GL_COLOR_ARRAY);
-	glDisableVertexAttribArray(VATTR_VERTEX2);
+	glBindVertexArray(0);
+
 }
 
+FSkyVertexBuffer::~FSkyVertexBuffer()
+{
+}
 
 //-----------------------------------------------------------------------------
 //