Support for multiple OpenGL Loaders: epoxy, glbinding, glad, glew
parent
72ec16aefb
commit
12fdcc237f
|
@ -92,16 +92,15 @@ endif()
|
||||||
|
|
||||||
find_package(Optional REQUIRED)
|
find_package(Optional REQUIRED)
|
||||||
|
|
||||||
pkg_search_module(EPOXY REQUIRED epoxy)
|
|
||||||
pkg_search_module(GLFW REQUIRED glfw3)
|
pkg_search_module(GLFW REQUIRED glfw3)
|
||||||
pkg_search_module(SQLITE3 REQUIRED sqlite3)
|
pkg_search_module(SQLITE3 REQUIRED sqlite3)
|
||||||
pkg_search_module(LIBSODIUM REQUIRED libsodium)
|
pkg_search_module(LIBSODIUM REQUIRED libsodium)
|
||||||
include_directories(BEFORE
|
include_directories(BEFORE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||||
${ETC_INCLUDE_DIRS}
|
${ETC_INCLUDE_DIRS}
|
||||||
${LUA_INCLUDE_DIR}
|
${LUA_INCLUDE_DIR}
|
||||||
${LZFX_INCLUDE_DIRS}
|
${LZFX_INCLUDE_DIRS}
|
||||||
${ENET_INCLUDE_DIRS}
|
${ENET_INCLUDE_DIRS}
|
||||||
${EPOXY_INCLUDE_DIRS}
|
|
||||||
${GLFW_INCLUDE_DIRS}
|
${GLFW_INCLUDE_DIRS}
|
||||||
${LIBSODIUM_INCLUDE_DIRS}
|
${LIBSODIUM_INCLUDE_DIRS}
|
||||||
${SQLITE3_INCLUDE_DIRS}
|
${SQLITE3_INCLUDE_DIRS}
|
||||||
|
@ -114,27 +113,64 @@ include_directories(BEFORE
|
||||||
#file(GLOB_RECURSE FILELIST "*.h" "*.hpp" "*.cpp")
|
#file(GLOB_RECURSE FILELIST "*.h" "*.hpp" "*.cpp")
|
||||||
#add_custom_target(files SOURCES ${FILELIST})
|
#add_custom_target(files SOURCES ${FILELIST})
|
||||||
|
|
||||||
# Add diggler executable target
|
### Allow subdirs to add params to the `diggler` target
|
||||||
|
# Sources
|
||||||
set_property(GLOBAL PROPERTY DIGGLER_SOURCE_FILES "")
|
set_property(GLOBAL PROPERTY DIGGLER_SOURCE_FILES "")
|
||||||
macro(diggler_add_sources)
|
function(diggler_add_sources)
|
||||||
get_property(SRCS GLOBAL PROPERTY DIGGLER_SOURCE_FILES)
|
get_property(SRCS GLOBAL PROPERTY DIGGLER_SOURCE_FILES)
|
||||||
list(APPEND SRCS ${ARGV})
|
list(APPEND SRCS ${ARGV})
|
||||||
set_property(GLOBAL PROPERTY DIGGLER_SOURCE_FILES "${SRCS}")
|
set_property(GLOBAL PROPERTY DIGGLER_SOURCE_FILES "${SRCS}")
|
||||||
endmacro(diggler_add_sources)
|
endfunction(diggler_add_sources)
|
||||||
|
|
||||||
|
# Definitions
|
||||||
|
set_property(GLOBAL PROPERTY DIGGLER_DEFINITIONS "")
|
||||||
|
function(diggler_add_definition)
|
||||||
|
get_property(DEFS GLOBAL PROPERTY DIGGLER_DEFINITIONS)
|
||||||
|
list(APPEND DEFS "${ARGV0}")
|
||||||
|
set_property(GLOBAL PROPERTY DIGGLER_DEFINITIONS "${DEFS}")
|
||||||
|
endfunction(diggler_add_definition)
|
||||||
|
|
||||||
|
# Include directories
|
||||||
|
set_property(GLOBAL PROPERTY DIGGLER_INCLUDE_DIRECTORIES "")
|
||||||
|
function(diggler_include_directories)
|
||||||
|
get_property(INCDIRS GLOBAL PROPERTY DIGGLER_INCLUDE_DIRECTORIES)
|
||||||
|
list(APPEND INCDIRS ${ARGV})
|
||||||
|
set_property(GLOBAL PROPERTY DIGGLER_INCLUDE_DIRECTORIES "${INCDIRS}")
|
||||||
|
endfunction(diggler_include_directories)
|
||||||
|
|
||||||
|
# Link libraries
|
||||||
|
set_property(GLOBAL PROPERTY DIGGLER_LINK_LIBRARIES "")
|
||||||
|
function(diggler_link_libraries)
|
||||||
|
get_property(LIBS GLOBAL PROPERTY DIGGLER_LINK_LIBRARIES)
|
||||||
|
list(APPEND LIBS ${ARGV})
|
||||||
|
set_property(GLOBAL PROPERTY DIGGLER_LINK_LIBRARIES "${LIBS}")
|
||||||
|
endfunction(diggler_link_libraries)
|
||||||
|
|
||||||
set(DIGGLER_USED_ROOT_CMAKELISTS TRUE)
|
set(DIGGLER_USED_ROOT_CMAKELISTS TRUE)
|
||||||
|
|
||||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/src")
|
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
|
||||||
|
### Create target and apply parameters
|
||||||
|
# Include directories
|
||||||
|
get_property(INCDIRS GLOBAL PROPERTY DIGGLER_INCLUDE_DIRECTORIES)
|
||||||
|
include_directories(BEFORE ${INCDIRS})
|
||||||
|
|
||||||
|
# Sources
|
||||||
get_property(SRCS GLOBAL PROPERTY DIGGLER_SOURCE_FILES)
|
get_property(SRCS GLOBAL PROPERTY DIGGLER_SOURCE_FILES)
|
||||||
add_executable(diggler ${SRCS})
|
add_executable(diggler ${SRCS})
|
||||||
|
|
||||||
|
# Definitions
|
||||||
|
get_property(DEFS GLOBAL PROPERTY DIGGLER_DEFINITIONS)
|
||||||
|
target_compile_definitions(diggler PUBLIC ${DEFS})
|
||||||
|
|
||||||
|
# Link libraries
|
||||||
|
get_property(LIBS GLOBAL PROPERTY DIGGLER_LINK_LIBRARIES)
|
||||||
target_link_libraries(diggler
|
target_link_libraries(diggler
|
||||||
|
${LIBS}
|
||||||
${ETC_LIBRARIES}
|
${ETC_LIBRARIES}
|
||||||
${LUA_LIBRARY}
|
${LUA_LIBRARY}
|
||||||
${LZFX_LIBRARIES}
|
${LZFX_LIBRARIES}
|
||||||
${ENET_LIBRARIES}
|
${ENET_LIBRARIES}
|
||||||
${EPOXY_LIBRARIES}
|
|
||||||
${GLFW_LIBRARIES}
|
${GLFW_LIBRARIES}
|
||||||
${LIBSODIUM_LIBRARIES}
|
${LIBSODIUM_LIBRARIES}
|
||||||
${SQLITE3_LIBRARIES}
|
${SQLITE3_LIBRARIES}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
KHR
|
||||||
|
glad
|
|
@ -0,0 +1 @@
|
||||||
|
glad.c
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef CLOUDS_HPP
|
#ifndef DIGGLER_CLOUDS_HPP
|
||||||
#define CLOUDS_HPP
|
#define DIGGLER_CLOUDS_HPP
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include "render/gl/OpenGL.hpp"
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "render/gl/VBO.hpp"
|
#include "render/gl/VBO.hpp"
|
||||||
|
@ -37,4 +37,4 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* DIGGLER_CLOUDS_HPP */
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "EscMenu.hpp"
|
#include "EscMenu.hpp"
|
||||||
#include <epoxy/gl.h>
|
|
||||||
|
#include "render/gl/OpenGL.hpp"
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
#include "Game.hpp"
|
#include "Game.hpp"
|
||||||
#include "ui/Text.hpp"
|
#include "ui/Text.hpp"
|
||||||
#include "ui/Button.hpp"
|
#include "ui/Button.hpp"
|
||||||
|
|
|
@ -45,6 +45,8 @@ static void APIENTRY glDebugCallback(GLenum source, GLenum type, GLuint id,
|
||||||
case GL_DEBUG_SOURCE_OTHER:
|
case GL_DEBUG_SOURCE_OTHER:
|
||||||
sourceStr = "OTH";
|
sourceStr = "OTH";
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
const char *typeStr = "???";
|
const char *typeStr = "???";
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -75,6 +77,8 @@ static void APIENTRY glDebugCallback(GLenum source, GLenum type, GLuint id,
|
||||||
case GL_DEBUG_TYPE_OTHER:
|
case GL_DEBUG_TYPE_OTHER:
|
||||||
typeStr = "OTH";
|
typeStr = "OTH";
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
const char *severityStr = "??";
|
const char *severityStr = "??";
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
|
@ -90,6 +94,8 @@ static void APIENTRY glDebugCallback(GLenum source, GLenum type, GLuint id,
|
||||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||||
severityStr = "NT";
|
severityStr = "NT";
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
char line[3 + 1 + 3 + 1 + 2 + 2 + 1];
|
char line[3 + 1 + 3 + 1 + 2 + 2 + 1];
|
||||||
std::snprintf(line, sizeof(line)/sizeof(line[0]), "%3s %3s %2s] ", sourceStr, typeStr, severityStr);
|
std::snprintf(line, sizeof(line)/sizeof(line[0]), "%3s %3s %2s] ", sourceStr, typeStr, severityStr);
|
||||||
|
@ -101,7 +107,7 @@ GameWindow::GameWindow(Game *G) : G(G) {
|
||||||
if (InstanceCount++ == 0) {
|
if (InstanceCount++ == 0) {
|
||||||
glfwSetErrorCallback(glfwErrorCallback);
|
glfwSetErrorCallback(glfwErrorCallback);
|
||||||
int glfwStatus = glfwInit();
|
int glfwStatus = glfwInit();
|
||||||
if (glfwStatus != GL_TRUE) {
|
if (glfwStatus != GLFW_TRUE) {
|
||||||
std::ostringstream err;
|
std::ostringstream err;
|
||||||
err << "GLFW init failed (" << glfwStatus << ')';
|
err << "GLFW init failed (" << glfwStatus << ')';
|
||||||
throw std::runtime_error(err.str());
|
throw std::runtime_error(err.str());
|
||||||
|
@ -122,7 +128,7 @@ GameWindow::GameWindow(Game *G) : G(G) {
|
||||||
//glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
//glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_window = glfwCreateWindow(m_w, m_h, "Diggler", nullptr, nullptr);
|
m_window = glfwCreateWindow(m_w, m_h, "Diggler", nullptr, nullptr);
|
||||||
|
@ -131,6 +137,9 @@ GameWindow::GameWindow(Game *G) : G(G) {
|
||||||
throw std::runtime_error("GLFW window creation failed");
|
throw std::runtime_error("GLFW window creation failed");
|
||||||
}
|
}
|
||||||
glfwMakeContextCurrent(m_window);
|
glfwMakeContextCurrent(m_window);
|
||||||
|
|
||||||
|
Render::gl::OpenGL::init();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
|
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
|
||||||
glDebugMessageCallback(glDebugCallback, nullptr);
|
glDebugMessageCallback(glDebugCallback, nullptr);
|
||||||
|
@ -173,7 +182,14 @@ GameWindow::GameWindow(Game *G) : G(G) {
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
getOutputStreamRaw() << "-- Epoxy GL" << (epoxy_is_desktop_gl() ? "" : "ES") << epoxy_gl_version() << std::endl;
|
auto glver = Render::gl::OpenGL::version();
|
||||||
|
getOutputStreamRaw() << "-- " <<
|
||||||
|
Render::gl::OpenGL::loaderName() << ' ' <<
|
||||||
|
Render::gl::OpenGL::loaderVersion() << " -- GL" <<
|
||||||
|
(glver.isGLES ? "ES" : "") << ' ' <<
|
||||||
|
glver.major << '.' << glver.minor <<
|
||||||
|
(glver.isCore ? " Core" : "") <<
|
||||||
|
(glver.isForward ? " FC" : "") << ' ' << std::endl;
|
||||||
|
|
||||||
if (InstanceCount == 1) { // If we're the first instance
|
if (InstanceCount == 1) { // If we're the first instance
|
||||||
const uint8 *GL_version = glGetString(GL_VERSION);
|
const uint8 *GL_version = glGetString(GL_VERSION);
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
#ifndef GAME_WINDOW_HPP
|
#ifndef GAME_WINDOW_HPP
|
||||||
#define GAME_WINDOW_HPP
|
#define GAME_WINDOW_HPP
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <alc.h>
|
#include <alc.h>
|
||||||
#include <epoxy/gl.h>
|
|
||||||
|
#include "render/gl/OpenGL.hpp"
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <glm/detail/type_mat.hpp>
|
#include <glm/detail/type_mat.hpp>
|
||||||
|
|
||||||
#include "Platform.hpp"
|
#include "Platform.hpp"
|
||||||
#include "ui/Manager.hpp"
|
#include "ui/Manager.hpp"
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#ifndef PLAYER_HPP
|
#ifndef DIGGLER_PLAYER_HPP
|
||||||
#define PLAYER_HPP
|
#define DIGGLER_PLAYER_HPP
|
||||||
#include "Platform.hpp"
|
#include "Platform.hpp"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "render/gl/OpenGL.hpp"
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <epoxy/gl.h>
|
|
||||||
|
|
||||||
#include "platform/PreprocUtils.hpp"
|
#include "platform/PreprocUtils.hpp"
|
||||||
#include "network/Network.hpp"
|
#include "network/Network.hpp"
|
||||||
|
@ -75,4 +75,4 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* DIGGLER_PLAYER_HPP */
|
||||||
|
|
|
@ -40,9 +40,9 @@ Texture::Texture(const std::string &path, PixelFormat format) {
|
||||||
case PixelFormat::RGBA:
|
case PixelFormat::RGBA:
|
||||||
stbiFormat = STBI_rgb_alpha;
|
stbiFormat = STBI_rgb_alpha;
|
||||||
break;
|
break;
|
||||||
case PixelFormat::Monochrome8:
|
/* case PixelFormat::Monochrome8:
|
||||||
stbiFormat = STBI_grey;
|
stbiFormat = STBI_grey;
|
||||||
break;
|
break;*/
|
||||||
}
|
}
|
||||||
int width, height, channels;
|
int width, height, channels;
|
||||||
unsigned char *ptr = nullptr;
|
unsigned char *ptr = nullptr;
|
||||||
|
@ -89,7 +89,7 @@ GLenum getFilterGlConstant(Texture::Filter filter) {
|
||||||
case Texture::Filter::Nearest:
|
case Texture::Filter::Nearest:
|
||||||
return GL_NEAREST;
|
return GL_NEAREST;
|
||||||
}
|
}
|
||||||
return 0;
|
return GL_INVALID_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setFiltering(Filter min, Filter mag) {
|
void Texture::setFiltering(Filter min, Filter mag) {
|
||||||
|
@ -100,7 +100,7 @@ void Texture::setFiltering(Filter min, Filter mag) {
|
||||||
PopBoundTex();
|
PopBoundTex();
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLint getWrapGlConstant(Texture::Wrapping wrap) {
|
static GLenum getWrapGlConstant(Texture::Wrapping wrap) {
|
||||||
switch (wrap) {
|
switch (wrap) {
|
||||||
case Texture::Wrapping::ClampEdge:
|
case Texture::Wrapping::ClampEdge:
|
||||||
return GL_CLAMP_TO_EDGE;
|
return GL_CLAMP_TO_EDGE;
|
||||||
|
@ -111,7 +111,7 @@ static GLint getWrapGlConstant(Texture::Wrapping wrap) {
|
||||||
case Texture::Wrapping::MirroredRepeat:
|
case Texture::Wrapping::MirroredRepeat:
|
||||||
return GL_MIRRORED_REPEAT;
|
return GL_MIRRORED_REPEAT;
|
||||||
}
|
}
|
||||||
return 0;
|
return GL_INVALID_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setWrapping(Wrapping s, Wrapping t) {
|
void Texture::setWrapping(Wrapping s, Wrapping t) {
|
||||||
|
@ -130,9 +130,9 @@ void Texture::setPlaceholder() {
|
||||||
case PixelFormat::RGBA:
|
case PixelFormat::RGBA:
|
||||||
pxLength = 4;
|
pxLength = 4;
|
||||||
break;
|
break;
|
||||||
case PixelFormat::Monochrome8:
|
/* case PixelFormat::Monochrome8:
|
||||||
pxLength = 1;
|
pxLength = 1;
|
||||||
break;
|
break;*/
|
||||||
}
|
}
|
||||||
unsigned char *white = new unsigned char[m_w * m_h * pxLength];
|
unsigned char *white = new unsigned char[m_w * m_h * pxLength];
|
||||||
memset(white, 255, m_w * m_h * pxLength);
|
memset(white, 255, m_w * m_h * pxLength);
|
||||||
|
@ -148,11 +148,11 @@ static GLenum getGlTexFormat(Texture::PixelFormat fmt) {
|
||||||
case Texture::PixelFormat::RGBA:
|
case Texture::PixelFormat::RGBA:
|
||||||
return GL_RGBA;
|
return GL_RGBA;
|
||||||
break;
|
break;
|
||||||
case Texture::PixelFormat::Monochrome8:
|
/* case Texture::PixelFormat::Monochrome8:
|
||||||
return GL_R8;
|
return GL_R8;
|
||||||
break;
|
break;*/
|
||||||
}
|
}
|
||||||
return 0;
|
return GL_INVALID_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setTexture(uint w, uint h, const uint8_t *data, PixelFormat format) {
|
void Texture::setTexture(uint w, uint h, const uint8_t *data, PixelFormat format) {
|
||||||
|
@ -223,9 +223,9 @@ uint Texture::requiredBufferSize() {
|
||||||
case PixelFormat::RGBA:
|
case PixelFormat::RGBA:
|
||||||
texelSize = 4;
|
texelSize = 4;
|
||||||
break;
|
break;
|
||||||
case PixelFormat::Monochrome8:
|
/* case PixelFormat::Monochrome8:
|
||||||
texelSize = 1;
|
texelSize = 1;
|
||||||
break;
|
break; */
|
||||||
}
|
}
|
||||||
return m_w * m_h * texelSize;
|
return m_w * m_h * texelSize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
#ifndef TEXTURE_HPP
|
#ifndef DIGGLER_TEXTURE_HPP
|
||||||
#define TEXTURE_HPP
|
#define DIGGLER_TEXTURE_HPP
|
||||||
#include <epoxy/gl.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "render/gl/OpenGL.hpp"
|
||||||
|
|
||||||
namespace Diggler {
|
namespace Diggler {
|
||||||
class Texture {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
enum class PixelFormat {
|
enum class PixelFormat {
|
||||||
RGB,
|
RGB,
|
||||||
RGBA,
|
RGBA,
|
||||||
Monochrome8
|
// Monochrome8
|
||||||
};
|
};
|
||||||
enum class Filter {
|
enum class Filter {
|
||||||
Nearest,
|
Nearest,
|
||||||
|
@ -72,4 +74,4 @@ public:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* DIGGLER_TEXTURE_HPP */
|
||||||
|
|
|
@ -117,6 +117,7 @@ Registry::Registry() :
|
||||||
br.commit();
|
br.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GlobalProperties::IsClient) {
|
||||||
m_texturePacker = new TexturePacker(64*8, 64*8);
|
m_texturePacker = new TexturePacker(64*8, 64*8);
|
||||||
m_texturePacker->freezeTexUpdate(true);
|
m_texturePacker->freezeTexUpdate(true);
|
||||||
|
|
||||||
|
@ -132,10 +133,13 @@ Registry::Registry() :
|
||||||
|
|
||||||
m_texturePacker->freezeTexUpdate(false);
|
m_texturePacker->freezeTexUpdate(false);
|
||||||
m_atlas = m_texturePacker->getAtlas();
|
m_atlas = m_texturePacker->getAtlas();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Registry::~Registry() {
|
Registry::~Registry() {
|
||||||
|
if (GlobalProperties::IsClient) {
|
||||||
delete m_texturePacker;
|
delete m_texturePacker;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TexturePacker::Coord Registry::addTexture(const std::string &texName,
|
TexturePacker::Coord Registry::addTexture(const std::string &texName,
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef DIGGLER_PLATFORM_FIXES_GLIBC
|
||||||
|
#define DIGGLER_PLATFORM_FIXES_GLIBC
|
||||||
|
|
||||||
|
// Disable some names (major, minor, makedev) inappropriately reserved as macros
|
||||||
|
// by the morons glibc devs are.
|
||||||
|
// https://bugzilla.redhat.com/show_bug.cgi?id=130601
|
||||||
|
#ifndef _SYS_SYSMACROS_H
|
||||||
|
#define _SYS_SYSMACROS_H 1
|
||||||
|
#else
|
||||||
|
#undef major
|
||||||
|
#undef minor
|
||||||
|
#undef makedev
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DIGGLER_PLATFORM_FIXES_GLIBC */
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef DIGGLER_PLATFORM_FIXES
|
||||||
|
#define DIGGLER_PLATFORM_FIXES
|
||||||
|
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
#include "Fixes.glibc.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "Fixes.windows.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DIGGLER_PLATFORM_FIXES */
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef DIGGLER_PLATFORM_FIXES_WINDOWS
|
||||||
|
#define DIGGLER_PLATFORM_FIXES_WINDOWS
|
||||||
|
|
||||||
|
// Microsoft has a shitty habit of polluting the user namespace with frequently used names
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
|
#define NOMINMAX 1
|
||||||
|
#include <windows.h>
|
||||||
|
#undef near
|
||||||
|
#undef far
|
||||||
|
|
||||||
|
#endif /* DIGGLER_PLATFORM_FIXES_WINDOWS */
|
|
@ -1,10 +1,51 @@
|
||||||
set(DIGGLER_ENABLE_GL_RENDERER TRUE CACHE BOOL "Enable OpenGL (ES) renderer")
|
set(DIGGLER_ENABLE_GL_RENDERER TRUE CACHE BOOL "Enable OpenGL (ES) renderer")
|
||||||
set(DIGGLER_ENABLE_VK_RENDERER TRUE CACHE BOOL "Enable Vulkan renderer")
|
set(DIGGLER_ENABLE_VK_RENDERER TRUE CACHE BOOL "Enable Vulkan renderer")
|
||||||
|
|
||||||
if(DIGGLER_ENABLE_GL_RENDERER)
|
set(DIGGLER_GL_LOADER "libepoxy" CACHE STRING
|
||||||
|
"OpenGL loader to use. One of 'libepoxy', 'glad', 'glbinding', 'glew'")
|
||||||
|
|
||||||
|
if (DIGGLER_ENABLE_GL_RENDERER)
|
||||||
|
if ("${DIGGLER_GL_LOADER}" STREQUAL "libepoxy")
|
||||||
|
pkg_search_module(EPOXY REQUIRED epoxy)
|
||||||
|
set(DIGGLER_GL_USE_LIBEPOXY TRUE)
|
||||||
|
set(DIGGLER_GL_LOADER_SUPPORTED TRUE)
|
||||||
|
diggler_add_definition("DIGGLER_GL_USE_LIBEPOXY")
|
||||||
|
diggler_include_directories(${EPOXY_INCLUDE_DIRS})
|
||||||
|
diggler_link_libraries(${EPOXY_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
if ("${DIGGLER_GL_LOADER}" STREQUAL "glad")
|
||||||
|
set(DIGGLER_GL_USE_GLAD TRUE)
|
||||||
|
set(DIGGLER_GL_LOADER_SUPPORTED TRUE)
|
||||||
|
diggler_add_definition("DIGGLER_GL_USE_GLAD")
|
||||||
|
diggler_add_sources("${CMAKE_CURRENT_SOURCE_DIR}/../glad.c")
|
||||||
|
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||||
|
diggler_link_libraries(dl)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if ("${DIGGLER_GL_LOADER}" STREQUAL "glbinding")
|
||||||
|
find_package(glbinding REQUIRED)
|
||||||
|
set(DIGGLER_GL_USE_GLAD TRUE)
|
||||||
|
set(DIGGLER_GL_LOADER_SUPPORTED TRUE)
|
||||||
|
diggler_add_definition("DIGGLER_GL_USE_GLBINDING")
|
||||||
|
diggler_include_directories(${glbinding_INCLUDE_DIRS})
|
||||||
|
diggler_link_libraries(glbinding)
|
||||||
|
endif()
|
||||||
|
if ("${DIGGLER_GL_LOADER}" STREQUAL "glew")
|
||||||
|
pkg_search_module(GLEW REQUIRED glew)
|
||||||
|
set(DIGGLER_GL_USE_GLEW TRUE)
|
||||||
|
set(DIGGLER_GL_LOADER_SUPPORTED TRUE)
|
||||||
|
diggler_add_definition("DIGGLER_GL_USE_GLEW")
|
||||||
|
diggler_include_directories(${GLEW_INCLUDE_DIRS})
|
||||||
|
diggler_link_libraries(${GLEW_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT DIGGLER_GL_LOADER_SUPPORTED)
|
||||||
|
message(SEND_ERROR "OpenGL loader \"${DIGGLER_GL_LOADER}\" is unsupported")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory("gl")
|
add_subdirectory("gl")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(DIGGLER_ENABLE_VK_RENDERER)
|
if (DIGGLER_ENABLE_VK_RENDERER)
|
||||||
add_subdirectory("vk")
|
add_subdirectory("vk")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -3,6 +3,8 @@ diggler_add_sources(
|
||||||
${CSD}/FBO.cpp
|
${CSD}/FBO.cpp
|
||||||
${CSD}/FeatureSupport.cpp
|
${CSD}/FeatureSupport.cpp
|
||||||
${CSD}/FontRenderer.cpp
|
${CSD}/FontRenderer.cpp
|
||||||
|
${CSD}/OpenGL.cpp
|
||||||
|
${CSD}/OpenGL.${DIGGLER_GL_LOADER}.cpp
|
||||||
${CSD}/ParticlesRenderer.cpp
|
${CSD}/ParticlesRenderer.cpp
|
||||||
${CSD}/Program.cpp
|
${CSD}/Program.cpp
|
||||||
${CSD}/ProgramManager.cpp
|
${CSD}/ProgramManager.cpp
|
||||||
|
|
|
@ -3,18 +3,6 @@
|
||||||
#include "FeatureSupport.hpp"
|
#include "FeatureSupport.hpp"
|
||||||
#include "Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
||||||
#ifdef IN_IDE_PARSER
|
|
||||||
void glCheck();
|
|
||||||
#else
|
|
||||||
#define glCheck() { GLenum glErr = glGetError(); \
|
|
||||||
if (glErr) { \
|
|
||||||
getDebugStream() << getErrorString(glErr) << std::endl; \
|
|
||||||
} glErr = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (glErr != GL_FRAMEBUFFER_COMPLETE) { \
|
|
||||||
getDebugStream() << getErrorString(glErr) << std::endl; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Diggler {
|
namespace Diggler {
|
||||||
namespace Render {
|
namespace Render {
|
||||||
namespace gl {
|
namespace gl {
|
||||||
|
@ -34,8 +22,13 @@ FBO::FBO(int w, int h, Texture::PixelFormat format, bool stencil) : m_hasStencil
|
||||||
glGenRenderbuffers(1, &rboId);
|
glGenRenderbuffers(1, &rboId);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
|
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
|
||||||
if (stencil) {
|
if (stencil) {
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, FeatureSupport::FBO_ARB ? GL_DEPTH24_STENCIL8 :
|
#ifdef GL_DEPTH24_STENCIL8_OES
|
||||||
GL_DEPTH24_STENCIL8_OES, w, h);
|
const GLenum depth24stencil8 = FeatureSupport::FBO_ARB ? GL_DEPTH24_STENCIL8 :
|
||||||
|
GL_DEPTH24_STENCIL8_OES;
|
||||||
|
#else
|
||||||
|
constexpr GLenum depth24stencil8 = GL_DEPTH24_STENCIL8;
|
||||||
|
#endif
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, depth24stencil8, w, h);
|
||||||
} else {
|
} else {
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, w, h);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, w, h);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +46,14 @@ FBO::FBO(int w, int h, Texture::PixelFormat format, bool stencil) : m_hasStencil
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId);
|
||||||
}
|
}
|
||||||
|
|
||||||
glCheck();
|
GLenum glErr = glGetError();
|
||||||
|
if (glErr != GL_NO_ERROR) {
|
||||||
|
getDebugStream() << getErrorString(glErr) << std::endl;
|
||||||
|
}
|
||||||
|
glErr = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
if (glErr != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
getDebugStream() << getErrorString(glErr) << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBO::resize(int w, int h) {
|
void FBO::resize(int w, int h) {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
#include "../../Texture.hpp"
|
#include "../../Texture.hpp"
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
namespace Diggler {
|
namespace Diggler {
|
||||||
namespace Render {
|
namespace Render {
|
||||||
namespace gl {
|
namespace gl {
|
||||||
|
@ -18,14 +20,14 @@ bool
|
||||||
F::buffer_storage;
|
F::buffer_storage;
|
||||||
|
|
||||||
void F::probe() {
|
void F::probe() {
|
||||||
VAO = epoxy_has_gl_extension("GL_ARB_vertex_array_object") or
|
VAO = OpenGL::hasExtension("GL_ARB_vertex_array_object") or
|
||||||
epoxy_has_gl_extension("GL_OES_vertex_array_object");
|
OpenGL::hasExtension("GL_OES_vertex_array_object");
|
||||||
DSA_ARB = epoxy_has_gl_extension("GL_ARB_direct_state_access");
|
DSA_ARB = OpenGL::hasExtension("GL_ARB_direct_state_access");
|
||||||
DSA_EXT = epoxy_has_gl_extension("GL_EXT_direct_state_access");
|
DSA_EXT = OpenGL::hasExtension("GL_EXT_direct_state_access");
|
||||||
DSA = DSA_ARB or DSA_EXT;
|
DSA = DSA_ARB or DSA_EXT;
|
||||||
shader_image_load_store = epoxy_has_gl_extension("GL_ARB_shader_image_load_store");
|
shader_image_load_store = OpenGL::hasExtension("GL_ARB_shader_image_load_store");
|
||||||
FBO_ARB = epoxy_has_gl_extension("GL_ARB_framebuffer_object");
|
FBO_ARB = OpenGL::hasExtension("GL_ARB_framebuffer_object");
|
||||||
buffer_storage = epoxy_has_gl_extension("GL_ARB_buffer_storage");
|
buffer_storage = OpenGL::hasExtension("GL_ARB_buffer_storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define feature(x) if(x){oss<<#x<<std::endl;}
|
#define feature(x) if(x){oss<<#x<<std::endl;}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
#ifndef DIGGLER_RENDER_GL_FEATURE_SUPPORT_HPP
|
#ifndef DIGGLER_RENDER_GL_FEATURE_SUPPORT_HPP
|
||||||
#define DIGGLER_RENDER_GL_FEATURE_SUPPORT_HPP
|
#define DIGGLER_RENDER_GL_FEATURE_SUPPORT_HPP
|
||||||
|
|
||||||
#include "../../Platform.hpp"
|
#include "../../platform/Types.hpp"
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
|
||||||
|
|
||||||
namespace Diggler {
|
namespace Diggler {
|
||||||
namespace Render {
|
namespace Render {
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace Diggler {
|
||||||
|
namespace Render {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
static std::set<std::string> extensionsSet;
|
||||||
|
|
||||||
|
void OpenGL::probeExtensions() {
|
||||||
|
if (version() >= 30) {
|
||||||
|
#ifdef GL_NUM_EXTENSIONS
|
||||||
|
GLint numExt;
|
||||||
|
glGetIntegerv(GL_NUM_EXTENSIONS, &numExt);
|
||||||
|
for (GLint i = 0; i < numExt; ++i) {
|
||||||
|
extensionsSet.insert(reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, GLuint(i))));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.str(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
|
||||||
|
std::string item;
|
||||||
|
while (std::getline(ss, item, ' ')) {
|
||||||
|
extensionsSet.insert(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::set<std::string>& OpenGL::extensions() {
|
||||||
|
return extensionsSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenGL::hasExtension(const std::string &ext) {
|
||||||
|
return extensionsSet.find(ext) != extensionsSet.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace Diggler {
|
||||||
|
namespace Render {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
void OpenGL::init() {
|
||||||
|
if (!gladLoadGL()) {
|
||||||
|
throw std::runtime_error("GLAD initialization failed");
|
||||||
|
}
|
||||||
|
probeExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<OpenGL::Version> OpenGL::loaderSupportedGLVersions() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGL::Version OpenGL::version() {
|
||||||
|
const int major = GLVersion.major, minor = GLVersion.minor;
|
||||||
|
bool isForward = false;
|
||||||
|
#ifdef GL_CONTEXT_FLAGS
|
||||||
|
if (major >= 3) {
|
||||||
|
GLuint contextFlags;
|
||||||
|
glGetIntegerv(GL_CONTEXT_FLAGS, reinterpret_cast<GLint*>(&contextFlags));
|
||||||
|
isForward = bool(contextFlags & GLuint(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bool isCore = false;
|
||||||
|
#ifdef GL_CONTEXT_PROFILE_MASK
|
||||||
|
if (major >= 3 and (major >= 4 or minor >= 2)) {
|
||||||
|
GLuint profileFlags = 0;
|
||||||
|
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, reinterpret_cast<GLint*>(&profileFlags));
|
||||||
|
isCore = bool(profileFlags & GLuint(GL_CONTEXT_CORE_PROFILE_BIT));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return { major, minor, false, isCore, isForward };
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderName() {
|
||||||
|
return "GLAD";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderVersion() {
|
||||||
|
return "rolling";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
|
#include <glbinding/Binding.h>
|
||||||
|
#include <glbinding/ContextInfo.h>
|
||||||
|
#include <glbinding/Meta.h>
|
||||||
|
#include <glbinding/glbinding-version.h>
|
||||||
|
#include <glbinding/Version.h>
|
||||||
|
|
||||||
|
namespace Diggler {
|
||||||
|
namespace Render {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
void OpenGL::init() {
|
||||||
|
glbinding::Binding::initialize(false);
|
||||||
|
probeExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<OpenGL::Version> OpenGL::loaderSupportedGLVersions() {
|
||||||
|
std::set<Version> versions;
|
||||||
|
for (const auto& version : glbinding::Meta::versions()) {
|
||||||
|
versions.emplace(version.majorVersion(), version.minorVersion(), false, false, false);
|
||||||
|
if (version.majorVersion() >= 3) {
|
||||||
|
versions.emplace(version.majorVersion(), version.minorVersion(), false, false, true);
|
||||||
|
versions.emplace(version.majorVersion(), version.minorVersion(), false, true, false);
|
||||||
|
versions.emplace(version.majorVersion(), version.minorVersion(), false, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGL::Version OpenGL::version() {
|
||||||
|
auto ver = glbinding::ContextInfo::version();
|
||||||
|
const int major = ver.majorVersion(), minor = ver.minorVersion();
|
||||||
|
GLuint contextFlags = 0;
|
||||||
|
if (major >= 3) {
|
||||||
|
glGetIntegerv(GL_CONTEXT_FLAGS, reinterpret_cast<GLint*>(&contextFlags));
|
||||||
|
}
|
||||||
|
GLuint profileFlags = 0;
|
||||||
|
if (major >= 3 and (major >= 4 or minor >= 2)) {
|
||||||
|
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, reinterpret_cast<GLint*>(&profileFlags));
|
||||||
|
}
|
||||||
|
return { major, minor, false,
|
||||||
|
bool(profileFlags & GLuint(GL_CONTEXT_CORE_PROFILE_BIT)),
|
||||||
|
bool(contextFlags & GLuint(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderName() {
|
||||||
|
return "glbinding";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderVersion() {
|
||||||
|
return GLBINDING_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace Diggler {
|
||||||
|
namespace Render {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
void OpenGL::init() {
|
||||||
|
GLenum err = glewInit();
|
||||||
|
if (err != GLEW_OK) {
|
||||||
|
throw std::runtime_error(std::string("GLEW initialization failed") +
|
||||||
|
reinterpret_cast<const char*>(glewGetErrorString(err)));
|
||||||
|
}
|
||||||
|
probeExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<OpenGL::Version> OpenGL::loaderSupportedGLVersions() {
|
||||||
|
std::set<Version> versions;
|
||||||
|
for (int ver : { 20, 21, 30, 31, 32, 33, 40, 41, 42, 43, 44, 45 }) {
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, false, false);
|
||||||
|
if (ver >= 30) {
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, false, true);
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, true, false);
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGL::Version OpenGL::version() {
|
||||||
|
auto ver = glGetString(GL_VERSION);
|
||||||
|
const int major = ver[0] - '0', minor = ver[2] - '0';
|
||||||
|
GLuint contextFlags = 0;
|
||||||
|
if (major >= 3) {
|
||||||
|
glGetIntegerv(GL_CONTEXT_FLAGS, reinterpret_cast<GLint*>(&contextFlags));
|
||||||
|
}
|
||||||
|
GLuint profileFlags = 0;
|
||||||
|
if (major >= 3 and (major >= 4 or minor >= 2)) {
|
||||||
|
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, reinterpret_cast<GLint*>(&profileFlags));
|
||||||
|
}
|
||||||
|
return { major, minor, false,
|
||||||
|
bool(profileFlags & GLuint(GL_CONTEXT_CORE_PROFILE_BIT)),
|
||||||
|
bool(contextFlags & GLuint(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderName() {
|
||||||
|
return "GLEW";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderVersion() {
|
||||||
|
return reinterpret_cast<const char*>(glewGetString(GLEW_VERSION));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
#ifndef DIGGLER_RENDER_GL_OPENGL_HPP
|
||||||
|
#define DIGGLER_RENDER_GL_OPENGL_HPP
|
||||||
|
|
||||||
|
#include "../../platform/Fixes.hpp"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#if defined(DIGGLER_GL_USE_LIBEPOXY)
|
||||||
|
#include <epoxy/gl.h>
|
||||||
|
#elif defined(DIGGLER_GL_USE_GLAD)
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#elif defined(DIGGLER_GL_USE_GLBINDING)
|
||||||
|
#include <glbinding/gl/gl.h>
|
||||||
|
using namespace gl;
|
||||||
|
#elif defined(DIGGLER_GL_USE_GLEW)
|
||||||
|
#define GLEW_NO_GLU
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#else
|
||||||
|
#error "No OpenGL loader selected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Diggler {
|
||||||
|
namespace Render {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
class OpenGL {
|
||||||
|
private:
|
||||||
|
static void probeExtensions();
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct Version {
|
||||||
|
int major, minor;
|
||||||
|
bool isGLES, isCore, isForward;
|
||||||
|
|
||||||
|
Version(int major, int minor, bool isGLES, bool isCore, bool isForward) :
|
||||||
|
major(major),
|
||||||
|
minor(minor),
|
||||||
|
isGLES(isGLES),
|
||||||
|
isCore(isCore),
|
||||||
|
isForward(isForward) {}
|
||||||
|
|
||||||
|
operator int() const { return major * 10 + minor; }
|
||||||
|
bool operator<(const Version &v) const {
|
||||||
|
return major < v.major && minor < v.minor &&
|
||||||
|
(isGLES ^ v.isGLES) && (isCore ^ v.isCore) && (isForward ^ v.isForward);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The OpenGL Loader name
|
||||||
|
*/
|
||||||
|
static const char* loaderName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The OpenGL Loader version
|
||||||
|
*/
|
||||||
|
static const char* loaderVersion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of OpenGL versions whose initialization is supported by the Loader.
|
||||||
|
* An empty set means supported versions are unknown.
|
||||||
|
* @note Presence of a given version in this liss only shows Loader support, not driver support
|
||||||
|
* @return The OpenGL versions the Loader supports
|
||||||
|
*/
|
||||||
|
static std::set<Version> loaderSupportedGLVersions();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes OpenGL entrypoints
|
||||||
|
*/
|
||||||
|
static void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The currently loaded OpenGL version
|
||||||
|
*/
|
||||||
|
static Version version();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The currently available OpenGL extensions
|
||||||
|
*/
|
||||||
|
static const std::set<std::string>& extensions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for availability of an OpenGL extension
|
||||||
|
* @return `true` if the extension is available, `false` otherwise
|
||||||
|
*/
|
||||||
|
static bool hasExtension(const std::string&);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DIGGLER_RENDER_GL_OPENGL_HPP */
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace Diggler {
|
||||||
|
namespace Render {
|
||||||
|
namespace gl {
|
||||||
|
|
||||||
|
void OpenGL::init() {
|
||||||
|
// libepoxy initializes lazily
|
||||||
|
probeExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<OpenGL::Version> OpenGL::loaderSupportedGLVersions() {
|
||||||
|
std::set<Version> versions;
|
||||||
|
for (int ver : { 20, 21, 30, 31, 32, 33, 40, 41, 42, 43, 44, 45 }) {
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, false, false);
|
||||||
|
if (ver >= 30) {
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, false, true);
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, true, false);
|
||||||
|
versions.emplace(ver / 10, ver % 10, false, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int ver : { 20, 30, 31, 32 }) {
|
||||||
|
versions.emplace(ver / 10, ver % 10, true, false, false);
|
||||||
|
}
|
||||||
|
return versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGL::Version OpenGL::version() {
|
||||||
|
auto ver = epoxy_gl_version();
|
||||||
|
const int major = ver / 10, minor = ver % 10;
|
||||||
|
GLuint contextFlags = 0;
|
||||||
|
if (major >= 3) {
|
||||||
|
glGetIntegerv(GL_CONTEXT_FLAGS, reinterpret_cast<GLint*>(&contextFlags));
|
||||||
|
}
|
||||||
|
GLuint profileFlags = 0;
|
||||||
|
if (major >= 3 and (major >= 4 or minor >= 2)) {
|
||||||
|
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, reinterpret_cast<GLint*>(&profileFlags));
|
||||||
|
}
|
||||||
|
return { major, minor, !epoxy_is_desktop_gl(),
|
||||||
|
bool(profileFlags & GL_CONTEXT_CORE_PROFILE_BIT),
|
||||||
|
bool(contextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderName() {
|
||||||
|
return "libepoxy";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* OpenGL::loaderVersion() {
|
||||||
|
return "rolling";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,11 @@ namespace Diggler {
|
||||||
namespace Render {
|
namespace Render {
|
||||||
namespace gl {
|
namespace gl {
|
||||||
|
|
||||||
Program::Program(Shader* vsh, Shader* fsh) : vsh(vsh), fsh(fsh), id(0) {
|
Program::Program(Shader* vsh, Shader* fsh) :
|
||||||
|
vsh(vsh),
|
||||||
|
fsh(fsh),
|
||||||
|
id(0),
|
||||||
|
linked(GL_FALSE) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +38,9 @@ bool Program::link() {
|
||||||
glAttachShader(id, vsh->getId());
|
glAttachShader(id, vsh->getId());
|
||||||
glAttachShader(id, fsh->getId());
|
glAttachShader(id, fsh->getId());
|
||||||
glLinkProgram(id);
|
glLinkProgram(id);
|
||||||
glGetProgramiv(id, GL_LINK_STATUS, &linked);
|
GLint linkStatus;
|
||||||
|
glGetProgramiv(id, GL_LINK_STATUS, &linkStatus);
|
||||||
|
linked = GLboolean(linkStatus);
|
||||||
if (!linked) {
|
if (!linked) {
|
||||||
getErrorStream() << id << ':' << getError() << std::endl;
|
getErrorStream() << id << ':' << getError() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -11,7 +11,7 @@ class Program {
|
||||||
private:
|
private:
|
||||||
Shader *vsh, *fsh;
|
Shader *vsh, *fsh;
|
||||||
GLuint id;
|
GLuint id;
|
||||||
GLint linked = GL_FALSE;
|
GLboolean linked;
|
||||||
bool mustDestroy = false;
|
bool mustDestroy = false;
|
||||||
std::string fshPath, vshPath;
|
std::string fshPath, vshPath;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Using GLAD in Diggler
|
||||||
|
|
||||||
|
GLAD is a small, generated OpenGL loader targeting a single GL version with an optional set of supported extensions.
|
||||||
|
|
||||||
|
It is hosted on GitHub at https://github.com/Dav1dde/glad . It can be either installed, or [used from a web service](http://glad.dav1d.de/).
|
||||||
|
|
||||||
|
## Diggler requirements
|
||||||
|
|
||||||
|
Diggler mandates a minimum support of OpenGL (ES) 2.0.
|
||||||
|
|
||||||
|
On desktop OpenGL, loader support of these extensions is required:
|
||||||
|
|
||||||
|
* GL_ARB_buffer_storage
|
||||||
|
* GL_ARB_direct_state_access
|
||||||
|
* GL_ARB_framebuffer_object
|
||||||
|
* GL_ARB_shader_image_load_store
|
||||||
|
* GL_ARB_vertex_array_object
|
||||||
|
* GL_EXT_direct_state_access
|
||||||
|
* GL_KHR_debug
|
||||||
|
|
||||||
|
```
|
||||||
|
--profile="compatibility" --api="gl=2.0" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_direct_state_access,GL_ARB_framebuffer_object,GL_ARB_shader_image_load_store,GL_ARB_vertex_array_object,GL_EXT_direct_state_access,GL_KHR_debug"
|
||||||
|
```
|
||||||
|
|
||||||
|
As said, you can [generate the loader online](http://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D2.0&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_direct_state_access&extensions=GL_ARB_framebuffer_object&extensions=GL_ARB_shader_image_load_store&extensions=GL_ARB_vertex_array_object&extensions=GL_EXT_direct_state_access&extensions=GL_KHR_debug).
|
|
@ -51,8 +51,9 @@ bool Shader::compileFromString(const std::string &source, const std::string &pat
|
||||||
const char *src = srcStr.c_str();
|
const char *src = srcStr.c_str();
|
||||||
glShaderSource(id, 1, &src, nullptr);
|
glShaderSource(id, 1, &src, nullptr);
|
||||||
glCompileShader(id);
|
glCompileShader(id);
|
||||||
|
GLint compiled;
|
||||||
glGetShaderiv(id, GL_COMPILE_STATUS, &compiled);
|
glGetShaderiv(id, GL_COMPILE_STATUS, &compiled);
|
||||||
if (!compiled) {
|
if (!GLboolean(compiled)) {
|
||||||
getErrorStream() << "Compile error in " << path << "\n" << getError() << std::endl;
|
getErrorStream() << "Compile error in " << path << "\n" << getError() << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
namespace Diggler {
|
namespace Diggler {
|
||||||
namespace Render {
|
namespace Render {
|
||||||
|
@ -13,13 +13,12 @@ namespace gl {
|
||||||
class Shader {
|
class Shader {
|
||||||
private:
|
private:
|
||||||
GLuint id;
|
GLuint id;
|
||||||
GLint compiled = GL_FALSE;
|
|
||||||
const std::vector<std::string> *m_preludeLines;
|
const std::vector<std::string> *m_preludeLines;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Type : GLenum {
|
enum class Type : unsigned int {
|
||||||
FRAGMENT = GL_FRAGMENT_SHADER,
|
FRAGMENT = static_cast<unsigned int>(GL_FRAGMENT_SHADER),
|
||||||
VERTEX = GL_VERTEX_SHADER
|
VERTEX = static_cast<unsigned int>(GL_VERTEX_SHADER)
|
||||||
} type;
|
} type;
|
||||||
Shader(Type type);
|
Shader(Type type);
|
||||||
Shader(Type type, const std::string& path);
|
Shader(Type type, const std::string& path);
|
||||||
|
|
|
@ -22,8 +22,10 @@ const char* getErrorString(GLenum code) {
|
||||||
return "GL_OUT_OF_MEMORY";
|
return "GL_OUT_OF_MEMORY";
|
||||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||||
return "GL_INVALID_FRAMEBUFFER_OPERATION";
|
return "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||||
|
#ifdef GL_TABLE_TOO_LARGE
|
||||||
case GL_TABLE_TOO_LARGE:
|
case GL_TABLE_TOO_LARGE:
|
||||||
return "GL_TABLE_TOO_LARGE";
|
return "GL_TABLE_TOO_LARGE";
|
||||||
|
#endif
|
||||||
case GL_FRAMEBUFFER_COMPLETE:
|
case GL_FRAMEBUFFER_COMPLETE:
|
||||||
return "GL_FRAMEBUFFER_COMPLETE";
|
return "GL_FRAMEBUFFER_COMPLETE";
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||||
|
@ -36,6 +38,8 @@ const char* getErrorString(GLenum code) {
|
||||||
return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
|
return "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||||
return "GL_FRAMEBUFFER_UNSUPPORTED";
|
return "GL_FRAMEBUFFER_UNSUPPORTED";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "../../Platform.hpp"
|
#include "../../Platform.hpp"
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
namespace Diggler {
|
namespace Diggler {
|
||||||
namespace Render {
|
namespace Render {
|
||||||
|
@ -43,8 +43,10 @@ constexpr GLenum getBinding(GLenum bufferT) {
|
||||||
return GL_RENDERBUFFER_BINDING;
|
return GL_RENDERBUFFER_BINDING;
|
||||||
case GL_VERTEX_ARRAY:
|
case GL_VERTEX_ARRAY:
|
||||||
return GL_VERTEX_ARRAY_BINDING;
|
return GL_VERTEX_ARRAY_BINDING;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return GL_INVALID_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<GLenum BufferT, GLenum BoundBufferT = getBinding(BufferT)>
|
template<GLenum BufferT, GLenum BoundBufferT = getBinding(BufferT)>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
#include "FeatureSupport.hpp"
|
#include "FeatureSupport.hpp"
|
||||||
#include "Util.hpp"
|
#include "Util.hpp"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include "OpenGL.hpp"
|
||||||
|
|
||||||
#include "../../platform/PreprocUtils.hpp"
|
#include "../../platform/PreprocUtils.hpp"
|
||||||
#include "FeatureSupport.hpp"
|
#include "FeatureSupport.hpp"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "../Platform.hpp"
|
#include "../Platform.hpp"
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include "../render/gl/OpenGL.hpp"
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "../render/FontRendererFwd.hpp"
|
#include "../render/FontRendererFwd.hpp"
|
||||||
|
|
Loading…
Reference in New Issue