kick
/Users/morten/Programmering/cpp/kick/src/kick/mesh/mesh.cpp
00001 //
00002 //  mesh.cpp
00003 //  KickCPP
00004 //
00005 //  Created by Morten Nobel-Jørgensen on 07/12/13.
00006 //  Copyright (c) 2013 Morten Nobel-Joergensen. All rights reserved.
00007 //
00008 
00009 #include "kick/mesh/mesh.h"
00010 #include "kick/mesh/mesh_data.h"
00011 #include "kick/core/debug.h"
00012 #include <vector>
00013 #include <set>
00014 
00015 using namespace std;
00016 
00017 namespace kick {
00018     Mesh::Mesh()
00019     {
00020         glGenBuffers(1, &mVertexBufferId);
00021         glGenBuffers(1, &mElementBufferId);
00022     }
00023     
00024     Mesh::~Mesh(){
00025         if (mVertexArrayObject.size()>0){
00026             vector<GLuint> array(mVertexArrayObject.size());
00027             for (auto keyValue : mVertexArrayObject){
00028                 array.push_back(keyValue.second);
00029             }
00030 #ifndef GL_ES_VERSION_2_0
00031             if (openglUsingVao()) {
00032                 glDeleteVertexArrays((GLsizei) array.size(), array.data());
00033             }
00034 #endif
00035         }
00036         glDeleteBuffers(1, &mVertexBufferId);
00037         glDeleteBuffers(1, &mElementBufferId);
00038     }
00039     
00040     void Mesh::bind(Shader * shader){
00041         shader->bind();
00042 
00043 #ifndef GL_ES_VERSION_2_0
00044         if (openglUsingVao()){
00045             auto iter = mVertexArrayObject.find(shader);
00046             if (iter == mVertexArrayObject.end()){
00047                 // create and bind object
00048                 GLuint vertexArrayObjectIdx;
00049 
00050                 glGenVertexArrays(1, &vertexArrayObjectIdx);
00051                 glBindVertexArray(vertexArrayObjectIdx);
00052                 updateArrayBufferStructure(shader);
00053                 mVertexArrayObject[shader] = vertexArrayObjectIdx;
00054             } else {
00055                 GLuint vertexArrayObject = iter->second;
00056                 glBindVertexArray(vertexArrayObject);
00057             }
00058         } else
00059 #endif
00060         {
00061             updateArrayBufferStructure(shader);
00062         }
00063         // reassign buffers
00064         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBufferId);
00065     }
00066     
00067     void Mesh::updateArrayBufferStructure(Shader *shader){
00068         glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferId);
00069         static int maxAtrrSizes = -1;
00070         if (maxAtrrSizes == -1){
00071             glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAtrrSizes);
00072             if (maxAtrrSizes>32){
00073                 maxAtrrSizes = 32;
00074             }
00075         }
00076         bitset<32> enabledArrays;
00077 
00078         for (InterleavedRecord format_record : mInterleavedFormat) {
00079             const AttributeDescriptor * desc = shader->getShaderAttribute(format_record.semantic);
00080             if (desc){
00081                 glEnableVertexAttribArray(desc->index);
00082                 glVertexAttribPointer(desc->index, format_record.size,
00083                                        format_record.type, (GLboolean) format_record.normalized, format_record.stride, format_record.offset);
00084                 enabledArrays[desc->index] = true;
00085             }
00086         }
00087         for (int i=0;i<maxAtrrSizes;i++){
00088             if (enabledArrays[i] == false){
00089                 glDisableVertexAttribArray(i);
00090             }
00091         }
00092     }
00093     
00094     void Mesh::render(unsigned int submeshIndex){
00095         if (submeshIndex >= mSubmeshData.size()){
00096             logWarning("submesh not found");
00097             return;
00098         }
00099         auto data = mSubmeshData[submeshIndex];
00100         GLenum mode = data.mode;
00101         GLsizei count = data.indexCount;
00102         GLenum type = data.type;
00103         const GLvoid * offset = data.dataOffset;
00104 
00105         if (count < 0) {
00106             glDrawArrays(mode, 0, -count);
00107         } else if (count > 0) {
00108             glDrawElements(mode, count, type, offset);
00109         }
00110     }
00111     
00112     std::string Mesh::name(){
00113         return mName;
00114     }
00115     
00116     void Mesh::setName(std::string n){
00117         mName = n;
00118     }
00119 
00120     void Mesh::setMeshData(shared_ptr<MeshData> m){
00121         if (m != nullptr){
00122             mInterleavedFormat = m->interleavedFormat();
00123             mSubmeshData = m->indicesFormat();
00124             updateMeshData(m.get());
00125         } else {
00126             mInterleavedFormat.clear();
00127         }
00128         mMeshData = m;
00129     }
00130     
00131     void Mesh::updateMeshData(MeshData *mesh_data){
00132         vector<float> data = mesh_data->interleavedData();
00133 
00134         if (data.size()){
00135             GLsizeiptr vertexDataSize =data.size()*sizeof(float);
00136             glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferId);
00137             glBufferData(GL_ARRAY_BUFFER, vertexDataSize, data.data(), mesh_data->meshUsageVal());
00138         }
00139 
00140         vector<GLushort> indices = mesh_data->indicesConcat();
00141         if (indices.size()){
00142             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBufferId);
00143             GLsizeiptr indicesSize = indices.size()*sizeof(GLushort);
00144             glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices.data(), mesh_data->meshUsageVal());
00145         }
00146     }
00147 
00148     std::shared_ptr<MeshData> Mesh::meshData() {
00149         return mMeshData;
00150     }
00151 };
 All Classes Functions Variables