最近在看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 researchcontracts.engineering@imperial.ac.uk.
*
*/
#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命令,即可。