//---------------------------------------------------------- void ofGLRenderer::draw(ofMesh & vertexData, ofPolyRenderMode renderType, bool useColors, bool useTextures, bool useNormals){ if (bSmoothHinted) startSmoothing(); #ifndef TARGET_OPENGLES glPushAttrib(GL_POLYGON_BIT); glPolygonMode(GL_FRONT_AND_BACK, ofGetGLPolyMode(renderType)); draw(vertexData,useColors,useTextures,useNormals); glPopAttrib(); //TODO: GLES doesnt support polygon mode, add renderType to gl renderer? #else if(vertexData.getNumVertices()){ glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(ofVec3f), vertexData.getVerticesPointer()); } if(vertexData.getNumNormals() && useNormals){ glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, 0, vertexData.getNormalsPointer()); } if(vertexData.getNumColors() && useColors){ glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4,GL_FLOAT, sizeof(ofFloatColor), vertexData.getColorsPointer()); } if(vertexData.getNumTexCoords() && useTextures){ glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, vertexData.getTexCoordsPointer()); } GLenum drawMode; switch(renderType){ case OF_MESH_POINTS: drawMode = GL_POINTS; break; case OF_MESH_WIREFRAME: drawMode = GL_LINES; break; case OF_MESH_FILL: drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); break; default: drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); break; } if(vertexData.getNumIndices()){ glDrawElements(drawMode, vertexData.getNumIndices(),GL_UNSIGNED_SHORT,vertexData.getIndexPointer()); }else{ glDrawArrays(drawMode, 0, vertexData.getNumVertices()); } if(vertexData.getNumColors() && useColors){ glDisableClientState(GL_COLOR_ARRAY); } if(vertexData.getNumNormals() && useNormals){ glDisableClientState(GL_NORMAL_ARRAY); } if(vertexData.getNumTexCoords() && useTextures){ glDisableClientState(GL_TEXTURE_COORD_ARRAY); } #endif if (bSmoothHinted) endSmoothing(); }
void ofxObjLoader::save(string path, ofMesh& mesh){ path = ofToDataPath(path); GLuint writeMode = GLM_NONE; GLMmodel* m = new GLMmodel(); if(mesh.getNumVertices() > 0){ m->numvertices = mesh.getNumVertices(); m->vertices = new GLfloat[m->numvertices*3+1]; memcpy(&m->vertices[3], &mesh.getVertices()[0].x, sizeof(ofVec3f) * mesh.getNumVertices()); } else { ofLogError("ofxObjLoader::save -- No vertices to save!"); return; } if(mesh.getNumNormals() > 0){ m->numnormals = mesh.getNumNormals(); m->normals = new GLfloat[m->numnormals*3+1]; memcpy(&m->normals[3], &mesh.getNormals()[0].x, sizeof(ofVec3f)*mesh.getNumNormals()); writeMode |= GLM_SMOOTH; } if(mesh.getNumTexCoords() > 0){ m->numtexcoords = mesh.getNumTexCoords(); m->texcoords = new GLfloat[m->numtexcoords*2+1]; memcpy(&m->texcoords[2], &mesh.getTexCoords()[0].x, sizeof(ofVec2f)*mesh.getNumTexCoords()); writeMode |= GLM_TEXTURE; } if(mesh.getNumIndices() > 0){ //create triangles m->numtriangles = mesh.getNumIndices()/3; m->triangles = new GLMtriangle[m->numtriangles]; //add them all to one group m->groups = new GLMgroup(); m->groups->next = NULL; m->groups->material = NULL; string name = "ofMesh"; m->groups->name = (char*)malloc(sizeof(char) * name.length()+1); strcpy(m->groups->name, name.c_str()); m->groups->numtriangles = mesh.getNumIndices()/3; m->groups->triangles = new GLuint[m->groups->numtriangles]; m->numgroups = 1; for(int i = 0; i < mesh.getNumIndices()/3; i++){ memcpy(m->triangles[i].vindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3); memcpy(m->triangles[i].nindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3); memcpy(m->triangles[i].tindices, &mesh.getIndices()[i*3], sizeof(GLuint)*3); m->groups->triangles[i] = i; } } glmWriteOBJ(m, (char*)path.c_str(), writeMode); glmDelete(m); }
//-------------------------------------------------------------- void ofVboByteColor::setMesh(const ofMesh & mesh, int usage){ setVertexData(mesh.getVerticesPointer(),mesh.getNumVertices(),usage); setColorData(mesh.getColorsPointer(),mesh.getNumColors(),usage); setNormalData(mesh.getNormalsPointer(),mesh.getNumNormals(),usage); setTexCoordData(mesh.getTexCoordsPointer(),mesh.getNumTexCoords(),usage); setIndexData(mesh.getIndexPointer(), mesh.getNumIndices(), usage); }
//-------------------------------------------------------------- void ofVbo::setMesh(const ofMesh & mesh, int usage, bool useColors, bool useTextures, bool useNormals){ if(mesh.getVertices().empty()){ ofLogWarning("ofVbo") << "setMesh(): ignoring mesh with no vertices"; return; } setVertexData(mesh.getVerticesPointer(),mesh.getNumVertices(),usage); if(mesh.hasColors() && useColors){ setColorData(mesh.getColorsPointer(),mesh.getNumColors(),usage); enableColors(); }else{ disableColors(); } if(mesh.hasNormals() && useNormals){ setNormalData(mesh.getNormalsPointer(),mesh.getNumNormals(),usage); enableNormals(); }else{ disableNormals(); } if(mesh.hasTexCoords() && useTextures){ setTexCoordData(mesh.getTexCoordsPointer(),mesh.getNumTexCoords(),usage); enableTexCoords(); }else{ disableTexCoords(); } if(mesh.hasIndices()){ setIndexData(mesh.getIndexPointer(), mesh.getNumIndices(), usage); enableIndices(); }else{ disableIndices(); } }
ofMesh convertFromIndices(const ofMesh& mesh) { ofMesh result; // have to do a const_cast because ofMesh::get*() is not const correct ofMesh& cmesh = const_cast<ofMesh&>(mesh); int vertices = mesh.getNumVertices(); int colors = mesh.getNumColors(); int normals = mesh.getNumNormals(); int texcoords = mesh.getNumTexCoords(); int indices = mesh.getNumIndices(); for(int i = 0; i < indices; i++) { int cur = cmesh.getIndex(i); if(vertices > 0) { result.addVertex(cmesh.getVertex(cur)); } if(colors > 0) { result.addColor(cmesh.getColor(cur)); } if(normals > 0) { result.addNormal(cmesh.getNormal(cur)); } if(texcoords > 0) { result.addTexCoord(cmesh.getTexCoord(cur)); } } return result; }
//---------------------------------------------------------- void ofGLRenderer::draw(const ofMesh & vertexData, bool useColors, bool useTextures, bool useNormals) const{ if(vertexData.getNumVertices()){ glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(ofVec3f), &vertexData.getVerticesPointer()->x); } if(vertexData.getNumNormals() && useNormals){ glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, sizeof(ofVec3f), &vertexData.getNormalsPointer()->x); } if(vertexData.getNumColors() && useColors){ glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4,GL_FLOAT, sizeof(ofFloatColor), &vertexData.getColorsPointer()->r); } if(vertexData.getNumTexCoords() && useTextures){ set<int>::iterator textureLocation = textureLocationsEnabled.begin(); for(;textureLocation!=textureLocationsEnabled.end();textureLocation++){ glActiveTexture(GL_TEXTURE0+*textureLocation); glClientActiveTexture(GL_TEXTURE0+*textureLocation); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(ofVec2f), &vertexData.getTexCoordsPointer()->x); } glActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0); } if(vertexData.getNumIndices()){ #ifdef TARGET_OPENGLES glDrawElements(ofGetGLPrimitiveMode(vertexData.getMode()), vertexData.getNumIndices(),GL_UNSIGNED_SHORT,vertexData.getIndexPointer()); #else glDrawElements(ofGetGLPrimitiveMode(vertexData.getMode()), vertexData.getNumIndices(),GL_UNSIGNED_INT,vertexData.getIndexPointer()); #endif }else{ glDrawArrays(ofGetGLPrimitiveMode(vertexData.getMode()), 0, vertexData.getNumVertices()); } if(vertexData.getNumColors() && useColors){ glDisableClientState(GL_COLOR_ARRAY); } if(vertexData.getNumNormals() && useNormals){ glDisableClientState(GL_NORMAL_ARRAY); } if(vertexData.getNumTexCoords() && useTextures){ glDisableClientState(GL_TEXTURE_COORD_ARRAY); } }
//---------------------------------------------------------- void ofGLRenderer::draw(ofMesh & vertexData){ if(vertexData.getNumVertices()){ glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(ofVec3f), vertexData.getVerticesPointer()); } if(vertexData.getNumNormals()){ glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, 0, vertexData.getNormalsPointer()); } if(vertexData.getNumColors()){ glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4,GL_FLOAT, sizeof(ofColor), vertexData.getColorsPointer()); } if(vertexData.getNumTexCoords()){ glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, vertexData.getTexCoordsPointer()); } if(vertexData.getNumIndices()){ #ifdef TARGET_OPENGLES glDrawElements(ofGetGLPrimitiveMode(vertexData.getMode()), vertexData.getNumIndices(),GL_UNSIGNED_SHORT,vertexData.getIndexPointer()); #else glDrawElements(ofGetGLPrimitiveMode(vertexData.getMode()), vertexData.getNumIndices(),GL_UNSIGNED_INT,vertexData.getIndexPointer()); #endif }else{ glDrawArrays(ofGetGLPrimitiveMode(vertexData.getMode()), 0, vertexData.getNumVertices()); } if(vertexData.getNumColors()){ glDisableClientState(GL_COLOR_ARRAY); } if(vertexData.getNumNormals()){ glDisableClientState(GL_NORMAL_ARRAY); } if(vertexData.getNumTexCoords()){ glDisableClientState(GL_TEXTURE_COORD_ARRAY); } }
ofMesh convertToIndices(const ofMesh& mesh){ ofMesh result; ofMesh& cmesh = const_cast<ofMesh&>(mesh); int vertices = mesh.getNumVertices(); int colors = mesh.getNumColors(); int normals = mesh.getNumNormals(); int texcoords = mesh.getNumTexCoords(); //int indices = mesh.getNumIndices(); for (int i = 0; i < vertices; i++){ // check if this vertex already exists. //int who = isPointInVector( } }
void CloudsVisualSystem3DModelLoader::facetMesh( ofMesh& smoothedMesh, ofMesh& targetMesh ) { //get our vertex, uv and face info vector<ofVec3f>& v = smoothedMesh.getVertices(); vector<ofVec2f>& uv = smoothedMesh.getTexCoords(); vector<ofIndexType>& indices = smoothedMesh.getIndices(); bool hasTC = smoothedMesh.getNumTexCoords(); //use these to store our new mesh info vector<ofVec3f> facetedVertices( indices.size() ); vector<ofVec3f> facetedNormals( indices.size() ); vector<ofVec2f> facetedTexCoords; if(hasTC){ facetedTexCoords.resize( indices.size() ); } vector<ofIndexType> facetedIndices( indices.size() ); //store vertex and uv data for (int i=0; i < indices.size(); i++) { facetedIndices[i] = i; facetedVertices[i] = v[indices[i]]; if(hasTC) facetedTexCoords[i] = uv[indices[i]]; } //calculate our face normals ofVec3f n; for (int i=0; i < facetedIndices.size(); i+=3) { n = normalFrom3Points( facetedVertices[i], facetedVertices[i+1], facetedVertices[i+2]); facetedNormals[i] = n; facetedNormals[i+1] = n; facetedNormals[i+2] = n; } //setup our faceted mesh. this should still work if our targetMesh is our smoothMesh targetMesh.clear(); targetMesh.addVertices( facetedVertices ); targetMesh.addNormals( facetedNormals ); if(hasTC) targetMesh.addTexCoords( facetedTexCoords ); targetMesh.addIndices( facetedIndices ); }
Handle <Device::RTShape> Renderer::addMesh(Device::RTMaterial material, const ofMesh & meshPr, const ofMatrix4x4& transform) { int vertsNum = meshPr.getNumVertices(); int vertsSize = vertsNum * sizeof(ofVec3f); Device::RTData positions = g_device->rtNewData("immutable_managed", vertsSize, meshPr.getVerticesPointer()); int normalsNum = meshPr.getNumNormals(); int normalsSize = normalsNum * sizeof(ofVec3f); Device::RTData normals = g_device->rtNewData("immutable_managed", normalsSize, meshPr.getNormalsPointer()); int textcoordsNum = meshPr.getNumTexCoords(); int textcoordsSize = textcoordsNum * sizeof(ofVec2f); Device::RTData texcoords = g_device->rtNewData("immutable_managed", textcoordsSize, meshPr.getTexCoordsPointer()); int indicesNum = meshPr.getNumIndices(); int indicesSize = indicesNum * sizeof(ofIndexType); Device::RTData triangles = g_device->rtNewData("immutable_managed", indicesSize, meshPr.getIndexPointer()); Handle <Device::RTShape> mesh = device->rtNewShape("trianglemesh"); if(vertsNum) { g_device->rtSetArray(mesh, "positions", "float3", positions, vertsNum, sizeof(ofVec3f), 0); } if(normalsNum) { g_device->rtSetArray(mesh, "normals", "float3", normals, normalsNum, sizeof(ofVec3f), 0); } if(textcoordsNum) { g_device->rtSetArray(mesh, "texcoords", "float2", texcoords, textcoordsNum, sizeof(ofVec2f), 0); } if(indicesNum) { g_device->rtSetArray(mesh, "indices", "int3", triangles, indicesNum / 3, 3 * sizeof(ofIndexType), 0); } device->rtCommit(mesh); device->rtClear(mesh); return addShape(material, mesh, transform); }
//-------------------------------------------------------------- void save(const string& path, const ofMesh& mesh) { ofFile file(path, ofFile::WriteOnly, true); int numVerts = mesh.getNumVertices(); file.write((char *)(&numVerts), sizeof(int)); if (numVerts > 0) { file.write((char *)(&(mesh.getVertices())[0]), sizeof(ofPoint) * numVerts); } int numNormals = mesh.getNumNormals(); file.write((char *)(&numNormals), sizeof(int)); if (numNormals > 0) { file.write((char *)(&(mesh.getNormals())[0]), sizeof(ofPoint) * numNormals); } int numTexCoords = mesh.getNumTexCoords(); file.write((char *)(&numTexCoords), sizeof(int)); if (numTexCoords > 0) { file.write((char *)(&(mesh.getTexCoords())[0]), sizeof(ofVec2f) * numTexCoords); } int numColors = mesh.getNumColors(); file.write((char *)(&numColors), sizeof(int)); if (numColors > 0) { file.write((char *)(&(mesh.getColors())[0]), sizeof(ofFloatColor) * numColors); } int numIndices = mesh.getNumIndices(); file.write((char *)(&numIndices), sizeof(int)); if (numIndices > 0) { file.write((char *)(&(mesh.getIndices())[0]), sizeof(ofIndexType) * numIndices); } file.close(); }
//-------------------------------------------------------------- void ofVboByteColor::updateMesh(const ofMesh & mesh){ ofMesh * nonconstMesh = (ofMesh*)&mesh; if(nonconstMesh->haveVertsChanged()) updateVertexData(mesh.getVerticesPointer(),mesh.getNumVertices()); if(nonconstMesh->haveColorsChanged()) updateColorData(mesh.getColorsPointer(),mesh.getNumColors()); if(nonconstMesh->haveNormalsChanged()) updateNormalData(mesh.getNormalsPointer(),mesh.getNumNormals()); if(nonconstMesh->haveTexCoordsChanged()) updateTexCoordData(mesh.getTexCoordsPointer(),mesh.getNumTexCoords()); }
//-------------------------------------------------------------- void ofVbo::setMesh(const ofMesh & mesh, int usage){ setVertexData(mesh.getVerticesPointer(),mesh.getNumVertices(),usage,sizeof(ofVec3f)); setColorData(mesh.getColorsPointer(),mesh.getNumColors(),usage,sizeof(ofColor)); setNormalData(mesh.getNormalsPointer(),mesh.getNumNormals(),usage,sizeof(ofVec3f)); setTexCoordData(mesh.getTexCoordsPointer(),mesh.getNumTexCoords(),usage,sizeof(ofVec2f)); }
void CloudsVisualSystem3DModelLoader::smoothMesh( ofMesh& facetedMesh, ofMesh& targetMesh, int precision) { cout << "smoothing mesh" << endl; //get our vertex, uv and face info vector<ofVec3f>& v = facetedMesh.getVertices(); vector<ofVec2f>& uv = facetedMesh.getTexCoords(); vector<ofIndexType>& indices = facetedMesh.getIndices(); bool hasTC = facetedMesh.getNumTexCoords(); //use these to store our new mesh info map<string, unsigned int> mergeMap; vector<ofVec3f> smoothVertices; vector<ofVec3f> smoothNormals; vector<ofVec2f> smoothTexCoords; vector<ofIndexType> smoothIndices; //merge our vertices by pointing near by vertices to the same index for (int i=0; i<v.size(); i++) { mergeMap[ vec3ToString( v[i], precision ) ] = i; } //fill our smoothed vertex array with merged vertices & tex coords smoothVertices.resize( mergeMap.size() ); if(hasTC) smoothTexCoords.resize( mergeMap.size() ); int smoothVertexCount = 0; for (map<string, unsigned int>::iterator it = mergeMap.begin(); it != mergeMap.end(); it++) { smoothVertices[smoothVertexCount] = v[it->second]; if(hasTC) smoothTexCoords[smoothVertexCount] = uv[it->second]; it->second = smoothVertexCount;//store our new vertex index smoothVertexCount++; } //reconstruct our faces by reassigning their indices to the merged vertices smoothIndices.resize( indices.size() ); for (int i=0; i<indices.size(); i++) { //use our old vertex poisition to retrieve our new index smoothIndices[i] = mergeMap[ vec3ToString( v[ indices[i] ], precision ) ]; } //calculate our normals smoothNormals.resize( smoothVertices.size() ); ofVec3f n; for (int i=0; i<smoothIndices.size(); i+=3) { n = normalFrom3Points( smoothVertices[smoothIndices[i]], smoothVertices[smoothIndices[i+1]], smoothVertices[smoothIndices[i+2]] ); smoothNormals[smoothIndices[i]] += n; smoothNormals[smoothIndices[i+1]] += n; smoothNormals[smoothIndices[i+2]] += n; } for (int i=0; i<smoothNormals.size(); i++) { smoothNormals[i].normalize(); } //setup our smoothed mesh. this should still work if our targetMesh is our facetedMesh targetMesh.clear(); targetMesh.addVertices( smoothVertices ); targetMesh.addNormals( smoothNormals ); if(hasTC) targetMesh.addTexCoords( smoothTexCoords ); targetMesh.addIndices( smoothIndices ); }