|
Katana Plug-in APIs 0.1
|
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_ */
1.7.3