//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;
	}
}
Пример #2
0
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]));
    }
}
Пример #3
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();
}
Пример #4
0
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();
}
Пример #5
0
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);
}
Пример #6
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");
}
Пример #7
0
//------------------------------------------------------------------------------
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;
}
Пример #8
0
//------------------------------------------------------------------------------
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;
}
Пример #9
0
//------------------------------------------------------------------------------
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;
}
Пример #10
0
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;
}