/*! Subdivides the mesh uniformly one step */ void LoopSubdivisionMesh::Subdivide() { // Create new mesh and copy all the attributes HalfEdgeMesh subDivMesh; subDivMesh.SetTransform(GetTransform()); subDivMesh.SetName(GetName()); subDivMesh.SetColorMap(GetColorMap()); subDivMesh.SetWireframe(GetWireframe()); subDivMesh.SetShowNormals(GetShowNormals()); subDivMesh.SetOpacity(GetOpacity()); if (IsHovering()) subDivMesh.Hover(); if (IsSelected()) subDivMesh.Select(); subDivMesh.mMinCMap = mMinCMap; subDivMesh.mMaxCMap = mMaxCMap; subDivMesh.mAutoMinMax = mAutoMinMax; // loop over each face and create 4 new ones for (unsigned int i=0; i<mFaces.size(); i++){ // subdivide face std::vector< std::vector<Vector3<float> > > faces = Subdivide(i); // add new faces to subDivMesh for(unsigned int j=0; j<faces.size(); j++){ subDivMesh.AddFace(faces.at(j)); } } // Assigns the new mesh *this = LoopSubdivisionMesh(subDivMesh, ++mNumSubDivs); Update(); }
//TODO: drive this with a generic VBO descriptor to avoid special case drawing like these particles static void DrawParticles( const DrawParticlesCommand &cmd ) { if ( !cmd.material ) { console.Print( PrintLevel::Developer, "%s with invalid material\n", XS_FUNCTION ); return; } cmd.material->Bind(); bool setWireframe = false; bool previousWireframe = false; if ( r_wireframe->GetBool() || (cmd.material->flags & MF_WIREFRAME) ) { setWireframe = true; previousWireframe = GetWireframe(); ToggleWireframe( true ); } if ( cmd.vbo ) { cmd.vbo->Bind(); // position4, uv2, colour4 EnableVertexAttribs( VERTEX_ATTRIB_0 | VERTEX_ATTRIB_1 | VERTEX_ATTRIB_2 ); // calculate stride GLsizei stride = sizeof(vector4) + sizeof(vector2) + sizeof(vector4); // set the attribute pointers size_t offset = 0u; glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) ); offset += sizeof(vector4); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) ); offset += sizeof(vector2); glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) ); offset += sizeof(vector4); } if ( 1 ) { cmd.ibo->Bind(); GLint size = 0; glGetBufferParameteriv( GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size ); glDrawElements( GL_TRIANGLES, size / sizeof(uint32_t), GL_UNSIGNED_INT, 0 ); } else { glDrawArrays( GL_TRIANGLES, 0, cmd.count ); } // clean up state if ( setWireframe ) { ToggleWireframe( previousWireframe ); } }
/*! Subdivides the mesh one step, depending on subdividability */ void AdaptiveLoopSubdivisionMesh::Subdivide() { // Create new mesh and copy all the attributes HalfEdgeMesh subDivMesh; subDivMesh.SetTransform(GetTransform()); subDivMesh.SetName(GetName()); subDivMesh.SetColorMap(GetColorMap()); subDivMesh.SetWireframe(GetWireframe()); subDivMesh.SetShowNormals(GetShowNormals()); subDivMesh.SetOpacity(GetOpacity()); if (IsHovering()) subDivMesh.Hover(); if (IsSelected()) subDivMesh.Select(); subDivMesh.mMinCMap = mMinCMap; subDivMesh.mMaxCMap = mMaxCMap; subDivMesh.mAutoMinMax = mAutoMinMax; // loop over each face and create new ones for(unsigned int i=0; i<GetNumFaces(); i++){ // find neighbor faces unsigned int f1, f2, f3; EdgeIterator eit = GetEdgeIterator( f(i).edge ); f1 = eit.Pair().GetEdgeFaceIndex(); eit.Pair(); f2 = eit.Next().Pair().GetEdgeFaceIndex(); eit.Pair(); f3 = eit.Next().Pair().GetEdgeFaceIndex(); unsigned int numNotSubdividable = !Subdividable(f1) + !Subdividable(f2) + !Subdividable(f3); // Do not subdivide if "self" is not subdividable if(!Subdividable(i)){ numNotSubdividable = 3; } std::vector< std::vector <Vector3<float> > > faces; switch(numNotSubdividable){ case 0: // normal subdivision (from LoopSubdivisionMesh) faces = LoopSubdivisionMesh::Subdivide(i); break; case 1: // special case 1 faces = Subdivide1(i); break; case 2: // special case 2 faces = Subdivide2(i); break; case 3: // trivial case, no subdivision, same as if subdividable(fi) == false faces = Subdivide3(i); break; } // add the faces (if any) to subDivMesh for(unsigned int j=0; j<faces.size(); j++){ subDivMesh.AddFace(faces.at(j)); } } // Assign the new mesh *this = AdaptiveLoopSubdivisionMesh(subDivMesh, ++mNumSubDivs); Update(); }
static void DrawMesh( const Mesh *mesh ) { SDL_assert( mesh->material && "DrawMesh with invalid material" ); bool setWireframe = false; bool previousWireframe = false; if ( r_wireframe->GetBool() || (mesh->material->flags & MF_WIREFRAME) ) { setWireframe = true; previousWireframe = GetWireframe(); ToggleWireframe( true ); } // bind the vertex/normal/uv buffers if ( mesh->vertexBuffer ) { const bool hasVerts = !mesh->vertices.empty(); const bool hasNormals = !mesh->normals.empty(); const bool hasUVs = !mesh->UVs.empty(); mesh->vertexBuffer->Bind(); uint32_t vertexAttribs = 0u; if ( hasVerts ) { vertexAttribs |= VERTEX_ATTRIB_0; } if ( hasNormals ) { vertexAttribs |= VERTEX_ATTRIB_1; } if ( hasUVs ) { vertexAttribs |= VERTEX_ATTRIB_2; } EnableVertexAttribs( vertexAttribs ); // calculate stride GLsizei stride = 0; if ( hasVerts ) { stride += sizeof(vector3); } if ( hasNormals ) { stride += sizeof(vector3); } if ( hasUVs ) { stride += sizeof(vector2); } // set the attribute pointers size_t offset = 0u; if ( hasVerts ) { glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) ); offset += sizeof(vector3); } if ( hasNormals ) { glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) ); offset += sizeof(vector3); } if ( hasUVs ) { glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, stride, reinterpret_cast<const GLvoid *>( offset ) ); offset += sizeof(vector2); } } // issue the draw command //FIXME: index buffer is all kinds of wrong when using glDrawElements if ( 0 ) {//mesh->indexBuffer ) { mesh->indexBuffer->Bind(); GLint size = 0; glGetBufferParameteriv( GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size ); glDrawElements( GL_TRIANGLES, size / sizeof(uint32_t), GL_UNSIGNED_INT, 0 ); } else { glDrawArrays( GL_TRIANGLES, 0, mesh->indices.size() ); } // clean up state if ( setWireframe ) { ToggleWireframe( previousWireframe ); } }