在Windows平臺上編譯ElasticFusion

最近在看ElasticFusion的文章,打算在Windows平臺上進行復現,由於涉及到衆多軟件,故在此記錄一下編譯過程,以備後續升級軟件使用。這篇主要記錄完整的Debug x64版編譯過程, 如果不想自己編譯,可直接從用我的百度雲分享,這裏也有編譯所需的全部文件。
我的項目根目錄是D:\ElasticFusionDebug,其下屬的文件目錄示例結構如下:

  • Eigen
    • blas
  • ElasticFusion
  • OpenNI2
    • OpenNI.sln
  • Pangolin
  • SuiteSparse
    • build

1. OpenNI2 Debug x64版

按照我的博客“ElasticFusion之OpenNI2編譯”編譯OpenNI的Debug x64版本。

2. SuiteSparse Release x64版

按照我的博客“ElasticFusion之Eigen+SuiteSparce編譯”編譯SuiteSparse的Release x64版本,不能編譯Debug x64版。

3. Pangolin Debug x64版

按照我的博客“ElasticFusion之Pangolin編譯”編譯Pangolin的Debug x64版。

4. ElasticFusion Core Debug x64版

參考鏈接
將下面的代碼保存爲static_glew_init.hpp,並放到在ElasticFusion/Core/src文件夾下。

/*
Function to get, find, or initialize Pangolin context and initialize glew
*/

#if !defined(__STATIC_GLEW_INIT_HPP__)
#define __STATIC_GLEW_INIT_HPP__
#define GLEW_STATIC
#include <pangolin/pangolin.h>
#include <pangolin/gl/gl.h>
#include <pangolin/gl/glplatform.h>
#include <pangolin/display/display_internal.h>
#include <string>

static inline void staticGlewInit(std::string name = "Main")
{
    // GetCurrentContext
    pangolin::PangolinGl* context = pangolin::GetCurrentContext();
    if (context == NULL)
    {
        // Find Context
        context = pangolin::FindContext(name);
        if (context == NULL)
        {
            // Create new
            std::shared_ptr<pangolin::PangolinGl> newcontext(new pangolin::PangolinGl());
            AddNewContext(name, newcontext);
            context = newcontext.get();
            std::cout << "Pangolin Context" << name << "created." << std::endl;
        }
        else
        {
            std::cout << "Pangolin Context" << name << "already exists." << std::endl;
        }
        // Make Current Context
        context->MakeCurrent();

        //  Initialize GLEW
        glewExperimental = GL_TRUE; // GL_FALSE; 
        GLenum error = glGetError();

        if (error != GL_NO_ERROR)
        {
            std::cout << "OpenGL Error: " << error << std::endl;
        }

        GLenum glewinit = glewInit();
        if (glewinit != GLEW_OK) {
            std::cout << "Glew Error: " << glewGetErrorString(glewinit) << std::endl;
            exit(EXIT_FAILURE);
        }
    }
    else
    {
        std::cout << "Pangolin Current Context exists." << std::endl;
    }
}

#endif /* !__STATIC_GLEW_INIT_HPP__ */

修改CMakeLists.txt文件,添加下面兩個變量,如下所示:

set(SUITESPARSE_INCLUDE_DIR "D:/ElasticFusionDebug/SuiteSparse/build/install/include/suitesparse")
set(SUITESPARSE_LIBRARY_DIR "D:/ElasticFusionDebug/SuiteSparse/build/install/lib64")

用CMake生成VS解決方案,打開,在efusion工程Header Files篩選器中添加static_glew_init.hpp。再打開Shaders.h文件,在Shader類Shader()構造函數中添加staticGlewInit()函數,修改後的文件如下所示:

/*
 * This file is part of ElasticFusion.
 *
 * Copyright (C) 2015 Imperial College London
 * 
 * The use of the code within this file and all code within files that 
 * make up the software that is ElasticFusion is permitted for 
 * non-commercial purposes only.  The full terms and conditions that 
 * apply to the code within this file are detailed within the LICENSE.txt 
 * file and at <http://www.imperial.ac.uk/dyson-robotics-lab/downloads/elastic-fusion/elastic-fusion-license/> 
 * unless explicitly stated.  By downloading this file you agree to 
 * comply with these terms.
 *
 * If you wish to use any of this code for commercial purposes then 
 * please email [email protected].
 *
 */

#ifndef SHADERS_SHADERS_H_
#define SHADERS_SHADERS_H_

#include <pangolin/gl/glsl.h>
#include <memory>
#include "../Utils/Parse.h"
#include "../static_glew_init.hpp"
#include "Uniform.h"

class Shader : public pangolin::GlSlProgram
{
    public:
        Shader()
        {
            // glewInit
            staticGlewInit();
        }

        GLuint programId()
        {
            return prog;
        }

        void setUniform(const Uniform & v)
        {
            GLuint loc = glGetUniformLocation(prog, v.id.c_str());

            switch(v.t)
            {
                case Uniform::INT:
                    glUniform1i(loc, v.i);
                    break;
                case Uniform::FLOAT:
                    glUniform1f(loc, v.f);
                    break;
                case Uniform::VEC2:
                    glUniform2f(loc, v.v2(0), v.v2(1));
                    break;
                case Uniform::VEC3:
                    glUniform3f(loc, v.v3(0), v.v3(1), v.v3(2));
                    break;
                case Uniform::VEC4:
                    glUniform4f(loc, v.v4(0), v.v4(1), v.v4(2), v.v4(3));
                    break;
                case Uniform::MAT4:
                    glUniformMatrix4fv(loc, 1, false, v.m4.data());
                    break;
                default:
                    assert(false && "Uniform type not implemented!");
                    break;
            }
        }
};

