Katana Plug-in APIs 0.1

FnDrawable.h

00001 // Copyright (c) 2017 The Foundry Visionmongers Ltd. All Rights Reserved.
00002 
00003 #ifndef FNDRAWABLE_H_
00004 #define FNDRAWABLE_H_
00005 
00006 #include <vector>
00007 #include <FnViewer/plugin/FnGLStateHelper.h>
00008 #include <FnViewer/plugin/FnMathTypes.h>
00009 #include <FnViewer/utils/FnDrawingHelpers.h>
00010 #include <FnViewer/utils/FnImathHelpers.h>
00011 #include <GL/glew.h>
00012 
00013 using Foundry::Katana::ViewerAPI::Vec3f;
00014 using Foundry::Katana::ViewerAPI::Vec2f;
00015 
00016 namespace Foundry
00017 {
00018 namespace Katana
00019 {
00020 namespace ViewerUtils
00021 {
00022 
00023 
00030 class Drawable
00031 {
00032 public:
00033 
00035     enum BUFFER {
00036         VERTEX_BUFFER = 0,
00037         NORMAL_BUFFER,
00038         UV_BUFFER,
00039         INDEX_BUFFER,
00040         NUM_BUFFERS
00041     };
00042 
00044     Drawable()
00045     : m_isReady(false),
00046       m_vao(0),
00047       m_numVertices(0),
00048       m_numIndices(0),
00049       m_lineWidth(1),
00050       m_pointSize(1)
00051     {
00052         m_vbo[VERTEX_BUFFER] = 0;
00053         m_vbo[NORMAL_BUFFER] = 0;
00054         m_vbo[INDEX_BUFFER] = 0;
00055         m_vbo[UV_BUFFER] = 0;
00056     }
00057 
00059     ~Drawable() { cleanup(); }
00060 
00062     bool isReady()
00063     {
00064         return m_isReady;
00065     }
00066 
00068     void setup(
00069         const std::vector<Vec3f>& vertices,
00070         const std::vector<Vec3f>& normals,
00071         const std::vector<unsigned int>& indices,
00072         const std::vector<Vec2f>& uvs = std::vector<Vec2f>())
00073     {
00074         if (isReady())
00075         {
00076             // Do not load it again
00077             return;
00078         }
00079 
00080         // No existing VAO found for this context
00081         glGenVertexArrays(1, &m_vao);
00082         glBindVertexArray(m_vao);
00083 
00084         glGenBuffers(NUM_BUFFERS, &m_vbo[0]);
00085 
00086         // Fill the vertex buffer
00087         glBindBuffer(GL_ARRAY_BUFFER, m_vbo[VERTEX_BUFFER]);
00088         glBufferData(
00089             GL_ARRAY_BUFFER,
00090             vertices.size() * sizeof(Vec3f),
00091             vertices.data(),
00092             GL_STATIC_DRAW);
00093         glVertexAttribPointer(VERTEX_BUFFER, 3, GL_FLOAT, GL_FALSE, 0, 0);
00094         glEnableVertexAttribArray(VERTEX_BUFFER);
00095 
00096         // Fill the normal buffer
00097         glBindBuffer(GL_ARRAY_BUFFER, m_vbo[NORMAL_BUFFER]);
00098         glBufferData(
00099             GL_ARRAY_BUFFER,
00100             normals.size() * sizeof(Vec3f),
00101             normals.data(),
00102             GL_STATIC_DRAW);
00103         glVertexAttribPointer(NORMAL_BUFFER, 3, GL_FLOAT, GL_FALSE, 0, 0);
00104         glEnableVertexAttribArray(NORMAL_BUFFER);
00105 
00106         // Fill the index buffer
00107         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_vbo[INDEX_BUFFER]);
00108         glBufferData(
00109             GL_ELEMENT_ARRAY_BUFFER,
00110             indices.size() * sizeof(unsigned int),
00111             indices.data(),
00112             GL_STATIC_DRAW);
00113 
00114         // Fill the uv buffer
00115         if (!uvs.empty())
00116         {
00117             glBindBuffer(GL_ARRAY_BUFFER, m_vbo[UV_BUFFER]);
00118             glBufferData(
00119                 GL_ARRAY_BUFFER,
00120                 uvs.size() * sizeof(Vec2f),
00121                 uvs.data(),
00122                 GL_STATIC_DRAW);
00123             glVertexAttribPointer(UV_BUFFER, 2, GL_FLOAT, GL_FALSE, 0, 0);
00124             glEnableVertexAttribArray(UV_BUFFER);
00125         }
00126 
00127         // Unbind buffers
00128         glBindVertexArray(0);
00129         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00130         glBindBuffer(GL_ARRAY_BUFFER, 0);
00131 
00132         m_numVertices = static_cast<unsigned int>(vertices.size());
00133         m_numIndices = static_cast<unsigned int>(indices.size());
00134         m_isReady = true;
00135     }
00136 
00137     void cleanup()
00138     {
00139         if (m_vbo[VERTEX_BUFFER])
00140         {
00141             glDeleteBuffers(1, &m_vbo[VERTEX_BUFFER]);
00142             m_vbo[VERTEX_BUFFER] = 0;
00143         }
00144 
00145         if (m_vbo[NORMAL_BUFFER])
00146         {
00147             glDeleteBuffers(1, &m_vbo[NORMAL_BUFFER]);
00148             m_vbo[NORMAL_BUFFER] = 0;
00149         }
00150 
00151         if (m_vbo[INDEX_BUFFER])
00152         {
00153             glDeleteBuffers(1, &m_vbo[INDEX_BUFFER]);
00154             m_vbo[INDEX_BUFFER] = 0;
00155         }
00156 
00157         if (m_vbo[UV_BUFFER])
00158         {
00159             glDeleteBuffers(1, &m_vbo[UV_BUFFER]);
00160             m_vbo[UV_BUFFER] = 0;
00161         }
00162 
00163         if (glIsVertexArray(m_vao))
00164         {
00165             glDeleteVertexArrays(1, &m_vao);
00166             m_vao = 0;
00167         }
00168 
00169         m_isReady = false;
00170     }
00171 
00173     void updateVertices(const std::vector<Vec3f>& vertices)
00174     {
00175         updateVertices(vertices.data(), vertices.size());
00176     }
00177 
00179     void updateVertices(const Vec3f* const vertices,
00180                         const std::size_t numberOfVertices)
00181     {
00182         if (!isReady())
00183         {
00184             // Do not update if it hasn't been created yet
00185             return;
00186         }
00187 
00188         // Update the vertex data
00189         glBindBuffer(GL_ARRAY_BUFFER, m_vbo[VERTEX_BUFFER]);
00190         glBufferData(
00191             GL_ARRAY_BUFFER,
00192             numberOfVertices * sizeof(Vec3f),
00193             vertices,
00194             GL_STATIC_DRAW);
00195         glBindBuffer(GL_ARRAY_BUFFER, 0);
00196     }
00197 
00199     void setLineWidth(unsigned int width)
00200     {
00201         m_lineWidth = width;
00202     }
00203 
00205     void setPointWidth(unsigned int size)
00206     {
00207         m_pointSize = size;
00208     }
00209 
00211     void draw(bool withTransparency = true,
00212               bool cull = true)
00213     {
00214         if (!isReady())
00215         {
00216             // Not loaded yet, don't render
00217             return;
00218         }
00219 
00220         ViewerUtils::GLStateRestore glStateRestore(ViewerUtils::ColorBuffer |
00221                                                    ViewerUtils::Polygon);
00222 
00223         if (withTransparency)
00224         {
00225             // Enable alpha
00226             glEnable(GL_BLEND);             // ViewerUtils::ColorBuffer
00227             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00228         }
00229 
00230         // Update culling
00231         if (cull)
00232             glEnable(GL_CULL_FACE);         // ViewerUtils::Polygon
00233         else
00234             glDisable(GL_CULL_FACE);        // ViewerUtils::Polygon
00235 
00236 
00237         // Draw the VAO
00238         glBindVertexArray(m_vao);
00239         glDrawElements(GL_TRIANGLES, m_numIndices, GL_UNSIGNED_INT, 0);
00240         glBindVertexArray(0);
00241     }
00242 
00244     void drawLines(bool withTransparency=true)
00245     {
00246         if (!isReady())
00247         {
00248             // Not loaded yet, don't render
00249             return;
00250         }
00251 
00252         ViewerUtils::GLStateRestore glStateRestore(ViewerUtils::ColorBuffer |
00253                                                    ViewerUtils::Line);
00254 
00255         if (withTransparency)
00256         {
00257             // Enable alpha
00258             glEnable(GL_BLEND);             // // ViewerUtils::ColorBuffer
00259             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00260         }
00261 
00262         glLineWidth(static_cast<GLfloat>(m_lineWidth));
00263 
00264         glBindVertexArray(m_vao);
00265         glDrawElements(GL_LINES, m_numIndices, GL_UNSIGNED_INT, 0);
00266         glBindVertexArray(0);
00267     }
00268 
00270     void drawPoints(bool withTransparency=true)
00271     {
00272         if (!isReady())
00273         {
00274             // Not loaded yet, don't render
00275             return;
00276         }
00277 
00278         ViewerUtils::GLStateRestore glStateRestore(ViewerUtils::ColorBuffer |
00279                                                    ViewerUtils::Point);
00280 
00281         if (withTransparency)
00282         {
00283             // Enable alpha
00284             glEnable(GL_BLEND);             // ViewerUtils::ColorBuffer
00285             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00286         }
00287 
00288         glPointSize(static_cast<GLfloat>(m_pointSize));
00289 
00290         glBindVertexArray(m_vao);
00291         glDrawElements(GL_POINTS, m_numIndices, GL_UNSIGNED_INT, 0);
00292         glBindVertexArray(0);
00293     }
00294 
00295 
00296 private:
00297     bool m_isReady;
00298     GLuint m_vao;
00299     GLuint m_vbo[NUM_BUFFERS];
00300     unsigned int m_numVertices;
00301     unsigned int m_numIndices;
00302     unsigned int m_lineWidth;
00303     unsigned int m_pointSize;
00304 };
00305 
00306 }
00307 }
00308 }
00309 
00310 #endif /* FNDRAWABLE_H_ */
 All Classes Functions Variables Typedefs Enumerations Enumerator