diff --git a/neo/SConstruct b/neo/SConstruct index 1f2d50ed..9d8cf67d 100644 --- a/neo/SConstruct +++ b/neo/SConstruct @@ -15,7 +15,7 @@ conf_filename='site.conf' serialized=['CC', 'CXX', 'JOBS', 'BUILD', 'IDNET_HOST', 'DEDICATED', 'DEBUG_MEMORY', 'LIBC_MALLOC', 'ID_NOLANADDRESS', 'ID_MCHECK', 'ALSA', 'TARGET_CORE', 'TARGET_GAME', 'TARGET_D3XP', 'TARGET_MONO', 'TARGET_DEMO', 'NOCURL', - 'BUILD_ROOT', 'BUILD_GAMEPAK', 'BASEFLAGS', 'SILENT', 'TARGET_OPENGL', + 'BUILD_ROOT', 'BUILD_GAMEPAK', 'BASEFLAGS', 'SILENT', 'TARGET_OPENGL', 'TARGET_OPENGL_EGL', 'TARGET_ANDROID', 'NDK' ] # global build mode ------------------------------ @@ -95,7 +95,13 @@ TARGET_DEMO (default 0) TARGET_OPENGL (default 0) Build an OpenGL renderer instead of OpenGL ES2.0. GLSL shaders are compatible. + NOTE: This default Contexts to Enable OpenGL. For Linux, This is GLX. +TARGET_OPENGL_EGL (default 0) + Build an OpenGL renderer instead of OpenGL ES2.0. + GLSL shaders are compatible. + NOTE: This use EGL contexts to activate OpenGL. + TARGET_ANDROID (default 0) Build the Android version. @@ -176,6 +182,7 @@ TARGET_D3XP = '1' TARGET_MONO = '0' TARGET_DEMO = '0' TARGET_OPENGL = '0' +TARGET_OPENGL_EGL = '0' TARGET_ANDROID = '0' NDK = '' IDNET_HOST = '' @@ -395,8 +402,9 @@ local_idlibpic = 0 local_d3xp = 0 # OpenGL local_opengl = 0 +local_opengl_egl = 0 -GLOBALS = 'g_env g_env_noopt g_game_env g_os ID_MCHECK ALSA idlib_objects game_objects local_dedicated local_gamedll local_demo local_idlibpic local_curl local_d3xp local_opengl OPTCPPFLAGS NDK' +GLOBALS = 'g_env g_env_noopt g_game_env g_os ID_MCHECK ALSA idlib_objects game_objects local_dedicated local_gamedll local_demo local_idlibpic local_curl local_d3xp local_opengl local_opengl_egl OPTCPPFLAGS NDK' # end general configuration ---------------------- @@ -415,6 +423,10 @@ if ( TARGET_OPENGL != '0' ): local_opengl = 1 Export( 'GLOBALS ' + GLOBALS ) +if ( TARGET_OPENGL_EGL != '0' ): + local_opengl_egl = local_opengl = 1 + Export( 'GLOBALS ' + GLOBALS ) + if ( TARGET_ANDROID != '0' ): Export( 'GLOBALS ' + GLOBALS ) diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 4d8cb6cd..6c373213 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -67,6 +67,7 @@ idCVar r_znear("r_znear", "3", CVAR_RENDERER | CVAR_FLOAT, "near Z clip plane di idCVar r_ignoreGLErrors("r_ignoreGLErrors", "1", CVAR_RENDERER | CVAR_BOOL, "ignore GL errors"); idCVar r_finish("r_finish", "0", CVAR_RENDERER | CVAR_BOOL, "force a call to glFinish() every frame"); +idCVar r_swapInterval( "r_swapInterval", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "changes Vertical Sync Setting" ); idCVar r_gamma("r_gamma", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 3.0f); idCVar r_brightness("r_brightness", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_FLOAT, "changes gamma tables", 0.5f, 2.0f); diff --git a/neo/renderer/qgl.h b/neo/renderer/qgl.h index 78327b01..55639e81 100644 --- a/neo/renderer/qgl.h +++ b/neo/renderer/qgl.h @@ -38,7 +38,12 @@ If you have questions concerning this license or the applicable additional terms #ifdef ID_TARGET_OPENGL #include #include +#ifdef ID_TARGET_OPENGL_GLX #include +#else +#include +#include +#endif #define GL_APIENTRY GLAPIENTRY #else #include diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index e364623a..f80223eb 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -832,6 +832,7 @@ extern idCVar r_znear; // near Z clip plane extern idCVar r_finish; // force a call to glFinish() every frame extern idCVar r_frontBuffer; // draw to front buffer for debugging +extern idCVar r_swapInterval; // changes Vertical Sync Swap Interval. extern idCVar r_offsetFactor; // polygon offset parameter extern idCVar r_offsetUnits; // polygon offset parameter extern idCVar r_singleTriangle; // only draw a single triangle per primitive diff --git a/neo/sys/linux/gl_extensions.cpp b/neo/sys/linux/gl_extensions.cpp index 2584dbb6..ea350079 100644 --- a/neo/sys/linux/gl_extensions.cpp +++ b/neo/sys/linux/gl_extensions.cpp @@ -66,7 +66,7 @@ GLExtension_t GLimp_ExtensionPointer(const char *name) #endif GLExtension_t ret; -#ifdef ID_TARGET_OPENGL +#ifdef ID_TARGET_OPENGL_GLX ret = glXGetProcAddressARB(name); #else ret = eglGetProcAddress(name); diff --git a/neo/sys/linux/gles2.cpp b/neo/sys/linux/gles2.cpp index f8087d0a..bf15412d 100644 --- a/neo/sys/linux/gles2.cpp +++ b/neo/sys/linux/gles2.cpp @@ -91,6 +91,12 @@ bool GLimp_SpawnRenderThread(void (*a)()) void GLimp_ActivateContext() { +#if ID_TARGET_OPENGL + assert(eglDisplay); + assert(eglSurface); + assert(eglContext); + eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); +#endif #if 0 assert(dpy); assert(ctx); @@ -100,6 +106,10 @@ void GLimp_ActivateContext() void GLimp_DeactivateContext() { +#if ID_TARGET_OPENGL + assert(eglDisplay); + eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); +#endif #if 0 assert(dpy); glXMakeCurrent(dpy, None, NULL); @@ -242,6 +252,15 @@ void GLimp_Shutdown() void GLimp_SwapBuffers() { assert(eglDisplay && eglSurface); + +#ifdef ID_TARGET_OPENGL + if (r_swapInterval.IsModified()) { + // Allow disabling of Vertical Sync. + r_swapInterval.ClearModified(); + eglSwapInterval(eglDisplay, r_swapInterval.GetInteger()); + } +#endif + eglSwapBuffers(eglDisplay, eglSurface); } @@ -336,13 +355,13 @@ bool GLimp_OpenDisplay(void) /* =============== -GLX_Init +EGL_Init =============== */ EGLConfig eglConfig; EGLint eglNumConfig; -int GLX_Init(glimpParms_t a) +int EGL_Init(glimpParms_t a) { EGLint attrib[] = { EGL_RED_SIZE, 8, // 1, 2 @@ -352,7 +371,11 @@ int GLX_Init(glimpParms_t a) EGL_DEPTH_SIZE, 24, // 9, 10 EGL_STENCIL_SIZE, 8, // 11, 12 EGL_BUFFER_SIZE, 24, // 13, 14 +#ifdef ID_TARGET_OPENGL + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, // 15, 16 +#else EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // 15, 16 +#endif EGL_NONE, // 17 }; // these match in the array @@ -363,6 +386,7 @@ int GLX_Init(glimpParms_t a) #define ATTR_DEPTH_IDX 9 #define ATTR_STENCIL_IDX 11 #define ATTR_BUFFER_SIZE_IDX 13 +#define ATTR_RENDERABLE_TYPE 15 Window root; XVisualInfo *visinfo; XSetWindowAttributes attr; @@ -374,11 +398,25 @@ int GLX_Init(glimpParms_t a) int i; const char *glstring; + common->Printf("Initializing EGL\n"); if (!GLimp_OpenDisplay()) { return false; } - common->Printf("Initializing OpenGL display\n"); + glstring = (const char *) eglQueryString(eglDisplay,EGL_VENDOR); + common->Printf("EGL_VENDOR: %s\n", (glstring)?glstring:"NULL"); + + glstring = (const char *) eglQueryString(eglDisplay,EGL_VERSION); + common->Printf("EGL_VERSION: %s\n", (glstring)?glstring:"NULL"); + + glstring = (const char *) eglQueryString(eglDisplay,EGL_CLIENT_APIS); + common->Printf("EGL_CLIENT_APIS: %s\n", (glstring)?glstring:"NULL"); + + glstring = (const char *) eglQueryString(eglDisplay,EGL_EXTENSIONS); + common->Printf("EGL_EXTENSIONS: %s\n", (glstring)?glstring:"NULL"); + + glstring = (attrib[ATTR_RENDERABLE_TYPE]==EGL_OPENGL_ES2_BIT)?"OpenGL ES": "OpenGL"; + common->Printf("Initializing %s display\n",glstring); root = RootWindow(dpy, scrnum); @@ -448,10 +486,15 @@ int GLX_Init(glimpParms_t a) #endif // color, depth and stencil + colorbits = 24; depthbits = 24; stencilbits = 8; +#ifdef ID_TARGET_OPENGL + colorbits = 32; +#endif + for (i = 0; i < 16; i++) { // 0 - default // 1 - minus colorbits @@ -546,7 +589,7 @@ int GLX_Init(glimpParms_t a) } visinfo = malloc(sizeof(XVisualInfo)); - if (!(XMatchVisualInfo(dpy, scrnum, glConfig.depthBits, TrueColor, visinfo))) { + if (!(XMatchVisualInfo(dpy, scrnum, glConfig.depthBits, TrueColor, (XVisualInfo*)visinfo))) { common->Printf("Couldn't get a visual\n"); return false; } @@ -618,10 +661,23 @@ int GLX_Init(glimpParms_t a) } EGLint ctxattrib[] = { +#ifndef ID_TARGET_OPENGL EGL_CONTEXT_CLIENT_VERSION, 2, +#endif EGL_NONE }; + +#ifdef ID_TARGET_OPENGL + // Not all EGL Implementations will bind the current API to OpenGL + // automatically. Simply calling eglChooseConfig with EGL_RENDERABLE_TYPE + // set to EGL_OPENGL_BIT. + if(!eglBindAPI(EGL_OPENGL_API)) + { + common->Printf("Couldn't Bind OpenGL API\n"); + return false; + } +#endif eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, ctxattrib); if (eglContext == EGL_NO_CONTEXT) { common->Printf("Couldn't get a EGL context\n"); @@ -630,12 +686,38 @@ int GLX_Init(glimpParms_t a) eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); + EGLint Context_RendererType; + + eglQueryContext(eglDisplay, eglContext,EGL_CONTEXT_CLIENT_TYPE,&Context_RendererType); + + switch (Context_RendererType) + { + case EGL_OPENGL_API: + glstring = "OpenGL"; + break; + case EGL_OPENGL_ES_API: + glstring = "OpenGL ES"; + break; + case EGL_OPENVG_API: + common->Printf("Context Query Returned OpenVG. This is Unsupported\n"); + return false; + default: + common->Printf("Unknown Context Type. %04X\n",Context_RendererType); + return false; + } + common->Printf("EGL_CONTEXT_CLIENT_TYPE: %s\n", glstring); glstring = (const char *) glGetString(GL_RENDERER); common->Printf("GL_RENDERER: %s\n", glstring); glstring = (const char *) glGetString(GL_EXTENSIONS); common->Printf("GL_EXTENSIONS: %s\n", glstring); + +#ifdef ID_TARGET_OPENGL + // force Update of Vertical Sync setting on next frame + r_swapInterval.SetModified(); +#endif + // FIXME: here, software GL test glConfig.isFullscreen = a.fullScreen; @@ -669,7 +751,7 @@ bool GLimp_Init(glimpParms_t a) return false; } - if (!GLX_Init(a)) { + if (!EGL_Init(a)) { return false; } diff --git a/neo/sys/linux/glimp.cpp b/neo/sys/linux/glimp.cpp index 40886e14..c56685c4 100644 --- a/neo/sys/linux/glimp.cpp +++ b/neo/sys/linux/glimp.cpp @@ -335,10 +335,21 @@ int GLX_Init(glimpParms_t a) int i; const char *glstring; + common->Printf("Initializing GLX\n"); + if (!GLimp_OpenDisplay()) { return false; } + glstring = glXQueryExtensionsString( dpy, GLX_VENDOR); + common->Printf("GLX_VENDOR: %s\n", (glstring)?glstring:"NULL"); + + glstring = glXQueryExtensionsString( dpy, GLX_VERSION); + common->Printf("GLX_VERSION: %s\n", (glstring)?glstring:"NULL"); + + glstring = glXQueryExtensionsString( dpy, GLX_EXTENSIONS); + common->Printf("GLX_EXTENSIONS: %s\n", (glstring)?glstring:"NULL"); + common->Printf("Initializing OpenGL display\n"); root = RootWindow(dpy, scrnum); diff --git a/neo/sys/scons/SConscript.core b/neo/sys/scons/SConscript.core index 9af47c1f..8dffb296 100644 --- a/neo/sys/scons/SConscript.core +++ b/neo/sys/scons/SConscript.core @@ -264,7 +264,7 @@ if ( local_dedicated == 0 ): sys_string += ' android/input.cpp' else: sys_string += ' linux/input.cpp' - if ( local_opengl == 0 ): + if ( local_opengl == 0 or local_opengl_egl == 1): if g_os == 'Android': sys_string += ' android/gles2.cpp' else: @@ -311,7 +311,8 @@ else: if ( local_opengl == 1 ): local_env.Append( CPPDEFINES = [ 'ID_TARGET_OPENGL' ] ) - + if ( local_opengl_egl == 0 ): + local_env.Append( CPPDEFINES = [ 'ID_TARGET_OPENGL_GLX' ] ) sound_env = local_env.Clone() if g_os == 'Android': sound_list = [ '../android/sound.cpp' ] @@ -358,6 +359,10 @@ if ( local_dedicated == 0 ): local_env.Append( LIBS = [ 'GLESv2', 'EGL' ] ) else: local_env.Append( LIBS = [ 'GL' ] ) + if ( local_opengl_egl == 1 ): + local_env.Append( LIBS = [ 'EGL' ] ) + else: + local_env.Append( LIBS = [ 'Xxf86vm' ] ) source_list = core_list source_list += idlib_objects