From e9b4985dbd3ad745c06cf2651e6000f2d155a3cc Mon Sep 17 00:00:00 2001
From: Sam Hocevar <sam@hocevar.net>
Date: Mon, 25 Feb 2013 19:43:51 +0000
Subject: [PATCH] gpu: add MeshPrimitive::Lines enum and modify the cube
 tutorial to show how it can be used.

---
 src/gpu/vertexbuffer.cpp   | 18 +++++++++++++
 src/lol/gpu/vertexbuffer.h |  1 +
 tutorial/02_cube.cpp       | 55 +++++++++++++++++++++++---------------
 3 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/src/gpu/vertexbuffer.cpp b/src/gpu/vertexbuffer.cpp
index 5dc0ceb6..f4e75332 100644
--- a/src/gpu/vertexbuffer.cpp
+++ b/src/gpu/vertexbuffer.cpp
@@ -154,6 +154,11 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count)
                                               skip, count)))
             Abort();
         break;
+    case MeshPrimitive::Lines:
+        if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_LINELIST,
+                                              skip, count)))
+            Abort();
+        break;
     }
 #else
     /* FIXME: this has nothing to do here! */
@@ -175,6 +180,9 @@ void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count)
     case MeshPrimitive::Points:
         glDrawArrays(GL_POINTS, skip, count);
         break;
+    case MeshPrimitive::Lines:
+        glDrawArrays(GL_LINES, skip, count);
+        break;
     }
 #endif
 }
@@ -217,6 +225,11 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
                                            vbase, vskip, vcount, skip, count)))
             Abort();
         break;
+    case MeshPrimitive::Lines:
+        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_LINELIST,
+                                           vbase, vskip, vcount, skip, count)))
+            Abort();
+        break;
     }
 #else
     /* FIXME: this has nothing to do here! */
@@ -246,6 +259,11 @@ void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
         (void)vbase; (void)vskip; (void)vcount; (void)skip;
         glDrawElements(GL_POINTS, count, GL_UNSIGNED_SHORT, 0);
         break;
+    case MeshPrimitive::Lines:
+        /* FIXME: ignores most of the arguments! */
+        (void)vbase; (void)vskip; (void)vcount; (void)skip;
+        glDrawElements(GL_LINES, count, GL_UNSIGNED_SHORT, 0);
+        break;
     }
 #endif
 }
diff --git a/src/lol/gpu/vertexbuffer.h b/src/lol/gpu/vertexbuffer.h
index 15592742..c54c1cf7 100644
--- a/src/lol/gpu/vertexbuffer.h
+++ b/src/lol/gpu/vertexbuffer.h
@@ -76,6 +76,7 @@ struct MeshPrimitive
         TriangleStrips,
         TriangleFans,
         Points,
+        Lines,
     }
     m_value;
 
diff --git a/tutorial/02_cube.cpp b/tutorial/02_cube.cpp
index 60d48488..50564be8 100644
--- a/tutorial/02_cube.cpp
+++ b/tutorial/02_cube.cpp
@@ -38,18 +38,16 @@ public:
         m_mesh.Push(vec3( 1.0,  1.0, -1.0), vec3(0.0, 0.5, 1.0));
         m_mesh.Push(vec3(-1.0,  1.0, -1.0), vec3(0.0, 0.0, 1.0));
 
-        m_indices << i16vec3(0, 1, 2);
-        m_indices << i16vec3(2, 3, 0);
-        m_indices << i16vec3(1, 5, 6);
-        m_indices << i16vec3(6, 2, 1);
-        m_indices << i16vec3(7, 6, 5);
-        m_indices << i16vec3(5, 4, 7);
-        m_indices << i16vec3(4, 0, 3);
-        m_indices << i16vec3(3, 7, 4);
-        m_indices << i16vec3(4, 5, 1);
-        m_indices << i16vec3(1, 0, 4);
-        m_indices << i16vec3(3, 2, 6);
-        m_indices << i16vec3(6, 7, 3);
+        m_faces_indices << 0 << 1 << 2 << 2 << 3 << 0;
+        m_faces_indices << 1 << 5 << 6 << 6 << 2 << 1;
+        m_faces_indices << 7 << 6 << 5 << 5 << 4 << 7;
+        m_faces_indices << 4 << 0 << 3 << 3 << 7 << 4;
+        m_faces_indices << 4 << 5 << 1 << 1 << 0 << 4;
+        m_faces_indices << 3 << 2 << 6 << 6 << 7 << 3;
+
+        m_lines_indices << 0 << 1 << 1 << 2 << 2 << 3 << 3 << 0;
+        m_lines_indices << 4 << 5 << 5 << 6 << 6 << 7 << 7 << 4;
+        m_lines_indices << 0 << 4 << 1 << 5 << 2 << 6 << 3 << 7;
 
         m_ready = false;
     }
@@ -91,10 +89,15 @@ public:
             memcpy(mesh, &m_mesh[0], m_mesh.Bytes());
             m_vbo->Unlock();
 
-            m_ibo = new IndexBuffer(m_indices.Bytes());
-            void *indices = m_ibo->Lock(0, 0);
-            memcpy(indices, &m_indices[0], m_indices.Bytes());
-            m_ibo->Unlock();
+            m_lines_ibo = new IndexBuffer(m_lines_indices.Bytes());
+            void *indices = m_lines_ibo->Lock(0, 0);
+            memcpy(indices, &m_lines_indices[0], m_lines_indices.Bytes());
+            m_lines_ibo->Unlock();
+
+            m_faces_ibo = new IndexBuffer(m_faces_indices.Bytes());
+            indices = m_faces_ibo->Lock(0, 0);
+            memcpy(indices, &m_faces_indices[0], m_faces_indices.Bytes());
+            m_faces_ibo->Unlock();
 
             /* FIXME: this object never cleans up */
             m_ready = true;
@@ -103,13 +106,21 @@ public:
         Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));
 
         m_shader->Bind();
-        m_shader->SetUniform(m_mvp, m_matrix);
         m_vdecl->SetStream(m_vbo, m_coord, m_color);
         m_vdecl->Bind();
-        m_ibo->Bind();
+
+        m_shader->SetUniform(m_mvp, m_matrix);
+        m_lines_ibo->Bind();
+        m_vdecl->DrawIndexedElements(MeshPrimitive::Lines, 0, 0,
+                                     m_mesh.Count(), 0, m_lines_indices.Count());
+        m_lines_ibo->Unbind();
+
+        m_shader->SetUniform(m_mvp, m_matrix * mat4::scale(0.5f));
+        m_faces_ibo->Bind();
         m_vdecl->DrawIndexedElements(MeshPrimitive::Triangles, 0, 0,
-                                     m_mesh.Count(), 0, m_indices.Count() * 3);
-        m_ibo->Unbind();
+                                     m_mesh.Count(), 0, m_faces_indices.Count());
+        m_faces_ibo->Unbind();
+
         m_vdecl->Unbind();
     }
 
@@ -117,14 +128,14 @@ private:
     float m_angle;
     mat4 m_matrix;
     Array<vec3,vec3> m_mesh;
-    Array<i16vec3> m_indices;
+    Array<uint16_t> m_lines_indices, m_faces_indices;
 
     Shader *m_shader;
     ShaderAttrib m_coord, m_color;
     ShaderUniform m_mvp;
     VertexDeclaration *m_vdecl;
     VertexBuffer *m_vbo;
-    IndexBuffer *m_ibo;
+    IndexBuffer *m_lines_ibo, *m_faces_ibo;
 
     bool m_ready;
 };