//Mesh void RenderObject::setMesh(std::string name) { GLMeshData* meshData = Singleton<MeshDatabase>::Instance()->loadMesh(name); if(meshData != 0) { GLMesh* newMesh = new GLMesh(); newMesh->initialize(meshData); newMesh->setName(name); //By default GLMesh given same name as GLMeshData this->mesh = newMesh; } }
static void createFVarPatches(OpenSubdiv::Far::TopologyRefiner const & refiner, OpenSubdiv::Far::PatchTable const & patchTable, std::vector<Vertex> const & fvarBuffer) { assert(not fvarBuffer.empty()); static int channel = 0; if (g_FarDrawFVarVerts) { GLMesh::Options options; options.vertColorMode = GLMesh::VERTCOLOR_BY_LEVEL; fvarVerts.InitializeFVar(options, refiner, &patchTable, channel, 0, (float *)(&fvarBuffer[0])); } if (g_FarDrawFVarPatches) { // generate uniform tessellation for patches int tessFactor = g_FarDrawFVarPatchTess, npatches = patchTable.GetNumPatchesTotal(), nvertsperpatch = (tessFactor) * (tessFactor), nverts = npatches * nvertsperpatch; float * uvs = (float *)alloca(tessFactor); for (int i=0; i<tessFactor; ++i) { uvs[i] = (float)i/(tessFactor-1.0f); } std::vector<Vertex> verts(nverts); memset(&verts[0], 0, verts.size()*sizeof(Vertex)); /* OpenSubdiv::Far::PatchTable::PatchHandle handle; Vertex * vert = &verts[0]; for (int patch=0; patch<npatches; ++patch) { for (int i=0; i<tessFactor; ++i) { for (int j=0; j<tessFactor; ++j, ++vert) { handle.patchIndex = patch; // To be replaced with EvaluateBasis() for the appropriate channel: //patchTable.EvaluateFaceVarying(channel, handle, uvs[i], uvs[j], fvarBuffer, *vert); } } } */ GLMesh::Options options; options.edgeColorMode = GLMesh::EDGECOLOR_BY_PATCHTYPE; fvarWire.InitializeFVar(options, refiner, &patchTable, channel, tessFactor, (float *)(&verts[0])); } }
bool GLInputVertexAttribute::Disable() { if (isCreateOK()) { bool result = false; GLMesh* mesh = (dynamic_cast<GLRenderable*>(this->getRenderable()))->getMesh(); glDisableVertexAttribArray(m_IAHandle); if (mesh->isUseCPUBuffer() == false) { // Unbind VBO glBindBuffer(GL_ARRAY_BUFFER, 0); } result = true; m_bIsEnableOK = !result; } return !isEnableOK(); }
bool GLInputVertexAttribute::Enable() { if (isCreateOK()) { bool result = false; GLSLShader* shader = (dynamic_cast<GLRenderable*>(this->getRenderable()))->getShader(); GLMesh* mesh = (dynamic_cast<GLRenderable*>(this->getRenderable()))->getMesh(); if (shader->isCreateOK() && shader->isEnableOK() && mesh != NULL) { m_IAHandle = glGetAttribLocation(shader->getProgramHandle(), m_InputVertexAttributeName.c_str()); LOGD("call glGetAttribLocation(%d, %s), get the input attribute handle is %d", shader->getProgramHandle(), m_InputVertexAttributeName.c_str(), m_IAHandle); if (m_IAHandle != -1) { glEnableVertexAttribArray(m_IAHandle); if (mesh->isUseCPUBuffer()) { // use cpu memory's vertex buffer pointer glVertexAttribPointer(m_IAHandle, m_IAElementNum, m_IAType, m_IANormalized, m_IAStride, (BYTE*)(mesh->getVertexDataPointer()) + m_IAOffset); } else { // use gpu memory's vertex buffer glBindBuffer(GL_ARRAY_BUFFER, mesh->getVBOHandle()); glVertexAttribPointer(m_IAHandle, m_IAElementNum, m_IAType, m_IANormalized, m_IAStride, (BYTE*)m_IAOffset); } result = true; } else { LOGE("glGetAttribLocation return -1"); result = false; } } m_bIsEnableOK = result; } return isEnableOK(); }
void GLShader::Update(GLMesh& mesh, const GLCamera& camera) { glm::mat4 model = mesh.GetTransform().GetModel(); glm::mat4 projView = camera.GetViewProjectionMatrix(); glm::vec3 viewPos = camera.GetPos(); glUniformMatrix4fv(m_uniforms[TRANSFROM_U], 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(m_uniforms[PROJVIEW_U], 1, GL_FALSE, glm::value_ptr(projView)); glUniform3fv(m_uniforms[VIEWPOS_U], 1, glm::value_ptr(viewPos)); GLint matAmbientLoc = glGetUniformLocation(m_program, "material.ambient"); GLint matDiffuseLoc = glGetUniformLocation(m_program, "material.diffuse"); GLint matSpecularLoc = glGetUniformLocation(m_program, "material.specular"); GLint matShineLoc = glGetUniformLocation(m_program, "material.shininess"); glUniform3fv(matAmbientLoc, 1, glm::value_ptr(mesh.GetMaterial().ambient)); glUniform3fv(matDiffuseLoc, 1, glm::value_ptr(mesh.GetMaterial().diffuse)); glUniform3fv(matSpecularLoc, 1, glm::value_ptr(mesh.GetMaterial().specular)); glUniform1f(matShineLoc, mesh.GetMaterial().shininess); mesh.GetMaterial().texture->Bind(0); glUniform1i(this->GetUnifromLocation("diffuseTexture"), 0); }
//------------------------------------------------------------------------------ static void display() { g_hud.GetFrameBuffer()->Bind(); Stopwatch s; s.Start(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, g_width, g_height); // prepare view matrix double aspect = g_width/(double)g_height; identity(g_transformData.ModelViewMatrix); translate(g_transformData.ModelViewMatrix, -g_pan[0], -g_pan[1], -g_dolly); rotate(g_transformData.ModelViewMatrix, g_rotate[1], 1, 0, 0); rotate(g_transformData.ModelViewMatrix, g_rotate[0], 0, 1, 0); rotate(g_transformData.ModelViewMatrix, -90, 1, 0, 0); translate(g_transformData.ModelViewMatrix, -g_center[0], -g_center[1], -g_center[2]); perspective(g_transformData.ProjectionMatrix, 45.0f, (float)aspect, 0.1f, 500.0f); multMatrix(g_transformData.ModelViewProjectionMatrix, g_transformData.ModelViewMatrix, g_transformData.ProjectionMatrix); glEnable(GL_DEPTH_TEST); s.Stop(); float drawCpuTime = float(s.GetElapsed() * 1000.0f); glBindVertexArray(0); glUseProgram(0); // primitive counting glBeginQuery(GL_PRIMITIVES_GENERATED, g_queries[0]); #if defined(GL_VERSION_3_3) glBeginQuery(GL_TIME_ELAPSED, g_queries[1]); #endif // Update and bind transform state --------------------- if (! g_transformUB) { glGenBuffers(1, &g_transformUB); glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(g_transformData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(g_transformData), &g_transformData); glBindBuffer(GL_UNIFORM_BUFFER, 0); // Update and bind lighting state ---------------------- struct Lighting { struct Light { float position[4]; float ambient[4]; float diffuse[4]; float specular[4]; } lightSource[2]; } lightingData = { {{ { 0.5, 0.2f, 1.0f, 0.0f }, { 0.1f, 0.1f, 0.1f, 1.0f }, { 0.7f, 0.7f, 0.7f, 1.0f }, { 0.8f, 0.8f, 0.8f, 1.0f } }, { { -0.8f, 0.4f, -1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f }, { 0.5f, 0.5f, 0.5f, 1.0f }, { 0.8f, 0.8f, 0.8f, 1.0f } }} }; if (! g_lightingUB) { glGenBuffers(1, &g_lightingUB); glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferData(GL_UNIFORM_BUFFER, sizeof(lightingData), NULL, GL_STATIC_DRAW); }; glBindBuffer(GL_UNIFORM_BUFFER, g_lightingUB); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(lightingData), &lightingData); glBindBuffer(GL_UNIFORM_BUFFER, 0); // Draw stuff ------------------------------------------ // control cage edges & verts if (g_drawCageVertices) { g_base_glmesh.Draw(GLMesh::COMP_VERT, g_transformUB, g_lightingUB); } if (g_drawCageEdges) { g_base_glmesh.Draw(GLMesh::COMP_EDGE, g_transformUB, g_lightingUB); } // Hbr mesh if (g_HbrDrawMode!=kDRAW_NONE) { GLMesh::Component comp=GLMesh::COMP_VERT; switch (g_HbrDrawMode) { case kDRAW_VERTICES : comp=GLMesh::COMP_VERT; break; case kDRAW_WIREFRAME : comp=GLMesh::COMP_EDGE; break; case kDRAW_FACES : comp=GLMesh::COMP_FACE; break; default: assert(0); } g_hbr_glmesh.Draw(comp, g_transformUB, g_lightingUB); } // Vtr mesh if (g_VtrDrawMode!=kDRAW_NONE) { GLMesh::Component comp=GLMesh::COMP_VERT; switch (g_VtrDrawMode) { case kDRAW_VERTICES : comp=GLMesh::COMP_VERT; break; case kDRAW_WIREFRAME : comp=GLMesh::COMP_EDGE; break; case kDRAW_FACES : comp=GLMesh::COMP_FACE; break; default: assert(0); } g_vtr_glmesh.Draw(comp, g_transformUB, g_lightingUB); } assert(g_font); g_font->Draw(g_transformUB); // ----------------------------------------------------- g_hud.GetFrameBuffer()->ApplyImageShader(); GLuint numPrimsGenerated = 0; GLuint timeElapsed = 0; glGetQueryObjectuiv(g_queries[0], GL_QUERY_RESULT, &numPrimsGenerated); #if defined(GL_VERSION_3_3) glGetQueryObjectuiv(g_queries[1], GL_QUERY_RESULT, &timeElapsed); #endif float drawGpuTime = timeElapsed / 1000.0f / 1000.0f; if (g_hud.IsVisible()) { g_fpsTimer.Stop(); double fps = 1.0/g_fpsTimer.GetElapsed(); g_fpsTimer.Start(); { // display selectde patch info static char const * patchTypes[11] = { "undefined", "points", "lines", "quads", "tris", "loop", "regular", "boundary", "corner", "gregory", "gregory-boundary" }; if (g_Adaptive and g_currentPatch) { g_hud.DrawString(g_width/2-100, 100, "Current Patch : %d/%d (%s - %d CVs)", g_currentPatch-1, g_numPatches, patchTypes[g_currentPatchDesc.GetType()], g_currentPatchDesc.GetNumControlVertices()); } } static char const * schemeNames[3] = { "BILINEAR", "CATMARK", "LOOP" }; g_hud.DrawString(10, -140, "Primitives : %d", numPrimsGenerated); g_hud.DrawString(10, -120, "Scheme : %s", schemeNames[ g_shapes[g_currentShape].scheme ]); g_hud.DrawString(10, -100, "GPU Kernel : %.3f ms", g_gpuTime); g_hud.DrawString(10, -80, "CPU Kernel : %.3f ms", g_cpuTime); g_hud.DrawString(10, -60, "GPU Draw : %.3f ms", drawGpuTime); g_hud.DrawString(10, -40, "CPU Draw : %.3f ms", drawCpuTime); g_hud.DrawString(10, -20, "FPS : %3.1f", fps); g_hud.Flush(); } glFinish(); //checkGLErrors("display leave"); }
//------------------------------------------------------------------------------ static void createVtrMesh(Shape * shape, int maxlevel) { Stopwatch s; s.Start(); // create Vtr mesh (topology) OpenSubdiv::Sdc::Type sdctype = GetSdcType(*shape); OpenSubdiv::Sdc::Options sdcoptions = GetSdcOptions(*shape); OpenSubdiv::Far::TopologyRefiner * refiner = OpenSubdiv::Far::TopologyRefinerFactory<Shape>::Create(sdctype, sdcoptions, *shape); OpenSubdiv::Far::PatchTables * patchTables = 0; if (g_Adaptive) { refiner->RefineAdaptive(maxlevel, /*fullTopology*/true); patchTables = OpenSubdiv::Far::PatchTablesFactory::Create(*refiner); g_numPatches = patchTables->GetNumPatches(); } else { refiner->RefineUniform(maxlevel, /*fullTopology*/true); } s.Stop(); // create vertex primvar data buffer std::vector<Vertex> vertexBuffer(refiner->GetNumVerticesTotal()); Vertex * verts = &vertexBuffer[0]; //printf("Vtr time: %f ms (topology)\n", float(s.GetElapsed())*1000.0f); // copy coarse vertices positions int ncoarseverts = shape->GetNumVertices(); for (int i=0; i<ncoarseverts; ++i) { float * ptr = &shape->verts[i*3]; verts[i].SetPosition(ptr[0], ptr[1], ptr[2]); } //#define no_stencils #ifdef no_stencils { s.Start(); // populate buffer with Vtr interpolated vertex data refiner->Interpolate(verts, verts + ncoarseverts); s.Stop(); //printf(" %f ms (interpolate)\n", float(s.GetElapsed())*1000.0f); //printf(" %f ms (total)\n", float(s.GetTotalElapsed())*1000.0f); } #else { OpenSubdiv::Far::StencilTablesFactory::Options options; options.generateOffsets=true; options.generateAllLevels=true; options.sortBySize=false; OpenSubdiv::Far::StencilTables const * stencilTables = OpenSubdiv::Far::StencilTablesFactory::Create(*refiner, options); stencilTables->UpdateValues(verts, verts + ncoarseverts); } #endif if (g_VtrDrawVertIDs) { createVertNumbers(*refiner, vertexBuffer); } if (g_VtrDrawFaceIDs) { createFaceNumbers(*refiner, vertexBuffer); } if (g_VtrDrawPtexIDs and patchTables) { createPtexNumbers(*patchTables, vertexBuffer); } if (g_Adaptive and patchTables) { createPatchNumbers(*patchTables, vertexBuffer); } createEdgeNumbers(*refiner, vertexBuffer, g_VtrDrawEdgeIDs!=0, g_VtrDrawEdgeSharpness!=0); GLMesh::Options options; options.vertColorMode=g_Adaptive ? GLMesh::VERTCOLOR_BY_LEVEL : GLMesh::VERTCOLOR_BY_SHARPNESS; options.edgeColorMode=g_Adaptive ? GLMesh::EDGECOLOR_BY_PATCHTYPE : GLMesh::EDGECOLOR_BY_SHARPNESS; options.faceColorMode=g_Adaptive ? GLMesh::FACECOLOR_BY_PATCHTYPE :GLMesh::FACECOLOR_SOLID; if (g_Adaptive) { g_vtr_glmesh.Initialize(options, *refiner, patchTables, (float *)&verts[0]); g_vtr_glmesh.SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); } else { g_vtr_glmesh.Initialize(options, *refiner, patchTables, (float *)&verts[0]); g_vtr_glmesh.SetDiffuseColor(0.75f, 0.9f, 1.0f, 1.0f); } //setFaceColors(*refiner); g_vtr_glmesh.InitializeDeviceBuffers(); delete refiner; delete patchTables; }
//------------------------------------------------------------------------------ static void createHbrMesh(Shape * shape, int maxlevel) { Stopwatch s; s.Start(); // create Hbr mesh using functions from hbr_utils Hmesh * hmesh = createMesh<Vertex>(shape->scheme, /*fvarwidth*/ 0); createVerticesWithPositions<Vertex>(shape, hmesh); createTopology<Vertex>(shape, hmesh, shape->scheme); s.Stop(); std::vector<Hface const *> coarseFaces, // list of Hbr coarse faces refinedFaces; // list of Hbr faces refined at maxlevel int nfaces = hmesh->GetNumFaces(); { // create control cage GL mesh coarseFaces.resize(nfaces); for (int i=0; i<nfaces; ++i) { coarseFaces[i] = hmesh->GetFace(i); } GLMesh::Options coarseOptions; coarseOptions.vertColorMode=GLMesh::VERTCOLOR_BY_SHARPNESS; coarseOptions.edgeColorMode=GLMesh::EDGECOLOR_BY_SHARPNESS; coarseOptions.faceColorMode=GLMesh::FACECOLOR_SOLID; g_base_glmesh.Initialize(coarseOptions, coarseFaces); g_base_glmesh.InitializeDeviceBuffers(); } { // create maxlevel refined GL mesh s.Start(); OpenSubdiv::Far::PatchTables const * patchTables = 0; if (g_Adaptive) { int maxvalence = RefineAdaptive(*hmesh, maxlevel, refinedFaces); patchTables = CreatePatchTables(*hmesh, maxvalence); patchTables->GetNumPatches(); delete patchTables; } else { RefineUniform(*hmesh, maxlevel, refinedFaces); } s.Stop(); //printf("Hbr time: %f ms\n", float(s.GetElapsed())*1000.0f); if (g_HbrDrawVertIDs) { createVertNumbers(refinedFaces); } // Hbr is a half-edge rep, so edges do not have unique IDs that // can be displayed if (g_HbrDrawEdgeSharpness) { createEdgeNumbers(refinedFaces); } if (g_HbrDrawFaceIDs) { createFaceNumbers(refinedFaces, /*ptex*/ false); } if (g_HbrDrawPtexIDs) { createFaceNumbers(refinedFaces, /*ptex*/ true); } GLMesh::Options refinedOptions; refinedOptions.vertColorMode=GLMesh::VERTCOLOR_BY_SHARPNESS; refinedOptions.edgeColorMode=GLMesh::EDGECOLOR_BY_SHARPNESS; refinedOptions.faceColorMode=GLMesh::FACECOLOR_SOLID; g_hbr_glmesh.Initialize(refinedOptions, refinedFaces); g_hbr_glmesh.SetDiffuseColor(1.0f,0.75f,0.9f, 1.0f); } g_hbr_glmesh.InitializeDeviceBuffers(); delete hmesh; }
//------------------------------------------------------------------------------ static void createFarGLMesh(Shape * shape, int maxlevel) { Stopwatch s; s.Start(); using namespace OpenSubdiv; // create Far mesh (topology) Sdc::SchemeType sdctype = GetSdcType(*shape); Sdc::Options sdcoptions = GetSdcOptions(*shape); sdcoptions.SetFVarLinearInterpolation(g_fvarInterpolation); Far::TopologyRefiner * refiner = Far::TopologyRefinerFactory<Shape>::Create(*shape, Far::TopologyRefinerFactory<Shape>::Options(sdctype, sdcoptions)); if (g_Adaptive) { Far::TopologyRefiner::AdaptiveOptions options(maxlevel); options.useSingleCreasePatch = false; refiner->RefineAdaptive(options); } else { Far::TopologyRefiner::UniformOptions options(maxlevel); options.fullTopologyInLastLevel = true; refiner->RefineUniform(options); } int numTotalVerts = refiner->GetNumVerticesTotal(); // // Patch table // std::vector<Vertex> fvarBuffer; Far::PatchTable * patchTable = 0; bool createFVarWire = g_FarDrawFVarPatches or g_FarDrawFVarVerts; if (g_Adaptive) { Far::PatchTableFactory::Options options; options.generateFVarTables = createFVarWire; options.shareEndCapPatchPoints = false; patchTable = Far::PatchTableFactory::Create(*refiner, options); // increase vertex buffer for the additional local points if (patchTable->GetLocalPointStencilTable()) { numTotalVerts += patchTable->GetLocalPointStencilTable()->GetNumStencils(); } g_numPatches = patchTable->GetNumPatchesTotal(); g_maxValence = patchTable->GetMaxValence(); if (createFVarWire) { // interpolate fvar values int channel = 0; // XXXX should use a (u,v) vertex class fvarBuffer.resize(refiner->GetNumFVarValuesTotal(channel), 0); Vertex * values = &fvarBuffer[0]; int nCoarseValues = refiner->GetLevel(0).GetNumFVarValues(channel); for (int i=0; i<nCoarseValues; ++i) { float const * ptr = &shape->uvs[i*2]; values[i].SetPosition(ptr[0], ptr[1], 0.0f); } int lastLevel = refiner->GetMaxLevel(); Vertex * src = values; for (int level = 1; level <= lastLevel; ++level) { Vertex * dst = src + refiner->GetLevel(level-1).GetNumFVarValues(channel); Far::PrimvarRefiner(*refiner).InterpolateFaceVarying(level, src, dst, channel); src = dst; } } } // // interpolate vertices // // create vertex primvar data buffer std::vector<Vertex> vertexBuffer(numTotalVerts); Vertex * verts = &vertexBuffer[0]; // copy coarse vertices positions int ncoarseverts = shape->GetNumVertices(); for (int i=0; i<ncoarseverts; ++i) { float * ptr = &shape->verts[i*3]; verts[i].SetPosition(ptr[0], ptr[1], ptr[2]); } s.Start(); if (g_useStencils) { // // Stencil interpolation // Far::StencilTable const * stencilTable = 0; Far::StencilTableFactory::Options options; options.generateOffsets=true; options.generateIntermediateLevels=true; stencilTable = Far::StencilTableFactory::Create(*refiner, options); // append local point stencils if needed if (patchTable and patchTable->GetLocalPointStencilTable()) { if (Far::StencilTable const * stencilTableWithLocalPoints = Far::StencilTableFactory::AppendLocalPointStencilTable( *refiner, stencilTable, patchTable->GetLocalPointStencilTable())) { delete stencilTable; stencilTable = stencilTableWithLocalPoints; } } // // apply stencils // stencilTable->UpdateValues(verts, verts + ncoarseverts); delete stencilTable; } else { // // TopologyRefiner interpolation // // populate buffer with Far interpolated vertex data int lastLevel = refiner->GetMaxLevel(); Vertex * src = verts; for (int level = 1; level <= lastLevel; ++level) { Vertex * dst = src + refiner->GetLevel(level-1).GetNumVertices(); Far::PrimvarRefiner(*refiner).Interpolate(level, src, dst); src = dst; } //printf(" %f ms (interpolate)\n", float(s.GetElapsed())*1000.0f); //printf(" %f ms (total)\n", float(s.GetTotalElapsed())*1000.0f); // TODO: endpatch basis conversion comes here } s.Stop(); // // Misc display // //printf("Far time: %f ms (topology)\n", float(s.GetElapsed())*1000.0f); if (g_FarDrawVertIDs) { createVertNumbers(*refiner, vertexBuffer); } if (g_FarDrawFaceIDs) { createFaceNumbers(*refiner, vertexBuffer); } if (g_FarDrawPtexIDs and patchTable) { createPtexNumbers(*patchTable, vertexBuffer); } if (g_Adaptive) { createPatchNumbers(*patchTable, vertexBuffer); } if (g_Adaptive and g_FarDrawGregogyBasis) { createGregoryBasis(*patchTable, vertexBuffer); } if (g_Adaptive and createFVarWire) { createFVarPatches(*refiner, *patchTable, fvarBuffer); createFVarPatchNumbers(*patchTable, fvarBuffer); } createEdgeNumbers(*refiner, vertexBuffer, g_FarDrawEdgeIDs!=0, g_FarDrawEdgeSharpness!=0); GLMesh::Options options; options.vertColorMode=g_Adaptive ? GLMesh::VERTCOLOR_BY_LEVEL : GLMesh::VERTCOLOR_BY_SHARPNESS; options.edgeColorMode=g_Adaptive ? GLMesh::EDGECOLOR_BY_PATCHTYPE : GLMesh::EDGECOLOR_BY_SHARPNESS; options.faceColorMode=g_Adaptive ? GLMesh::FACECOLOR_BY_PATCHTYPE :GLMesh::FACECOLOR_SOLID; g_far_glmesh.Initialize(options, *refiner, patchTable, (float *)&verts[0]); if (g_Adaptive) { g_far_glmesh.SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); } else { g_far_glmesh.SetDiffuseColor(0.75f, 0.9f, 1.0f, 1.0f); } //setFaceColors(*refiner); g_far_glmesh.InitializeDeviceBuffers(); // save coarse topology (used for control mesh display) g_controlMeshDisplay.SetTopology(refiner->GetLevel(0)); // save coarse points in a GPU buffer (used for control mesh display) if (not g_controlMeshDisplayVBO) { glGenBuffers(1, &g_controlMeshDisplayVBO); } glBindBuffer(GL_ARRAY_BUFFER, g_controlMeshDisplayVBO); glBufferData(GL_ARRAY_BUFFER, 3*sizeof(float)*vertexBuffer.size(), (GLfloat*)&vertexBuffer[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // compute model bounds float min[3] = { FLT_MAX, FLT_MAX, FLT_MAX}; float max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; for (size_t i=0; i <vertexBuffer.size(); ++i) { for(int j=0; j<3; ++j) { float v = vertexBuffer[i].GetPos()[j]; min[j] = std::min(min[j], v); max[j] = std::max(max[j], v); } } for (int j=0; j<3; ++j) { g_center[j] = (min[j] + max[j]) * 0.5f; g_size += (max[j]-min[j])*(max[j]-min[j]); } g_size = sqrtf(g_size); delete refiner; delete patchTable; }
static void createGregoryBasis(OpenSubdiv::Far::PatchTable const & patchTable, std::vector<Vertex> const & vertexBuffer) { typedef OpenSubdiv::Far::PatchDescriptor PatchDescriptor; int npatches = 0; int patchArray = 0; for (int array=0; array<(int)patchTable.GetNumPatchArrays(); ++array) { if (patchTable.GetPatchArrayDescriptor(array).GetType()== PatchDescriptor::GREGORY_BASIS) { npatches = patchTable.GetNumPatches(array); patchArray = array; break; } } int nedges = npatches * 20; std::vector<int> vertsperedge(nedges), edgeindices(nedges*2); for (int patch=0; patch<npatches; ++patch) { static int basisedges[40] = { 0, 1, 0, 2, 1, 3, 2, 4, 5, 6, 5, 7, 6, 8, 7, 9, 10, 11, 10, 12, 11, 13, 12, 14, 15, 16, 15, 17, 16, 18, 17, 19, 1, 7, 6, 12, 11, 17, 16, 2 }; int offset = patch * 20, * vpe = &vertsperedge[offset], * indices = &edgeindices[patch * 40]; OpenSubdiv::Far::ConstIndexArray const cvs = patchTable.GetPatchVertices(patchArray, patch); for (int i=0; i<20; ++i) { vpe[i] = 2; indices[i*2] = cvs[basisedges[i*2]]; indices[i*2+1] = cvs[basisedges[i*2+1]]; } //Vertex const * verts = &edgeverts[offset]; static char buf[16]; for (int i=0; i<4; ++i) { int vid = patch * 20 + i * 5; const float *P = vertexBuffer[cvs[i*5+0]].GetPos(); const float *Ep = vertexBuffer[cvs[i*5+1]].GetPos(); const float *Em = vertexBuffer[cvs[i*5+2]].GetPos(); const float *Fp = vertexBuffer[cvs[i*5+3]].GetPos(); const float *Fm = vertexBuffer[cvs[i*5+4]].GetPos(); snprintf(buf, 16, " P%d (%d)", i, vid); g_font->Print3D(P, buf, 3); snprintf(buf, 16, " Ep%d (%d)", i, vid+1); g_font->Print3D(Ep, buf, 3); snprintf(buf, 16, " Em%d (%d)", i, vid+2); g_font->Print3D(Em, buf, 3); snprintf(buf, 16, " Fp%d (%d)", i, vid+3); g_font->Print3D(Fp, buf, 3); snprintf(buf, 16, " Fm%d (%d)", i, vid+4); g_font->Print3D(Fm, buf, 3); } } GLMesh::Options options; gregoryWire.Initialize(options, (int)vertexBuffer.size(), (int)vertsperedge.size(), &vertsperedge[0], &edgeindices[0], (float const *)&vertexBuffer[0]); }
/** This static method reads an obj file, whose name is sent in as a parameter, and returns a pointer to a GLMesh object that it created based on the file information. This method throws errors if the file doesn't exist, is not an obj file, etc. */ GLMesh* OBJReader::loadOBJFile(const char* fileName){ if (fileName == NULL) throwError("fileName is NULL."); // Logger::out()<< "Loading mesh: " << fileName <<std::endl; FILE* f = fopen(fileName, "r"); if (f == NULL) throwError("Cannot open file \'%s\'.", fileName); GLMesh* result = new GLMesh(); result->setOriginalFilename( fileName ); //have a temporary buffer used to read the file line by line... char buffer[200]; //and this is an array of texture coordinates - the Point3d is a simple data type so I can use the DynamicArray DynamicArray<Point3d> texCoordinates; //this variable will keep getting populated with face information GLIndexedPoly temporaryPolygon; //this is where it happens. while (!feof(f)){ //get a line from the file... fgets(buffer, 200, f); //see what line it is... int lineType = getLineType(buffer); if (lineType == VERTEX_INFO){ //we need to read in the three coordinates - skip over the v Point3d vertexCoords = readCoordinates(buffer + 1); result->addVertex(vertexCoords); } if (lineType == TEXTURE_INFO){ Point3d texCoords = readCoordinates(buffer + 2); texCoordinates.push_back(texCoords); } if (lineType == FACE_INFO){ temporaryPolygon.indexes.clear(); int vIndex, tIndex; int flag; char* tmpPointer = buffer+1; while (tmpPointer = getNextIndex(tmpPointer, vIndex, tIndex, flag)){ temporaryPolygon.indexes.push_back(vIndex-1); if (flag & READ_TEXTCOORD_INDEX){ if (tIndex<0) result->setVertexTexCoordinates(vIndex, texCoordinates[texCoordinates.size()+tIndex]); else result->setVertexTexCoordinates(vIndex, texCoordinates[tIndex]); } } if (temporaryPolygon.indexes.size() == 0) tprintf("Found a polygon with zero vertices.\n"); else result->addPoly(temporaryPolygon); } } fclose(f); return result; }