static inline std::shared_ptr<Shader> loadProgramGeomFromFile(const std::string& vertex_shader_file, const std::string& geometry_shader_file)
{
    std::shared_ptr<Shader> program = std::make_shared<Shader>();

    program->AddShaderFromFile(pangolin::GlSlVertexShader, Parse::get().shaderDir() + "/" + vertex_shader_file, {}, {Parse::get().shaderDir()});
    program->AddShaderFromFile(pangolin::GlSlGeometryShader, Parse::get().shaderDir() + "/" + geometry_shader_file, {}, {Parse::get().shaderDir()});
    program->Link();

    return program;
}

static inline std::shared_ptr<Shader> loadProgramFromFile(const std::string& vertex_shader_file)
{
    std::shared_ptr<Shader> program = std::make_shared<Shader>();

    program->AddShaderFromFile(pangolin::GlSlVertexShader, Parse::get().shaderDir() + "/" + vertex_shader_file, {}, {Parse::get().shaderDir()});
    program->Link();

    return program;
}

static inline std::shared_ptr<Shader> loadProgramFromFile(const std::string& vertex_shader_file, const std::string& fragment_shader_file)
{
    std::shared_ptr<Shader> program = std::make_shared<Shader>();

    program->AddShaderFromFile(pangolin::GlSlVertexShader, Parse::get().shaderDir() + "/" + vertex_shader_file, {}, {Parse::get().shaderDir()});
    program->AddShaderFromFile(pangolin::GlSlFragmentShader, Parse::get().shaderDir() + "/" + fragment_shader_file, {}, {Parse::get().shaderDir()});
    program->Link();

    return program;
}

static inline std::shared_ptr<Shader> loadProgramFromFile(const std::string& vertex_shader_file, const std::string& fragment_shader_file, const std::string& geometry_shader_file)
{
    std::shared_ptr<Shader> program = std::make_shared<Shader>();

    program->AddShaderFromFile(pangolin::GlSlVertexShader, Parse::get().shaderDir() + "/" + vertex_shader_file, {}, {Parse::get().shaderDir()});
    program->AddShaderFromFile(pangolin::GlSlGeometryShader, Parse::get().shaderDir() + "/" + geometry_shader_file, {}, {Parse::get().shaderDir()});
    program->AddShaderFromFile(pangolin::GlSlFragmentShader, Parse::get().shaderDir() + "/" + fragment_shader_file, {}, {Parse::get().shaderDir()});
    program->Link();

    return program;
}

#endif /* SHADERS_SHADERS_H_ */

保存,編譯。

5. ElasticFusion GUI Debug x64版

修改CMakeLists.txt文件,添加幾個路徑變量,如下所示:

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}")
set(JPEG_LIBRARY "D:/ElasticFusionDebug/Pangolin/build/external/libjpeg/lib/jpeg.lib")
set(JPEG_INCLUDE_DIR "D:/ElasticFusionDebug/Pangolin/build/external/libjpeg/include")
set(ZLIB_LIBRARY "D:/ElasticFusionDebug/Pangolin/build/external/zlib/lib/zlibd.lib")
set(ZLIB_INCLUDE_DIR "D:/ElasticFusionDebug/Pangolin/build/external/zlib/include")
set(OPENNI2_LIBRARY "D:/ElasticFusionDebug/OpenNI2/Bin/x64-Debug/OpenNI2.lib")
set(SUITESPARSE_INCLUDE_DIR "D:/ElasticFusionDebug/SuiteSparse/build/install/include/suitesparse")
set(SUITESPARSE_LIBRARY_DIR "D:/ElasticFusionDebug/SuiteSparse/build/install/lib64")
set(EFUSION_LIBRARY "D:/ElasticFusionDebug/ElasticFusion/Core/src/build/Debug/efusion.lib")
set(BLAS_LIBRARIES_DIR "D:/ElasticFusionDebug/SuiteSparse/build/install/lib64/lapack_blas_windows")
set(LAPACK_LIBRARIES_DIR  "D:/ElasticFusionDebug/SuiteSparse/build/install/lib64/lapack_blas_windows")

需要根據實際路徑進行修改
用CMake生成VS解決方案,編譯。

6. 測試

將D:\ElasticFusionDebug\OpenNI2\Bin\x64-Debug下OpenNI2文件夾和OpenNI2.dll,將D:\ElasticFusionDebug\SuiteSparse\build\install\lib64\lapack_blas_windows下五個dll文件,將D:\ElasticFusionDebug\Pangolin\build\external\zlib\bin下zlibd.dll,將D:\ElasticFusionDebug\ElasticFusion\Core\src\build\Debug下efusion.dll,拷貝到D:\ElasticFusionDebug\ElasticFusion\GUI\src\build\Debug下。

打開命令行窗口,cd到D:\ElasticFusionDebug\ElasticFusion\GUI\src\build\Debug,插上Kinect一代,運行ElasticFusion.exe命令,即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章