diff --git a/Makefile b/Makefile index 3fa3c7d9..84d1c5e9 100644 --- a/Makefile +++ b/Makefile @@ -1115,6 +1115,7 @@ REFGL3_OBJS_ := \ src/client/refresh/gl3/gl3_surf.o \ src/client/refresh/gl3/gl3_warp.o \ src/client/refresh/gl3/gl3_shaders.o \ + src/client/refresh/files/glshaders.o \ src/client/refresh/files/mesh.o \ src/client/refresh/files/light.o \ src/client/refresh/files/surf.o \ @@ -1160,6 +1161,7 @@ REFGL4_OBJS_ := \ src/client/refresh/gl4/gl4_surf.o \ src/client/refresh/gl4/gl4_warp.o \ src/client/refresh/gl4/gl4_shaders.o \ + src/client/refresh/files/glshaders.o \ src/client/refresh/files/mesh.o \ src/client/refresh/files/light.o \ src/client/refresh/files/surf.o \ diff --git a/doc/040_cvarlist.md b/doc/040_cvarlist.md index 0b97846e..9c1ef273 100644 --- a/doc/040_cvarlist.md +++ b/doc/040_cvarlist.md @@ -473,6 +473,14 @@ Set `0` by default. Other supported values: `GL_NEAREST_MIPMAP_NEAREST`, `GL_NEAREST_MIPMAP_LINEAR`, `GL_LINEAR_MIPMAP_LINEAR` +* **gl_version_override**: Override required by render OpenGL version, + should be used only for debug purpose and useful if OpenGL implementation + does not report required version and implements required by render extensions. + - `0`: check required version of OpenGL, + - `1`: render will try to run with OpenGL 1.0, + - `2`: render will try to run with OpenGL 2.0, + - `3`: render will try to run with OpenGL 3.0, + - `4`: render will try to run with OpenGL 4.0. ## Graphics (OpenGL 1.4 only) diff --git a/src/client/refresh/files/glshaders.c b/src/client/refresh/files/glshaders.c new file mode 100644 index 00000000..d280cee6 --- /dev/null +++ b/src/client/refresh/files/glshaders.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 1997-2001 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ======================================================================= + * + * Shared code for generate GL shaders + * + * ======================================================================= + */ + +#include "../ref_shared.h" + +const char* +glshader_version(int major_version, int minor_version) +{ +#ifdef YQ2_GL3_GLES3 + if (major_version == 2) + { + return "#version 100\nprecision mediump float;\n"; + } + else if (major_version == 3) + { + switch(minor_version) + { + case 0: return "#version 300 es\nprecision mediump float;\n"; + case 1: return "#version 310 es\nprecision mediump float;\n"; + case 2: return "#version 320 es\nprecision mediump float;\n"; + default: return "#version 320 es\nprecision mediump float;\n"; + } + } +#else // Desktop GL + if (major_version == 2) + { + switch(minor_version) + { + case 0: return "#version 110\n"; + case 1: return "#version 120\n"; + default: return "#version 120\n"; + } + } + else if (major_version == 3) + { + switch(minor_version) + { + case 0: return "#version 130\n"; + case 1: return "#version 140\n"; + case 2: return "#version 150\n"; + case 3: return "#version 330\n"; + default: return "#version 330\n"; + } + } + else if (major_version == 4) + { + switch(minor_version) + { + case 0: return "#version 400\n"; + case 1: return "#version 410\n"; + case 2: return "#version 420\n"; + case 3: return "#version 430\n"; + case 4: return "#version 440\n"; + case 5: return "#version 450\n"; + case 6: return "#version 460\n"; + default: return "#version 460\n"; + } + } +#endif + + /* some unknown version */ + return "#version 100\nprecision mediump float;\n"; +} diff --git a/src/client/refresh/gl1/gl1_main.c b/src/client/refresh/gl1/gl1_main.c index a3e5295e..c1726a31 100644 --- a/src/client/refresh/gl1/gl1_main.c +++ b/src/client/refresh/gl1/gl1_main.c @@ -79,6 +79,7 @@ cvar_t *r_validation; cvar_t *r_lightlevel; cvar_t *gl1_overbrightbits; +cvar_t *gl_version_override; cvar_t *gl1_particle_min_size; cvar_t *gl1_particle_max_size; @@ -1196,6 +1197,7 @@ R_Register(void) gl1_particle_att_c = ri.Cvar_Get("gl1_particle_att_c", "0.01", CVAR_ARCHIVE); gl1_particle_square = ri.Cvar_Get("gl1_particle_square", "0", CVAR_ARCHIVE); + gl_version_override = ri.Cvar_Get("gl_version_override", "0", CVAR_ARCHIVE); r_modulate = ri.Cvar_Get("r_modulate", "1", CVAR_ARCHIVE); r_mode = ri.Cvar_Get("r_mode", "4", CVAR_ARCHIVE); gl_lightmap = ri.Cvar_Get("r_lightmap", "0", 0); diff --git a/src/client/refresh/gl1/gl1_sdl.c b/src/client/refresh/gl1/gl1_sdl.c index f4028c03..2be77010 100644 --- a/src/client/refresh/gl1/gl1_sdl.c +++ b/src/client/refresh/gl1/gl1_sdl.c @@ -233,10 +233,22 @@ int RI_InitContext(void* win) if (gl_config.major_version < 1 || (gl_config.major_version == 1 && gl_config.minor_version < 4)) { - R_Printf(PRINT_ALL, "%s(): Got an OpenGL version %d.%d context - need (at least) 1.4!\n", - __func__, gl_config.major_version, gl_config.minor_version); + if ((!gl_version_override->value) || + (gl_config.major_version < gl_version_override->value)) + { + R_Printf(PRINT_ALL, "%s(): Got an OpenGL version %d.%d context - need (at least) 1.4!\n", + __func__, gl_config.major_version, gl_config.minor_version); + + return false; + } + else + { + R_Printf(PRINT_ALL, "%s(): Warning: glad only got GL version %d.%d.\n" + "Some functionality could be broken.\n", + __func__, gl_config.major_version, gl_config.minor_version); + + } - return false; } // Check if we've got the requested MSAA. diff --git a/src/client/refresh/gl1/header/local.h b/src/client/refresh/gl1/header/local.h index e354814d..a3714454 100644 --- a/src/client/refresh/gl1/header/local.h +++ b/src/client/refresh/gl1/header/local.h @@ -184,6 +184,7 @@ extern cvar_t *r_lerp_list; extern cvar_t *r_2D_unfiltered; extern cvar_t *r_videos_unfiltered; +extern cvar_t *gl_version_override; extern cvar_t *gl_lightmap; extern cvar_t *gl_shadows; extern cvar_t *gl1_stencilshadow; diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index ebe1ce6e..8331ecd2 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -80,6 +80,7 @@ const hmm_mat4 gl3_identityMat4 = {{ }}; cvar_t *gl_msaa_samples; +cvar_t *gl_version_override; cvar_t *r_vsync; cvar_t *r_retexturing; cvar_t *r_maptype; @@ -209,6 +210,7 @@ GL3_Register(void) gl_drawbuffer = ri.Cvar_Get("gl_drawbuffer", "GL_BACK", 0); r_vsync = ri.Cvar_Get("r_vsync", "1", CVAR_ARCHIVE); gl_msaa_samples = ri.Cvar_Get ( "r_msaa_samples", "0", CVAR_ARCHIVE ); + gl_version_override = ri.Cvar_Get ( "gl_version_override", "0", CVAR_ARCHIVE ); r_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE); r_maptype = ri.Cvar_Get("maptype", "0", CVAR_ARCHIVE); r_scale8bittextures = ri.Cvar_Get("r_scale8bittextures", "0", CVAR_ARCHIVE); diff --git a/src/client/refresh/gl3/gl3_sdl.c b/src/client/refresh/gl3/gl3_sdl.c index 4052f1e9..2d0fb0bc 100644 --- a/src/client/refresh/gl3/gl3_sdl.c +++ b/src/client/refresh/gl3/gl3_sdl.c @@ -250,8 +250,16 @@ int GL3_PrepareForWindow(void) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); #else // Desktop GL - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + if (gl_version_override->value) + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl_version_override->value); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + } + else + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + } SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); #endif @@ -380,10 +388,21 @@ int GL3_InitContext(void* win) else if (GLVersion.major < 3 || (GLVersion.major == 3 && GLVersion.minor < 2)) #endif { - R_Printf(PRINT_ALL, "%s(): ERROR: glad only got GL version %d.%d!\n", - __func__, GLVersion.major, GLVersion.minor); + if ((!gl_version_override->value) || + (GLVersion.major < gl_version_override->value)) + { + R_Printf(PRINT_ALL, "%s(): ERROR: glad only got GL version %d.%d!\n", + __func__, GLVersion.major, GLVersion.minor); - return false; + return false; + } + else + { + R_Printf(PRINT_ALL, "%s(): Warning: glad only got GL version %d.%d.\n" + "Some functionality could be broken.\n", + __func__, GLVersion.major, GLVersion.minor); + + } } else { diff --git a/src/client/refresh/gl3/gl3_shaders.c b/src/client/refresh/gl3/gl3_shaders.c index d5741f23..6aad4502 100644 --- a/src/client/refresh/gl3/gl3_shaders.c +++ b/src/client/refresh/gl3/gl3_shaders.c @@ -35,12 +35,7 @@ static GLuint CompileShader(GLenum shaderType, const char* shaderSrc, const char* shaderSrc2) { GLuint shader = glCreateShader(shaderType); - -#ifdef YQ2_GL3_GLES3 - const char* version = "#version 300 es\nprecision mediump float;\n"; -#else // Desktop GL - const char* version = "#version 150\n"; -#endif + const char* version = glshader_version(gl3config.major_version, gl3config.minor_version); const char* sources[3] = { version, shaderSrc, shaderSrc2 }; int numSources = shaderSrc2 != NULL ? 3 : 2; diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index beaa345c..a2987177 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -506,6 +506,7 @@ extern void GL3_UpdateUBOLights(void); // ############ Cvars ########### extern cvar_t *gl_msaa_samples; +extern cvar_t *gl_version_override; extern cvar_t *r_vsync; extern cvar_t *r_retexturing; extern cvar_t *r_maptype; diff --git a/src/client/refresh/gl4/gl4_main.c b/src/client/refresh/gl4/gl4_main.c index 118f94ab..2ed0bf5d 100644 --- a/src/client/refresh/gl4/gl4_main.c +++ b/src/client/refresh/gl4/gl4_main.c @@ -76,6 +76,7 @@ const hmm_mat4 gl4_identityMat4 = {{ }}; cvar_t *gl_msaa_samples; +cvar_t *gl_version_override; cvar_t *r_vsync; cvar_t *r_retexturing; cvar_t *r_maptype; @@ -205,6 +206,7 @@ GL4_Register(void) gl_drawbuffer = ri.Cvar_Get("gl_drawbuffer", "GL_BACK", 0); r_vsync = ri.Cvar_Get("r_vsync", "1", CVAR_ARCHIVE); gl_msaa_samples = ri.Cvar_Get ( "r_msaa_samples", "0", CVAR_ARCHIVE ); + gl_version_override = ri.Cvar_Get ( "gl_version_override", "0", CVAR_ARCHIVE ); r_retexturing = ri.Cvar_Get("r_retexturing", "1", CVAR_ARCHIVE); r_maptype = ri.Cvar_Get("maptype", "0", CVAR_ARCHIVE); r_scale8bittextures = ri.Cvar_Get("r_scale8bittextures", "0", CVAR_ARCHIVE); diff --git a/src/client/refresh/gl4/gl4_sdl.c b/src/client/refresh/gl4/gl4_sdl.c index 39e6678b..b1ffd29c 100644 --- a/src/client/refresh/gl4/gl4_sdl.c +++ b/src/client/refresh/gl4/gl4_sdl.c @@ -232,8 +232,16 @@ int GL4_PrepareForWindow(void) gl4config.stencil = false; } - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); + if (gl_version_override->value) + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl_version_override->value); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + } + else + { + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); + } SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); // Set GL context flags. @@ -351,10 +359,21 @@ int GL4_InitContext(void* win) } else if (GLVersion.major < 4 || (GLVersion.major == 4 && GLVersion.minor < 6)) { - R_Printf(PRINT_ALL, "%s(): ERROR: glad only got GL version %d.%d!\n", - __func__, GLVersion.major, GLVersion.minor); + if ((!gl_version_override->value) || + (GLVersion.major < gl_version_override->value)) + { + R_Printf(PRINT_ALL, "%s(): ERROR: glad only got GL version %d.%d!\n", + __func__, GLVersion.major, GLVersion.minor); - return false; + return false; + } + else + { + R_Printf(PRINT_ALL, "%s(): Warning: glad only got GL version %d.%d.\n" + "Some functionality could be broken.\n", + __func__, GLVersion.major, GLVersion.minor); + + } } else { diff --git a/src/client/refresh/gl4/gl4_shaders.c b/src/client/refresh/gl4/gl4_shaders.c index 2ca0542b..3af2449f 100644 --- a/src/client/refresh/gl4/gl4_shaders.c +++ b/src/client/refresh/gl4/gl4_shaders.c @@ -35,8 +35,7 @@ static GLuint CompileShader(GLenum shaderType, const char* shaderSrc, const char* shaderSrc2) { GLuint shader = glCreateShader(shaderType); - - const char* version = "#version 460\n"; + const char* version = glshader_version(gl4config.major_version, gl4config.minor_version); const char* sources[3] = { version, shaderSrc, shaderSrc2 }; int numSources = shaderSrc2 != NULL ? 3 : 2; diff --git a/src/client/refresh/gl4/header/local.h b/src/client/refresh/gl4/header/local.h index ceb75502..e75988f6 100644 --- a/src/client/refresh/gl4/header/local.h +++ b/src/client/refresh/gl4/header/local.h @@ -496,6 +496,7 @@ extern void GL4_UpdateUBOLights(void); // ############ Cvars ########### extern cvar_t *gl_msaa_samples; +extern cvar_t *gl_version_override; extern cvar_t *r_vsync; extern cvar_t *r_retexturing; extern cvar_t *r_maptype; diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index 93e5f3e4..9fed1367 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -418,4 +418,7 @@ extern void R_ClearSkyBox(float skymins[2][6], float skymaxs[2][6]); extern void R_MakeSkyVec(float s, float t, int axis, mvtx_t* vert, qboolean farsee, float sky_min, float sky_max); +/* GL only code */ +extern const char* glshader_version(int major_version, int minor_version); + #endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */