]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - vid_shared.c
removed allowfail flag on R_BufferData_Store and made cvar management
[xonotic/darkplaces.git] / vid_shared.c
index 4236bb766f4fd08cc55b1091d8553a141840d675..b141908a1e55f071b7f7a50763a2f67cb5bf8e2a 100644 (file)
@@ -199,8 +199,6 @@ cvar_t v_glslgamma = {CVAR_SAVE, "v_glslgamma", "1", "enables use of GLSL to app
 cvar_t v_glslgamma_2d = {CVAR_SAVE, "v_glslgamma_2d", "0", "applies GLSL gamma to 2d pictures (HUD, fonts)"};
 cvar_t v_psycho = {0, "v_psycho", "0", "easter egg"};
 
-extern cvar_t r_viewfbo;
-
 // brand of graphics chip
 const char *gl_vendor;
 // graphics chip model and other information
@@ -467,24 +465,27 @@ GLboolean (GLAPIENTRY *qglUnmapBufferARB) (GLenum target);
 void (GLAPIENTRY *qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
 void (GLAPIENTRY *qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
 
-//GL_EXT_framebuffer_object
-GLboolean (GLAPIENTRY *qglIsRenderbufferEXT)(GLuint renderbuffer);
-void (GLAPIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
-void (GLAPIENTRY *qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
-void (GLAPIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
-void (GLAPIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-void (GLAPIENTRY *qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
-GLboolean (GLAPIENTRY *qglIsFramebufferEXT)(GLuint framebuffer);
-void (GLAPIENTRY *qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
-void (GLAPIENTRY *qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
-void (GLAPIENTRY *qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
-GLenum (GLAPIENTRY *qglCheckFramebufferStatusEXT)(GLenum target);
-//void (GLAPIENTRY *qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-void (GLAPIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-void (GLAPIENTRY *qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
-void (GLAPIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-void (GLAPIENTRY *qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
-void (GLAPIENTRY *qglGenerateMipmapEXT)(GLenum target);
+//GL_ARB_framebuffer_object
+GLboolean (GLAPIENTRY *qglIsRenderbuffer)(GLuint renderbuffer);
+GLvoid (GLAPIENTRY *qglBindRenderbuffer)(GLenum target, GLuint renderbuffer);
+GLvoid (GLAPIENTRY *qglDeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers);
+GLvoid (GLAPIENTRY *qglGenRenderbuffers)(GLsizei n, GLuint *renderbuffers);
+GLvoid (GLAPIENTRY *qglRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLvoid (GLAPIENTRY *qglRenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLvoid (GLAPIENTRY *qglGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params);
+GLboolean (GLAPIENTRY *qglIsFramebuffer)(GLuint framebuffer);
+GLvoid (GLAPIENTRY *qglBindFramebuffer)(GLenum target, GLuint framebuffer);
+GLvoid (GLAPIENTRY *qglDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers);
+GLvoid (GLAPIENTRY *qglGenFramebuffers)(GLsizei n, GLuint *framebuffers);
+GLenum (GLAPIENTRY *qglCheckFramebufferStatus)(GLenum target);
+GLvoid (GLAPIENTRY *qglFramebufferTexture1D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLvoid (GLAPIENTRY *qglFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLvoid (GLAPIENTRY *qglFramebufferTexture3D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer);
+GLvoid (GLAPIENTRY *qglFramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLvoid (GLAPIENTRY *qglFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLvoid (GLAPIENTRY *qglGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLvoid (GLAPIENTRY *qglBlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GLvoid (GLAPIENTRY *qglGenerateMipmap)(GLenum target);
 
 void (GLAPIENTRY *qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
 
@@ -506,6 +507,17 @@ void (GLAPIENTRY *qglGetQueryObjectivARB)(GLuint qid, GLenum pname, GLint *param
 void (GLAPIENTRY *qglGetQueryObjectuivARB)(GLuint qid, GLenum pname, GLuint *params);
 
 void (GLAPIENTRY *qglSampleCoverageARB)(GLclampf value, GLboolean invert);
+
+void (GLAPIENTRY *qglGetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar** uniformNames, GLuint* uniformIndices);
+void (GLAPIENTRY *qglGetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+void (GLAPIENTRY *qglGetActiveUniformName)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName);
+GLuint (GLAPIENTRY *qglGetUniformBlockIndex)(GLuint program, const GLchar* uniformBlockName);
+void (GLAPIENTRY *qglGetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname,  GLint* params);
+void (GLAPIENTRY *qglGetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+void (GLAPIENTRY *qglBindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptrARB offset, GLsizeiptrARB size);
+void (GLAPIENTRY *qglBindBufferBase)(GLenum target, GLuint index, GLuint buffer);
+void (GLAPIENTRY *qglGetIntegeri_v)(GLenum target, GLuint index, GLint* data);
+void (GLAPIENTRY *qglUniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
 #endif
 
 #if _MSC_VER >= 1400
@@ -864,25 +876,65 @@ static dllfunction_t vbofuncs[] =
        {NULL, NULL}
 };
 
-static dllfunction_t fbofuncs[] =
+static dllfunction_t ubofuncs[] =
+{
+       {"glGetUniformIndices"        , (void **) &qglGetUniformIndices},
+       {"glGetActiveUniformsiv"      , (void **) &qglGetActiveUniformsiv},
+       {"glGetActiveUniformName"     , (void **) &qglGetActiveUniformName},
+       {"glGetUniformBlockIndex"     , (void **) &qglGetUniformBlockIndex},
+       {"glGetActiveUniformBlockiv"  , (void **) &qglGetActiveUniformBlockiv},
+       {"glGetActiveUniformBlockName", (void **) &qglGetActiveUniformBlockName},
+       {"glBindBufferRange"          , (void **) &qglBindBufferRange},
+       {"glBindBufferBase"           , (void **) &qglBindBufferBase},
+       {"glGetIntegeri_v"            , (void **) &qglGetIntegeri_v},
+       {"glUniformBlockBinding"      , (void **) &qglUniformBlockBinding},
+       {NULL, NULL}
+};
+
+static dllfunction_t arbfbofuncs[] =
 {
-       {"glIsRenderbufferEXT"                      , (void **) &qglIsRenderbufferEXT},
-       {"glBindRenderbufferEXT"                    , (void **) &qglBindRenderbufferEXT},
-       {"glDeleteRenderbuffersEXT"                 , (void **) &qglDeleteRenderbuffersEXT},
-       {"glGenRenderbuffersEXT"                    , (void **) &qglGenRenderbuffersEXT},
-       {"glRenderbufferStorageEXT"                 , (void **) &qglRenderbufferStorageEXT},
-       {"glGetRenderbufferParameterivEXT"          , (void **) &qglGetRenderbufferParameterivEXT},
-       {"glIsFramebufferEXT"                       , (void **) &qglIsFramebufferEXT},
-       {"glBindFramebufferEXT"                     , (void **) &qglBindFramebufferEXT},
-       {"glDeleteFramebuffersEXT"                  , (void **) &qglDeleteFramebuffersEXT},
-       {"glGenFramebuffersEXT"                     , (void **) &qglGenFramebuffersEXT},
-       {"glCheckFramebufferStatusEXT"              , (void **) &qglCheckFramebufferStatusEXT},
-//     {"glFramebufferTexture1DEXT"                , (void **) &qglFramebufferTexture1DEXT},
-       {"glFramebufferTexture2DEXT"                , (void **) &qglFramebufferTexture2DEXT},
-       {"glFramebufferTexture3DEXT"                , (void **) &qglFramebufferTexture3DEXT},
-       {"glFramebufferRenderbufferEXT"             , (void **) &qglFramebufferRenderbufferEXT},
-       {"glGetFramebufferAttachmentParameterivEXT" , (void **) &qglGetFramebufferAttachmentParameterivEXT},
-       {"glGenerateMipmapEXT"                      , (void **) &qglGenerateMipmapEXT},
+       {"glIsRenderbuffer"                      , (void **) &qglIsRenderbuffer},
+       {"glBindRenderbuffer"                    , (void **) &qglBindRenderbuffer},
+       {"glDeleteRenderbuffers"                 , (void **) &qglDeleteRenderbuffers},
+       {"glGenRenderbuffers"                    , (void **) &qglGenRenderbuffers},
+       {"glRenderbufferStorage"                 , (void **) &qglRenderbufferStorage},
+       {"glRenderbufferStorageMultisample"      , (void **) &qglRenderbufferStorageMultisample}, // not in GL_EXT_framebuffer_object
+       {"glGetRenderbufferParameteriv"          , (void **) &qglGetRenderbufferParameteriv},
+       {"glIsFramebuffer"                       , (void **) &qglIsFramebuffer},
+       {"glBindFramebuffer"                     , (void **) &qglBindFramebuffer},
+       {"glDeleteFramebuffers"                  , (void **) &qglDeleteFramebuffers},
+       {"glGenFramebuffers"                     , (void **) &qglGenFramebuffers},
+       {"glCheckFramebufferStatus"              , (void **) &qglCheckFramebufferStatus},
+       {"glFramebufferTexture1D"                , (void **) &qglFramebufferTexture1D},
+       {"glFramebufferTexture2D"                , (void **) &qglFramebufferTexture2D},
+       {"glFramebufferTexture3D"                , (void **) &qglFramebufferTexture3D},
+       {"glFramebufferTextureLayer"             , (void **) &qglFramebufferTextureLayer}, // not in GL_EXT_framebuffer_object
+       {"glFramebufferRenderbuffer"             , (void **) &qglFramebufferRenderbuffer},
+       {"glGetFramebufferAttachmentParameteriv" , (void **) &qglGetFramebufferAttachmentParameteriv},
+       {"glBlitFramebuffer"                     , (void **) &qglBlitFramebuffer}, // not in GL_EXT_framebuffer_object
+       {"glGenerateMipmap"                      , (void **) &qglGenerateMipmap},
+       {NULL, NULL}
+};
+
+static dllfunction_t extfbofuncs[] =
+{
+       {"glIsRenderbufferEXT"                      , (void **) &qglIsRenderbuffer},
+       {"glBindRenderbufferEXT"                    , (void **) &qglBindRenderbuffer},
+       {"glDeleteRenderbuffersEXT"                 , (void **) &qglDeleteRenderbuffers},
+       {"glGenRenderbuffersEXT"                    , (void **) &qglGenRenderbuffers},
+       {"glRenderbufferStorageEXT"                 , (void **) &qglRenderbufferStorage},
+       {"glGetRenderbufferParameterivEXT"          , (void **) &qglGetRenderbufferParameteriv},
+       {"glIsFramebufferEXT"                       , (void **) &qglIsFramebuffer},
+       {"glBindFramebufferEXT"                     , (void **) &qglBindFramebuffer},
+       {"glDeleteFramebuffersEXT"                  , (void **) &qglDeleteFramebuffers},
+       {"glGenFramebuffersEXT"                     , (void **) &qglGenFramebuffers},
+       {"glCheckFramebufferStatusEXT"              , (void **) &qglCheckFramebufferStatus},
+       {"glFramebufferTexture1DEXT"                , (void **) &qglFramebufferTexture1D},
+       {"glFramebufferTexture2DEXT"                , (void **) &qglFramebufferTexture2D},
+       {"glFramebufferTexture3DEXT"                , (void **) &qglFramebufferTexture3D},
+       {"glFramebufferRenderbufferEXT"             , (void **) &qglFramebufferRenderbuffer},
+       {"glGetFramebufferAttachmentParameterivEXT" , (void **) &qglGetFramebufferAttachmentParameteriv},
+       {"glGenerateMipmapEXT"                      , (void **) &qglGenerateMipmap},
        {NULL, NULL}
 };
 
@@ -953,7 +1005,7 @@ void VID_ClearExtensions(void)
        qglFlush = NULL;
        qglActiveTexture = NULL;
        qglGetCompressedTexImageARB = NULL;
-       qglFramebufferTexture2DEXT = NULL;
+       qglFramebufferTexture2D = NULL;
        qglDrawBuffersARB = NULL;
 #endif
 }
@@ -971,18 +1023,18 @@ void VID_CheckExtensions(void)
 
        if (vid.support.gl20shaders)
        {
-               // this one is purely optional, needed for GLSL 1.3 support (#version 130), so we don't even check the return value of GL_CheckExtension
-               vid.support.gl20shaders130 = GL_CheckExtension("glshaders130", glsl130funcs, "-noglsl130", true);
-               if(vid.support.gl20shaders130)
-               {
-                       char *s = (char *) qglGetString(GL_SHADING_LANGUAGE_VERSION);
-                       if(!s || atof(s) < 1.30 - 0.00001)
-                               vid.support.gl20shaders130 = 0;
-               }
-               if(vid.support.gl20shaders130)
-                       Con_DPrintf("Using GLSL 1.30\n");
-               else
-                       Con_DPrintf("Using GLSL 1.00\n");
+               char *s;
+               // detect what GLSL version is available, to enable features like r_glsl_skeletal and higher quality reliefmapping
+               vid.support.glshaderversion = 100;
+               s = (char *) qglGetString(GL_SHADING_LANGUAGE_VERSION);
+               if (s)
+                       vid.support.glshaderversion = (int)(atof(s) * 100.0f + 0.5f);
+               if (vid.support.glshaderversion < 100)
+                       vid.support.glshaderversion = 100;
+               Con_DPrintf("Detected GLSL #version %i\n", vid.support.glshaderversion);
+               // get the glBindFragDataLocation function
+               if (vid.support.glshaderversion >= 130)
+                       vid.support.gl20shaders130 = GL_CheckExtension("glshaders130", glsl130funcs, "-noglsl130", true);
        }
 
        // GL drivers generally prefer GL_BGRA
@@ -1003,11 +1055,17 @@ void VID_CheckExtensions(void)
        vid.support.arb_texture_non_power_of_two = GL_CheckExtension("GL_ARB_texture_non_power_of_two", NULL, "-notexturenonpoweroftwo", false);
 #endif
        vid.support.arb_vertex_buffer_object = GL_CheckExtension("GL_ARB_vertex_buffer_object", vbofuncs, "-novbo", false);
+       vid.support.arb_uniform_buffer_object = GL_CheckExtension("GL_ARB_uniform_buffer_object", ubofuncs, "-noubo", false);
        vid.support.ati_separate_stencil = GL_CheckExtension("separatestencil", gl2separatestencilfuncs, "-noseparatestencil", true) || GL_CheckExtension("GL_ATI_separate_stencil", atiseparatestencilfuncs, "-noseparatestencil", false);
        vid.support.ext_blend_minmax = GL_CheckExtension("GL_EXT_blend_minmax", blendequationfuncs, "-noblendminmax", false);
        vid.support.ext_blend_subtract = GL_CheckExtension("GL_EXT_blend_subtract", blendequationfuncs, "-noblendsubtract", false);
        vid.support.ext_draw_range_elements = GL_CheckExtension("drawrangeelements", drawrangeelementsfuncs, "-nodrawrangeelements", true) || GL_CheckExtension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false);
-       vid.support.ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", fbofuncs, "-nofbo", false);
+       vid.support.arb_framebuffer_object = GL_CheckExtension("GL_ARB_framebuffer_object", arbfbofuncs, "-nofbo", false);
+       if (vid.support.arb_framebuffer_object)
+               vid.support.ext_framebuffer_object = true;
+       else
+               vid.support.ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", extfbofuncs, "-nofbo", false);
+
        vid.support.ext_packed_depth_stencil = GL_CheckExtension("GL_EXT_packed_depth_stencil", NULL, "-nopackeddepthstencil", false);
        vid.support.ext_stencil_two_side = GL_CheckExtension("GL_EXT_stencil_two_side", stenciltwosidefuncs, "-nostenciltwoside", false);
        vid.support.ext_texture_3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false);
@@ -1413,7 +1471,7 @@ void VID_BuildGammaTables(unsigned short *ramps, int rampsize)
        {
                int i;
                for(i = 0; i < 3*rampsize; ++i)
-                       ramps[i] = (int)floor(bound(0.0f, Image_sRGBFloatFromLinearFloat(ramps[i] / 65535.0), 1.0f) * 65535.0 + 0.5);
+                       ramps[i] = (int)floor(bound(0.0f, Image_sRGBFloatFromLinearFloat(ramps[i] / 65535.0f), 1.0f) * 65535.0f + 0.5f);
        }
 
        // LordHavoc: this code came from Ben Winslow and Zinx Verituse, I have
@@ -1782,11 +1840,27 @@ static int VID_Mode(int fullscreen, int width, int height, int bpp, float refres
                vid.sRGB2D         = vid_sRGB.integer >= 1 && vid.sRGBcapable2D;
                vid.sRGB3D         = vid_sRGB.integer >= 1 && vid.sRGBcapable3D;
 
+               switch(vid.renderpath)
+               {
+               case RENDERPATH_GL11:
+               case RENDERPATH_GL13:
+               case RENDERPATH_GL20:
+                       {
+                               GLboolean stereo;
+                               qglGetBooleanv(GL_STEREO, &stereo);
+                               vid.stereobuffer = stereo != 0;
+                       }
+                       break;
+               default:
+                       vid.stereobuffer = false;
+                       break;
+               }
+
                if(
                        (vid_sRGB_fallback.integer >= 3) // force fallback
                        ||
                        (vid_sRGB_fallback.integer >= 2 && // fallback if framebuffer is 8bit
-                               !(r_viewfbo.integer >= 2 && vid.support.ext_framebuffer_object && vid.samples < 2))
+                               !(r_viewfbo.integer >= 2 && vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two && vid.samples < 2))
                )
                        vid.sRGB2D = vid.sRGB3D = false;
 
@@ -1802,7 +1876,7 @@ static int VID_Mode(int fullscreen, int width, int height, int bpp, float refres
                Cvar_SetValueQuick(&vid_samples, vid.mode.samples);
                if(vid_userefreshrate.integer)
                        Cvar_SetValueQuick(&vid_refreshrate, vid.mode.refreshrate);
-               Cvar_SetValueQuick(&vid_stereobuffer, vid.mode.stereobuffer);
+               Cvar_SetValueQuick(&vid_stereobuffer, vid.stereobuffer ? 1 : 0);
 
                return true;
        }
@@ -1835,7 +1909,7 @@ void VID_Restart_f(void)
 
        if (!vid_opened)
        {
-               SCR_BeginLoadingPlaque();
+               SCR_BeginLoadingPlaque(false);
                return;
        }
 
@@ -2012,6 +2086,7 @@ void VID_Soft_SharedSetup(void)
        vid.support.ext_blend_subtract = true;
        vid.support.ext_draw_range_elements = true;
        vid.support.ext_framebuffer_object = true;
+
        vid.support.ext_texture_3d = true;
        //vid.support.ext_texture_compression_s3tc = true;
        vid.support.ext_texture_filter_anisotropic = true;