diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 27d5668abb..130a65a655 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -2361,6 +2361,9 @@ def WriteConfigSettings(): if int(platform.mac_ver()[0][3]) <= 4: dtool_config["PHAVE_UCONTEXT_H"] = 'UNDEF' + if PkgSkip("X11"): + dtool_config["HAVE_GLX"] = 'UNDEF' + if (GetTarget() == "freebsd"): dtool_config["IS_LINUX"] = 'UNDEF' dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF' @@ -4494,6 +4497,25 @@ if (GetTarget() == 'windows' and PkgSkip("GL")==0): # DIRECTORY: panda/src/egldisplay/ # +# If we're not compiling with any windowing system at all, but we do have EGL, +# we can use that to create a headless libpandagl instead. +if not PkgSkip("EGL") and not PkgSkip("GL") and PkgSkip("X11") and GetTarget() not in ('windows', 'darwin'): + DefSymbol('EGL', 'HAVE_EGL', '') + OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGL', 'GL', 'EGL'] + TargetAdd('pandagl_egldisplay_composite1.obj', opts=OPTS, input='p3egldisplay_composite1.cxx') + OPTS=['DIR:panda/metalibs/pandagl', 'BUILDING:PANDAGL', 'GL', 'EGL'] + TargetAdd('pandagl_pandagl.obj', opts=OPTS, input='pandagl.cxx') + TargetAdd('libpandagl.dll', input='pandagl_pandagl.obj') + TargetAdd('libpandagl.dll', input='p3glgsg_config_glgsg.obj') + TargetAdd('libpandagl.dll', input='p3glgsg_glgsg.obj') + TargetAdd('libpandagl.dll', input='pandagl_egldisplay_composite1.obj') + TargetAdd('libpandagl.dll', input=COMMON_PANDA_LIBS) + TargetAdd('libpandagl.dll', opts=['MODULE', 'GL', 'EGL', 'CGGL']) + +# +# DIRECTORY: panda/src/egldisplay/ +# + if (PkgSkip("EGL")==0 and PkgSkip("GLES")==0): DefSymbol('GLES', 'OPENGLES_1', '') OPTS=['DIR:panda/src/egldisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAGLES', 'GLES', 'EGL'] diff --git a/panda/metalibs/pandagl/pandagl.cxx b/panda/metalibs/pandagl/pandagl.cxx index 7775d2e7b4..2f6c720712 100644 --- a/panda/metalibs/pandagl/pandagl.cxx +++ b/panda/metalibs/pandagl/pandagl.cxx @@ -23,8 +23,13 @@ #include "glxGraphicsPipe.h" #endif -#if !defined(HAVE_WGL) && !defined(HAVE_COCOA) && !defined(HAVE_GLX) -#error One of HAVE_WGL, HAVE_COCOA or HAVE_GLX must be defined when compiling pandagl! +#if defined(HAVE_EGL) && !defined(HAVE_X11) +#include "config_egldisplay.h" +#include "eglGraphicsPipe.h" +#endif + +#if !defined(HAVE_WGL) && !defined(HAVE_COCOA) && !defined(HAVE_GLX) && !defined(HAVE_EGL) +#error One of HAVE_WGL, HAVE_COCOA, HAVE_GLX or HAVE_EGL must be defined when compiling pandagl! #endif /** @@ -45,9 +50,13 @@ init_libpandagl() { init_libcocoadisplay(); #endif -#ifdef IS_LINUX +#ifdef HAVE_GLX init_libglxdisplay(); #endif + +#if defined(HAVE_EGL) && !defined(HAVE_X11) + init_libegldisplay(); +#endif } /** @@ -68,5 +77,9 @@ get_pipe_type_pandagl() { return glxGraphicsPipe::get_class_type().get_index(); #endif +#if defined(HAVE_EGL) && !defined(HAVE_X11) + return eglGraphicsPipe::get_class_type().get_index(); +#endif + return 0; } diff --git a/panda/src/egldisplay/config_egldisplay.cxx b/panda/src/egldisplay/config_egldisplay.cxx index 3f2dbb6c03..a72112c8c6 100644 --- a/panda/src/egldisplay/config_egldisplay.cxx +++ b/panda/src/egldisplay/config_egldisplay.cxx @@ -19,8 +19,8 @@ #include "dconfig.h" #include "pandaSystem.h" -#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDAGLES) && !defined(BUILDING_PANDAGLES2) - #error Buildsystem error: BUILDING_PANDAGLES(2) not defined +#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_PANDAGLES) && !defined(BUILDING_PANDAGLES2) && !defined(BUILDING_PANDAGL) + #error Buildsystem error: BUILDING_PANDAGL(ES(2)) not defined #endif Configure(config_egldisplay); @@ -57,8 +57,10 @@ init_libegldisplay() { PandaSystem *ps = PandaSystem::get_global_ptr(); #ifdef OPENGLES_2 ps->set_system_tag("OpenGL ES 2", "window_system", "EGL"); -#else +#elif defined(OPENGLES_1) ps->set_system_tag("OpenGL ES", "window_system", "EGL"); +#else + ps->set_system_tag("OpenGL", "window_system", "EGL"); #endif } diff --git a/panda/src/egldisplay/config_egldisplay.h b/panda/src/egldisplay/config_egldisplay.h index 40e30893b8..a85df9748e 100644 --- a/panda/src/egldisplay/config_egldisplay.h +++ b/panda/src/egldisplay/config_egldisplay.h @@ -23,20 +23,22 @@ #if defined(OPENGLES_1) && defined(OPENGLES_2) #error OPENGLES_1 and OPENGLES_2 cannot be defined at the same time! #endif -#if !defined(OPENGLES_1) && !defined(OPENGLES_2) - #error Either OPENGLES_1 or OPENGLES_2 must be defined when compiling egldisplay! -#endif #ifdef OPENGLES_2 NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES2, EXPTP_PANDAGLES2); extern EXPCL_PANDAGLES2 void init_libegldisplay(); extern EXPCL_PANDAGLES2 const std::string get_egl_error_string(int error); -#else +#elif defined(OPENGLES_1) NotifyCategoryDecl(egldisplay, EXPCL_PANDAGLES, EXPTP_PANDAGLES); extern EXPCL_PANDAGLES void init_libegldisplay(); extern EXPCL_PANDAGLES const std::string get_egl_error_string(int error); +#else + NotifyCategoryDecl(egldisplay, EXPCL_PANDAGL, EXPTP_PANDAGL); + + extern EXPCL_PANDAGL void init_libegldisplay(); + extern EXPCL_PANDAGL const std::string get_egl_error_string(int error); #endif #endif diff --git a/panda/src/egldisplay/eglGraphicsPipe.cxx b/panda/src/egldisplay/eglGraphicsPipe.cxx index 118ad02b5d..18c2317664 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.cxx +++ b/panda/src/egldisplay/eglGraphicsPipe.cxx @@ -41,10 +41,17 @@ eglGraphicsPipe() { return; } +#if defined(OPENGLES_1) || defined(OPENGLES_2) if (!eglBindAPI(EGL_OPENGL_ES_API)) { egldisplay_cat.error() << "Couldn't bind EGL to the OpenGL ES API: " << get_egl_error_string(eglGetError()) << "\n"; +#else + if (!eglBindAPI(EGL_OPENGL_API)) { + egldisplay_cat.error() + << "Couldn't bind EGL to the OpenGL API: " + << get_egl_error_string(eglGetError()) << "\n"; +#endif _is_valid = false; return; } @@ -74,7 +81,11 @@ eglGraphicsPipe:: */ std::string eglGraphicsPipe:: get_interface_name() const { +#if defined(OPENGLES_1) || defined(OPENGLES_2) return "OpenGL ES"; +#else + return "OpenGL"; +#endif } /** @@ -143,7 +154,7 @@ make_output(const std::string &name, #endif } - // Second thing to try: a GLES(2)GraphicsBuffer + // Second thing to try: a GL(ES(2))GraphicsBuffer if (retry == 1) { if ((host==0)|| // (!gl_support_fbo)|| @@ -174,9 +185,12 @@ make_output(const std::string &name, #ifdef OPENGLES_2 return new GLES2GraphicsBuffer(engine, this, name, fb_prop, win_prop, flags, gsg, host); -#else +#elif defined(OPENGLES_1) return new GLESGraphicsBuffer(engine, this, name, fb_prop, win_prop, flags, gsg, host); +#else + return new GLGraphicsBuffer(engine, this, name, fb_prop, win_prop, + flags, gsg, host); #endif } diff --git a/panda/src/egldisplay/eglGraphicsPipe.h b/panda/src/egldisplay/eglGraphicsPipe.h index f5ad026138..def344a61c 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.h +++ b/panda/src/egldisplay/eglGraphicsPipe.h @@ -32,11 +32,16 @@ typedef GraphicsPipe BaseGraphicsPipe; #define NativeDisplayType EGLNativeDisplayType #define NativePixmapType EGLNativePixmapType #define NativeWindowType EGLNativeWindowType -#else +#elif defined(OPENGLES_1) #include "glesgsg.h" #include "pre_x11_include.h" #include #include "post_x11_include.h" +#else + #include "glgsg.h" + #include "pre_x11_include.h" + #include + #include "post_x11_include.h" #endif class FrameBufferProperties; diff --git a/panda/src/egldisplay/eglGraphicsStateGuardian.cxx b/panda/src/egldisplay/eglGraphicsStateGuardian.cxx index d90cb410e3..c6fb88989b 100644 --- a/panda/src/egldisplay/eglGraphicsStateGuardian.cxx +++ b/panda/src/egldisplay/eglGraphicsStateGuardian.cxx @@ -25,11 +25,7 @@ TypeHandle eglGraphicsStateGuardian::_type_handle; eglGraphicsStateGuardian:: eglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe, eglGraphicsStateGuardian *share_with) : -#ifdef OPENGLES_2 - GLES2GraphicsStateGuardian(engine, pipe) -#else - GLESGraphicsStateGuardian(engine, pipe) -#endif + BaseGraphicsStateGuardian(engine, pipe) { _share_context=0; _context=0; @@ -128,11 +124,12 @@ choose_pixel_format(const FrameBufferProperties &properties, _fbprops.clear(); int attrib_list[] = { -#ifdef OPENGLES_1 +#if defined(OPENGLES_1) EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, -#endif -#ifdef OPENGLES_2 +#elif defined(OPENGLES_2) EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, +#else + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, #endif EGL_SURFACE_TYPE, need_window ? EGL_WINDOW_BIT : EGL_DONT_CARE, EGL_NONE @@ -204,12 +201,36 @@ choose_pixel_format(const FrameBufferProperties &properties, egldisplay_cat.debug() << "Chosen config " << best_result << ": " << best_props << "\n"; _fbconfig = configs[best_result]; + + EGLint attribs[32]; + int n = 0; + #ifdef OPENGLES_2 - EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - _context = eglCreateContext(_egl_display, _fbconfig, _share_context, context_attribs); -#else - _context = eglCreateContext(_egl_display, _fbconfig, _share_context, nullptr); + attribs[n++] = EGL_CONTEXT_CLIENT_VERSION; + attribs[n++] = 2; +#elif defined(OPENGLES_1) +#else // Regular OpenGL + if (gl_version.get_num_words() > 0) { + attribs[n++] = EGL_CONTEXT_MAJOR_VERSION; + attribs[n++] = gl_version[0]; + if (gl_version.get_num_words() > 1) { + attribs[n++] = EGL_CONTEXT_MINOR_VERSION; + attribs[n++] = gl_version[1]; + } + } + if (gl_debug) { + attribs[n++] = EGL_CONTEXT_OPENGL_DEBUG; + attribs[n++] = EGL_TRUE; + } + if (gl_forward_compatible) { + attribs[n++] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE; + attribs[n++] = EGL_TRUE; + } #endif + attribs[n] = EGL_NONE; + + _context = eglCreateContext(_egl_display, _fbconfig, _share_context, (n > 0) ? attribs : nullptr); + int err = eglGetError(); if (_context && err == EGL_SUCCESS) { #ifdef HAVE_X11 @@ -243,11 +264,7 @@ choose_pixel_format(const FrameBufferProperties &properties, */ void eglGraphicsStateGuardian:: reset() { -#ifdef OPENGLES_2 - GLES2GraphicsStateGuardian::reset(); -#else - GLESGraphicsStateGuardian::reset(); -#endif + BaseGraphicsStateGuardian::reset(); if (_gl_renderer == "Software Rasterizer") { _fbprops.set_force_software(1); @@ -282,11 +299,7 @@ gl_flush() const { // This call requires synchronization with X. LightReMutexHolder holder(eglGraphicsPipe::_x_mutex); #endif -#ifdef OPENGLES_2 - GLES2GraphicsStateGuardian::gl_flush(); -#else - GLESGraphicsStateGuardian::gl_flush(); -#endif + BaseGraphicsStateGuardian::gl_flush(); } /** @@ -298,11 +311,7 @@ gl_get_error() const { // This call requires synchronization with X. LightReMutexHolder holder(eglGraphicsPipe::_x_mutex); #endif -#ifdef OPENGLES_2 - return GLES2GraphicsStateGuardian::gl_get_error(); -#else - return GLESGraphicsStateGuardian::gl_get_error(); -#endif + return BaseGraphicsStateGuardian::gl_get_error(); } /** @@ -310,11 +319,7 @@ gl_get_error() const { */ void eglGraphicsStateGuardian:: query_gl_version() { -#ifdef OPENGLES_2 - GLES2GraphicsStateGuardian::query_gl_version(); -#else - GLESGraphicsStateGuardian::query_gl_version(); -#endif + BaseGraphicsStateGuardian::query_gl_version(); // Calling eglInitialize on an already-initialized display will just provide // us the version numbers. @@ -329,9 +334,12 @@ query_gl_version() { #ifdef OPENGLES_2 if (gles2gsg_cat.is_debug()) { gles2gsg_cat.debug() -#else +#elif defined(OPENGLES_1) if (glesgsg_cat.is_debug()) { glesgsg_cat.debug() +#else + if (glgsg_cat.is_debug()) { + glgsg_cat.debug() #endif << "EGL_VERSION = " << _egl_version_major << "." << _egl_version_minor << "\n"; diff --git a/panda/src/egldisplay/eglGraphicsStateGuardian.h b/panda/src/egldisplay/eglGraphicsStateGuardian.h index ab865afb3f..608e9aa080 100644 --- a/panda/src/egldisplay/eglGraphicsStateGuardian.h +++ b/panda/src/egldisplay/eglGraphicsStateGuardian.h @@ -21,15 +21,19 @@ #include "get_x11.h" #endif +#ifdef OPENGLES_2 +typedef GLES2GraphicsStateGuardian BaseGraphicsStateGuardian; +#elif defined(OPENGLES_1) +typedef GLESGraphicsStateGuardian BaseGraphicsStateGuardian; +#else +typedef GLGraphicsStateGuardian BaseGraphicsStateGuardian; +#endif + /** * A tiny specialization on GLESGraphicsStateGuardian to add some egl-specific * information. */ -#ifdef OPENGLES_2 -class eglGraphicsStateGuardian : public GLES2GraphicsStateGuardian { -#else -class eglGraphicsStateGuardian : public GLESGraphicsStateGuardian { -#endif +class eglGraphicsStateGuardian : public BaseGraphicsStateGuardian { public: INLINE const FrameBufferProperties &get_fb_properties() const; void get_properties(FrameBufferProperties &properties, @@ -73,15 +77,9 @@ public: return _type_handle; } static void init_type() { -#ifdef OPENGLES_2 - GLES2GraphicsStateGuardian::init_type(); + BaseGraphicsStateGuardian::init_type(); register_type(_type_handle, "eglGraphicsStateGuardian", - GLES2GraphicsStateGuardian::get_class_type()); -#else - GLESGraphicsStateGuardian::init_type(); - register_type(_type_handle, "eglGraphicsStateGuardian", - GLESGraphicsStateGuardian::get_class_type()); -#endif + BaseGraphicsStateGuardian::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type();