在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命令,即可。