/** * Go through GL_shader and call glDeleteObject() for all created shaders, then clear GL_shader */ void opengl_shader_shutdown() { size_t i; if ( !is_minimum_GLSL_version() ) { return; } for (i = 0; i < GL_shader.size(); i++) { if (GL_shader[i].program_id) { vglDeleteObjectARB(GL_shader[i].program_id); GL_shader[i].program_id = 0; } GL_shader[i].uniforms.clear(); GL_shader[i].attributes.clear(); GL_shader[i].uniform_blocks.clear(); } GL_shader.clear(); if (GLshader_info_log != NULL) { vm_free(GLshader_info_log); GLshader_info_log = NULL; } }
/** * Initializes the shader system. Creates a 1x1 texture that can be used as a fallback texture when framebuffer support is missing. * Also compiles the shaders used for particle rendering. */ void opengl_shader_init() { if ( !is_minimum_GLSL_version() ) { return; } glGenTextures(1,&Framebuffer_fallback_texture_id); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Framebuffer_fallback_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); GLuint pixels[4] = {0,0,0,0}; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &pixels); GL_shader.clear(); // Reserve 32 shader slots. This should cover most use cases in real life. GL_shader.reserve(32); // compile effect shaders gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, 0); gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, SDR_FLAG_PARTICLE_POINT_GEN); gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_DISTORTION, 0); // compile deferred lighting shaders opengl_shader_compile_deferred_light_shader(); mprintf(("\n")); }
void opengl_post_process_init() { Post_initialized = 0; //We need to read the tbl first. This is mostly for FRED's benefit, as otherwise the list of post effects for the sexp doesn't get updated. if ( !opengl_post_init_table() ) { mprintf((" Unable to read post-processing table! Disabling post-processing...\n\n")); Cmdline_postprocess = 0; return; } if ( !Cmdline_postprocess ) { return; } if ( !Scene_texture_initialized ) { return; } if ( !is_minimum_GLSL_version() || Cmdline_no_fbo || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) ) { Cmdline_postprocess = 0; return; } // for ease of use we require support for non-power-of-2 textures in one // form or another: // - the NPOT extension // - GL version 2.0+ (which should work for non-reporting ATI cards since we don't use mipmaps) if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_NON_POWER_OF_TWO) || (GL_version >= 20)) ) { Cmdline_postprocess = 0; return; } if ( !opengl_post_init_shaders() ) { mprintf((" Unable to initialize post-processing shaders! Disabling post-processing...\n\n")); Cmdline_postprocess = 0; return; } if ( !opengl_post_init_framebuffer() ) { mprintf((" Unable to initialize post-processing framebuffer! Disabling post-processing...\n\n")); Cmdline_postprocess = 0; return; } Post_initialized = 1; }
/** * Given a set of flags, determine whether a shader with these flags exists within the GL_shader vector. If no shader with the requested flags exists, attempt to compile one. * * @param shader_t shader_type variable, a reference to the shader program needed * @param flags Integer variable, holding a combination of SDR_* flags * @return Index into GL_shader, referencing a valid shader, or -1 if shader compilation failed */ int gr_opengl_maybe_create_shader(shader_type shader_t, unsigned int flags) { if (!is_minimum_GLSL_version()) return -1; size_t idx; size_t max = GL_shader.size(); for (idx = 0; idx < max; idx++) { if (GL_shader[idx].shader == shader_t && GL_shader[idx].flags == flags) { return idx; } } // If we are here, it means we need to compile a new shader return opengl_compile_shader(shader_t, flags); }
void opengl_extensions_init() { opengl_get_extensions(); // if S3TC compression is found, then "GL_ARB_texture_compression" must be an extension Use_compressed_textures = Is_Extension_Enabled(OGL_EXT_TEXTURE_COMPRESSION_S3TC); Texture_compression_available = Is_Extension_Enabled(OGL_ARB_TEXTURE_COMPRESSION); // Swifty put this in, but it's not doing anything. Once he uses it, he can uncomment it. //int use_base_vertex = Is_Extension_Enabled(OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX); //allow VBOs to be used if ( !Cmdline_nohtl && !Cmdline_novbo && Is_Extension_Enabled(OGL_ARB_VERTEX_BUFFER_OBJECT) ) { Use_VBOs = 1; } if ( !Cmdline_no_pbo && Is_Extension_Enabled(OGL_ARB_PIXEL_BUFFER_OBJECT) ) { Use_PBOs = 1; } // setup the best fog function found if ( !Fred_running ) { if ( Is_Extension_Enabled(OGL_EXT_FOG_COORD) ) { OGL_fogmode = 2; } else { OGL_fogmode = 1; } } // if we can't do cubemaps then turn off Cmdline_env if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_CUBE_MAP) && Is_Extension_Enabled(OGL_ARB_TEXTURE_ENV_COMBINE)) ) { Cmdline_env = 0; } if ( !(Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4) && Is_Extension_Enabled(OGL_EXT_TEXTURE_ARRAY) && Is_Extension_Enabled(OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX)) ) { Cmdline_shadow_quality = 0; mprintf((" No hardware support for shadow mapping. Shadows will be disabled. \n")); } if ( !Cmdline_noglsl && Is_Extension_Enabled(OGL_ARB_SHADER_OBJECTS) && Is_Extension_Enabled(OGL_ARB_FRAGMENT_SHADER) && Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) ) { int ver = 0, major = 0, minor = 0; const char *glsl_ver = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); sscanf(glsl_ver, "%d.%d", &major, &minor); ver = (major * 100) + minor; GLSL_version = ver; // we require a minimum GLSL version if (!is_minimum_GLSL_version()) { mprintf((" OpenGL Shading Language version %s is not sufficient to use GLSL mode in FSO. Defaulting to fixed-function renderer.\n", glGetString(GL_SHADING_LANGUAGE_VERSION) )); } } // can't have this stuff without GLSL support if ( !is_minimum_GLSL_version() ) { Cmdline_normal = 0; Cmdline_height = 0; Cmdline_postprocess = 0; Cmdline_shadow_quality = 0; Cmdline_no_deferred_lighting = 1; } if ( GLSL_version < 120 || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) || !Is_Extension_Enabled(OGL_ARB_FLOATING_POINT_TEXTURES) ) { mprintf((" No hardware support for deferred lighting. Deferred lighting will be disabled. \n")); Cmdline_no_deferred_lighting = 1; Cmdline_no_batching = true; } if (is_minimum_GLSL_version()) { GLint max_texture_units; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &max_texture_units); // we need enough texture slots for this stuff to work if (max_texture_units < 6) { mprintf(( "Not enough texture units for height map support. We need at least 6, we found %d.\n", max_texture_units )); Cmdline_height = 0; } else if (max_texture_units < 5) { mprintf(( "Not enough texture units for height and normal map support. We need at least 5, we found %d.\n", max_texture_units )); Cmdline_normal = 0; Cmdline_height = 0; } else if (max_texture_units < 4) { mprintf(( "Not enough texture units found for GLSL support. We need at least 4, we found %d.\n", max_texture_units )); GLSL_version = 0; } } }