Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add EGL backend for headless rendering on linux #266

Merged
merged 18 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ cmake_policy(SET CMP0054 NEW) # don't implicitly dereference inside if()
# Backend
set(POLYSCOPE_BACKEND_OPENGL3_GLFW "ON" CACHE BOOL "Enable openGL3_glfw backend")
set(POLYSCOPE_BACKEND_OPENGL_MOCK "ON" CACHE BOOL "Enable openGL_mock backend")
set(POLYSCOPE_BACKEND_OPENGL3_EGL "AUTO" CACHE STRING "Enable openGL3_egl backend") # 'AUTO' means "if we're on linux and EGL.h is available"

### Do anything needed for dependencies and bring their stuff in to scope
add_subdirectory(deps)
Expand Down
13 changes: 9 additions & 4 deletions include/polyscope/render/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,9 @@ class ShaderProgram {
class Engine {

public:
// Options

Engine();
virtual ~Engine();

// High-level control
virtual void checkError(bool fatal = false) = 0;
Expand Down Expand Up @@ -505,13 +507,16 @@ class Engine {
virtual std::string getClipboardText() = 0;
virtual void setClipboardText(std::string text) = 0;

// ImGui
// === ImGui

// NOTE: the imgui backend depends on the window manager (e.g. GLFW), so these must be implemented by the lowest-level concrete engine implementation
virtual void initializeImGui() = 0;
virtual void shutdownImGui() = 0;
void setImGuiStyle();
ImFontAtlas* getImGuiGlobalFontAtlas();
virtual void ImGuiNewFrame() = 0;
virtual void ImGuiRender() = 0;

void setImGuiStyle();
ImFontAtlas* getImGuiGlobalFontAtlas();
virtual void showTextureInImGuiWindow(std::string windowName, TextureBuffer* buffer);


Expand Down
55 changes: 10 additions & 45 deletions include/polyscope/render/opengl/gl_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,27 @@
#include "polyscope/render/engine.h"
#include "polyscope/utilities.h"

#include <unordered_map>

// Note: DO NOT include this header throughout polyscope, and do not directly make openGL calls. This header should only
// be used to construct an instance of Engine. engine.h gives the render API, all render calls should pass through that.

#ifdef __APPLE__
// this means this file can only compile openGL on apple if we are also using glfw, but that's fine, because we only
// ever use the two together on apple
#define GLFW_INCLUDE_GLCOREARB
#include "GLFW/glfw3.h"
#else
#include "glad/glad.h"
// glad must come first
#include "GLFW/glfw3.h"
#endif

#ifdef _WIN32
#undef APIENTRY
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#endif

#include "imgui.h"
#define IMGUI_IMPL_OPENGL_LOADER_GLAD
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"

#include <unordered_map>

// Note: DO NOT include this header throughout polyscope, and do not directly make openGL calls. This header should only
// be used to construct an instance of Engine. engine.h gives the render API, all render calls should pass through that.


namespace polyscope {
namespace render {
namespace backend_openGL3_glfw {
namespace backend_openGL3 {

// Some very nice typdefs
typedef GLuint TextureBufferHandle;
Expand Down Expand Up @@ -377,12 +368,11 @@ class GLShaderProgram : public ShaderProgram {
class GLEngine : public Engine {
public:
GLEngine();
virtual ~GLEngine();

// High-level control
void initialize();
void checkError(bool fatal = false) override;

void swapDisplayBuffers() override;
std::vector<unsigned char> readDisplayBuffer() override;

// Manage render state
Expand All @@ -391,28 +381,6 @@ class GLEngine : public Engine {
void setColorMask(std::array<bool, 4> mask = {true, true, true, true}) override;
void setBackfaceCull(bool newVal) override;

// === Windowing and framework things
void makeContextCurrent() override;
void focusWindow() override;
void showWindow() override;
void hideWindow() override;
void updateWindowSize(bool force = false) override;
void applyWindowSize() override;
void setWindowResizable(bool newVal) override;
bool getWindowResizable() override;
std::tuple<int, int> getWindowPos() override;
bool windowRequestsClose() override;
void pollEvents() override;
bool isKeyPressed(char c) override; // for lowercase a-z and 0-9 only
int getKeyCode(char c) override; // for lowercase a-z and 0-9 only
std::string getClipboardText() override;
void setClipboardText(std::string text) override;

// ImGui
void initializeImGui() override;
void shutdownImGui() override;
void ImGuiNewFrame() override;
void ImGuiRender() override;

// === Factory methods

Expand Down Expand Up @@ -462,9 +430,6 @@ class GLEngine : public Engine {
// Helpers
virtual void createSlicePlaneFliterRule(std::string name) override;

// Internal windowing and engine details
GLFWwindow* mainWindow = nullptr;

// Shader program & rule caches
std::unordered_map<std::string, std::pair<std::vector<ShaderStageSpecification>, DrawMode>> registeredShaderPrograms;
std::unordered_map<std::string, ShaderReplacementRule> registeredShaderRules;
Expand All @@ -478,6 +443,6 @@ class GLEngine : public Engine {
ShaderReplacementDefaults defaults);
};

} // namespace backend_openGL3_glfw
} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
80 changes: 80 additions & 0 deletions include/polyscope/render/opengl/gl_engine_egl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run

#pragma once

#include "polyscope/options.h"
#include "polyscope/render/engine.h"
#include "polyscope/utilities.h"

#ifdef __APPLE__
#error "EGL backend is not supported on macOS. Disable it in the CMake build options."
#else
#include "glad/glad.h"
// glad must come first
#include <EGL/egl.h>
#endif


#include "imgui.h"

#include "polyscope/render/opengl/gl_engine.h"

#include <unordered_map>

// Note: DO NOT include this header throughout polyscope, and do not directly make openGL calls. This header should only
// be used to construct an instance of Engine. engine.h gives the render API, all render calls should pass through that.


namespace polyscope {
namespace render {
namespace backend_openGL3 {


class GLEngineEGL : public GLEngine {

public:
GLEngineEGL();
virtual ~GLEngineEGL();

// High-level control
void initialize();
void swapDisplayBuffers() override;
void checkError(bool fatal = false) override;

// === Windowing and framework things

void makeContextCurrent() override;
void pollEvents() override;

void focusWindow() override;
void showWindow() override;
void hideWindow() override;
void updateWindowSize(bool force = false) override;
void applyWindowSize() override;
void setWindowResizable(bool newVal) override;
bool getWindowResizable() override;
std::tuple<int, int> getWindowPos() override;
bool windowRequestsClose() override;

bool isKeyPressed(char c) override; // for lowercase a-z and 0-9 only
int getKeyCode(char c) override; // for lowercase a-z and 0-9 only
std::string getClipboardText() override;
void setClipboardText(std::string text) override;


// === ImGui

void initializeImGui() override;
void shutdownImGui() override;
void ImGuiNewFrame() override;
void ImGuiRender() override;

protected:
// Internal windowing and engine details
EGLDisplay eglDisplay;
EGLContext eglContext;
};

} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
91 changes: 91 additions & 0 deletions include/polyscope/render/opengl/gl_engine_glfw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run

#pragma once

#include "polyscope/options.h"
#include "polyscope/render/engine.h"
#include "polyscope/utilities.h"

#ifdef __APPLE__
#define GLFW_INCLUDE_GLCOREARB
#include "GLFW/glfw3.h"
#else
#include "glad/glad.h"
// glad must come first
#include "GLFW/glfw3.h"
#endif

#ifdef _WIN32
#undef APIENTRY
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#include <GLFW/glfw3native.h>
#endif

#include "imgui.h"
#define IMGUI_IMPL_OPENGL_LOADER_GLAD
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"

#include "polyscope/render/opengl/gl_engine.h"

#include <unordered_map>

// Note: DO NOT include this header throughout polyscope, and do not directly make openGL calls. This header should only
// be used to construct an instance of Engine. engine.h gives the render API, all render calls should pass through that.


namespace polyscope {
namespace render {
namespace backend_openGL3 {


class GLEngineGLFW : public GLEngine {

public:

GLEngineGLFW();
virtual ~GLEngineGLFW();

// High-level control
void initialize();
void swapDisplayBuffers() override;

// === Windowing and framework things

void makeContextCurrent() override;
void pollEvents() override;

void focusWindow() override;
void showWindow() override;
void hideWindow() override;
void updateWindowSize(bool force = false) override;
void applyWindowSize() override;
void setWindowResizable(bool newVal) override;
bool getWindowResizable() override;
std::tuple<int, int> getWindowPos() override;
bool windowRequestsClose() override;

bool isKeyPressed(char c) override; // for lowercase a-z and 0-9 only
int getKeyCode(char c) override; // for lowercase a-z and 0-9 only
std::string getClipboardText() override;
void setClipboardText(std::string text) override;


// === ImGui

void initializeImGui() override;
void shutdownImGui() override;
void ImGuiNewFrame() override;
void ImGuiRender() override;

protected:

// Internal windowing and engine details
GLFWwindow* mainWindow = nullptr;

};

} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
4 changes: 2 additions & 2 deletions include/polyscope/render/opengl/shaders/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

namespace polyscope {
namespace render {
namespace backend_openGL3_glfw {
namespace backend_openGL3 {

extern const char* shaderCommonSource;

} // namespace backend_openGL3_glfw
} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
4 changes: 2 additions & 2 deletions include/polyscope/render/opengl/shaders/cylinder_shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace polyscope {
namespace render {
namespace backend_openGL3_glfw {
namespace backend_openGL3 {

// High level pipeline
extern const ShaderStageSpecification FLEX_CYLINDER_VERT_SHADER;
Expand All @@ -23,6 +23,6 @@ extern const ShaderReplacementRule CYLINDER_CULLPOS_FROM_MID;
extern const ShaderReplacementRule CYLINDER_VARIABLE_SIZE;


} // namespace backend_openGL3_glfw
} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
4 changes: 2 additions & 2 deletions include/polyscope/render/opengl/shaders/gizmo_shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace polyscope {
namespace render {
namespace backend_openGL3_glfw {
namespace backend_openGL3 {

// Stages
extern const ShaderStageSpecification TRANSFORMATION_GIZMO_ROT_VERT;
Expand All @@ -17,6 +17,6 @@ extern const ShaderStageSpecification SLICE_PLANE_FRAG_SHADER;
// Rules
extern const ShaderReplacementRule TRANSFORMATION_GIZMO_VEC;

} // namespace backend_openGL3_glfw
} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
4 changes: 2 additions & 2 deletions include/polyscope/render/opengl/shaders/grid_shaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace polyscope {
namespace render {
namespace backend_openGL3_glfw {
namespace backend_openGL3 {

// High level pipeline
extern const ShaderStageSpecification FLEX_GRIDCUBE_VERT_SHADER;
Expand All @@ -24,6 +24,6 @@ extern const ShaderReplacementRule GRIDCUBE_CONSTANT_PICK;
extern const ShaderReplacementRule GRIDCUBE_CULLPOS_FROM_CENTER;


} // namespace backend_openGL3_glfw
} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace polyscope {
namespace render {
namespace backend_openGL3_glfw {
namespace backend_openGL3 {

extern const ShaderStageSpecification GROUND_PLANE_VERT_SHADER;
extern const ShaderStageSpecification GROUND_PLANE_TILE_FRAG_SHADER;
Expand All @@ -16,6 +16,6 @@ extern const ShaderStageSpecification GROUND_PLANE_SHADOW_FRAG_SHADER;
// Rules
// extern const ShaderReplacementRule RULE_NAME;

} // namespace backend_openGL3_glfw
} // namespace backend_openGL3
} // namespace render
} // namespace polyscope
Loading