/** * 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() { 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); gr_opengl_maybe_create_shader(SDR_TYPE_SHIELD_DECAL, 0); // compile deferred lighting shaders opengl_shader_compile_deferred_light_shader(); // compile passthrough shader opengl_shader_compile_passthrough_shader(); mprintf(("\n")); }
/** * Compile the deferred light shader and the clear shader. */ void opengl_shader_compile_deferred_light_shader() { bool in_error = false; int sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_LIGHTING, 0); if ( sdr_handle >= 0 ) { opengl_shader_set_current(sdr_handle); Current_shader->program->Uniforms.setUniformi("ColorBuffer", 0); Current_shader->program->Uniforms.setUniformi("NormalBuffer", 1); Current_shader->program->Uniforms.setUniformi("PositionBuffer", 2); Current_shader->program->Uniforms.setUniformi("SpecBuffer", 3); Current_shader->program->Uniforms.setUniformf("invScreenWidth", 1.0f / gr_screen.max_w); Current_shader->program->Uniforms.setUniformf("invScreenHeight", 1.0f / gr_screen.max_h); Current_shader->program->Uniforms.setUniformf("specFactor", Cmdline_ogl_spec); } else { opengl_shader_set_current(); mprintf(("Failed to compile deferred lighting shader!\n")); in_error = true; } if ( gr_opengl_maybe_create_shader(SDR_TYPE_DEFERRED_CLEAR, 0) < 0 ) { mprintf(("Failed to compile deferred lighting buffer clear shader!\n")); in_error = true; } if ( in_error ) { mprintf((" Shader in_error! Disabling deferred lighting!\n")); Cmdline_no_deferred_lighting = 1; } }
void recompile_fxaa_shader() { mprintf(("Recompiling FXAA shader with preset %d\n", Cmdline_fxaa_preset)); // start recompile by grabbing deleting the current shader we have, assuming it's already created opengl_delete_shader( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) ); // then recreate it again. shader loading code will be updated with the new FXAA presets gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0); Fxaa_preset_last_frame = Cmdline_fxaa_preset; }
void opengl_post_lightshafts() { opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_LIGHTSHAFTS, 0)); float x, y; // should we even be here? if ( !Game_subspace_effect && ls_on && !ls_force_off ) { int n_lights = light_get_global_count(); for ( int idx = 0; idx<n_lights; idx++ ) { vec3d light_dir; vec3d local_light_dir; light_get_global_dir(&light_dir, idx); vm_vec_rotate(&local_light_dir, &light_dir, &Eye_matrix); if ( !stars_sun_has_glare(idx) ) { continue; } float dot; if ( (dot = vm_vec_dot(&light_dir, &Eye_matrix.vec.fvec)) > 0.7f ) { x = asinf(vm_vec_dot(&light_dir, &Eye_matrix.vec.rvec)) / PI*1.5f + 0.5f; //cant get the coordinates right but this works for the limited glare fov y = asinf(vm_vec_dot(&light_dir, &Eye_matrix.vec.uvec)) / PI*1.5f*gr_screen.clip_aspect + 0.5f; Current_shader->program->Uniforms.setUniform2f("sun_pos", x, y); Current_shader->program->Uniforms.setUniformi("scene", 0); Current_shader->program->Uniforms.setUniformi("cockpit", 1); Current_shader->program->Uniforms.setUniformf("density", ls_density); Current_shader->program->Uniforms.setUniformf("falloff", ls_falloff); Current_shader->program->Uniforms.setUniformf("weight", ls_weight); Current_shader->program->Uniforms.setUniformf("intensity", Sun_spot * ls_intensity); Current_shader->program->Uniforms.setUniformf("cp_intensity", Sun_spot * ls_cpintensity); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_depth_texture); GL_state.Texture.SetActiveUnit(1); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Cockpit_depth_texture); GL_state.Blend(GL_TRUE); GL_state.SetAlphaBlendMode(ALPHA_BLEND_ADDITIVE); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Blend(GL_FALSE); break; } } } if ( zbuffer_saved ) { zbuffer_saved = false; gr_zbuffer_set(GR_ZBUFF_FULL); glClear(GL_DEPTH_BUFFER_BIT); gr_zbuffer_set(GR_ZBUFF_NONE); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Scene_depth_texture, 0); } }
void opengl_post_pass_fxaa() { //If the preset changed, recompile the shader if (Fxaa_preset_last_frame != Cmdline_fxaa_preset) { recompile_fxaa_shader(); } // We only want to draw to ATTACHMENT0 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // Do a prepass to convert the main shaders' RGBA output into RGBL opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) ); // basic/default uniforms GL_state.Uniform.setUniformi( "tex", 0 ); vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Scene_luminance_texture, 0); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_color_texture); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Texture.Disable(); // set and configure post shader .. opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) ); vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Scene_color_texture, 0); // basic/default uniforms GL_state.Uniform.setUniformi( "tex0", 0 ); GL_state.Uniform.setUniformf( "rt_w", static_cast<float>(Post_texture_width)); GL_state.Uniform.setUniformf( "rt_h", static_cast<float>(Post_texture_height)); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_luminance_texture); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Texture.Disable(); opengl_shader_set_current(); }
bool opengl_post_init_shaders() { int idx; int flags = 0; // figure out which flags we need for the main post process shader for (idx = 0; idx < (int)Post_effects.size(); idx++) { if (Post_effects[idx].always_on) { flags |= (1 << idx); } } if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, flags) < 0 ) { // only the main shader is actually required for post-processing return false; } if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BRIGHTPASS, 0) < 0 || gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_HORIZONTAL) < 0 || gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_VERTICAL) < 0 || gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLOOM_COMP, 0) < 0) { // disable bloom if we don't have those shaders available Cmdline_bloom_intensity = 0; } if ( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA, 0) < 0 || gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_FXAA_PREPASS, 0) < 0 ) { Cmdline_fxaa = false; fxaa_unavailable = true; mprintf(("Error while compiling FXAA shaders. FXAA will be unavailable.\n")); } return true; }
void opengl_shader_compile_passthrough_shader() { mprintf(("Compiling passthrough shader...\n")); int sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0); opengl_shader_set_current(sdr_handle); //Hardcoded Uniforms Current_shader->program->Uniforms.setUniformi("baseMap", 0); Current_shader->program->Uniforms.setUniformi("clipEnabled", 0); opengl_shader_set_current(); }
void opengl_post_pass_tonemap() { opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_TONEMAPPING, 0) ); Current_shader->program->Uniforms.setUniformi("tex", 0); Current_shader->program->Uniforms.setUniformf("exposure", 4.0f); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_ldr_texture, 0); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_color_texture); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); }
void opengl_shader_set_passthrough(bool textured) { opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_PASSTHROUGH_RENDER, 0)); if ( textured ) { Current_shader->program->Uniforms.setUniformi("noTexturing", 0); } else { Current_shader->program->Uniforms.setUniformi("noTexturing", 1); } Current_shader->program->Uniforms.setUniformi("alphaTexture", 0); Current_shader->program->Uniforms.setUniformi("srgb", High_dynamic_range ? 1 : 0); Current_shader->program->Uniforms.setUniformf("intensity", 1.0f); Current_shader->program->Uniforms.setUniformf("alphaThreshold", GL_alpha_threshold); Current_shader->program->Uniforms.setUniform4f("color", 1.0f, 1.0f, 1.0f, 1.0f); Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix); Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix); }
void gr_opengl_post_process_set_effect(const char *name, int value) { if ( !Post_initialized ) { return; } if (name == NULL) { return; } size_t idx; int sflags = 0; if(!stricmp("lightshafts",name)) { ls_intensity = value / 100.0f; ls_on = !!value; return; } for (idx = 0; idx < Post_effects.size(); idx++) { const char *eff_name = Post_effects[idx].name.c_str(); if ( !stricmp(eff_name, name) ) { Post_effects[idx].intensity = (value / Post_effects[idx].div) + Post_effects[idx].add; break; } } // figure out new flags for (idx = 0; idx < Post_effects.size(); idx++) { if ( Post_effects[idx].always_on || (Post_effects[idx].intensity != Post_effects[idx].default_intensity) ) { sflags |= (1<<idx); } } Post_active_shader_index = gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, sflags); }
void opengl_post_pass_bloom() { // we need the scissor test disabled GLboolean scissor_test = GL_state.ScissorTest(GL_FALSE); // ------ begin bright pass ------ glBindFramebuffer(GL_FRAMEBUFFER, Bloom_framebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Bloom_textures[0], 0); // width and height are 1/2 for the bright pass int width = Post_texture_width >> 1; int height = Post_texture_height >> 1; glViewport(0, 0, width, height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BRIGHTPASS, 0) ); Current_shader->program->Uniforms.setUniformi("tex", 0); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_color_texture); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f); // ------ end bright pass ------ // ------ begin blur pass ------ GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Bloom_textures[0]); glGenerateMipmap(GL_TEXTURE_2D); for ( int iteration = 0; iteration < 2; iteration++) { for (int pass = 0; pass < 2; pass++) { GLuint source_tex = Bloom_textures[pass]; GLuint dest_tex = Bloom_textures[1 - pass]; if (pass) { opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_HORIZONTAL)); } else { opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLUR, SDR_FLAG_BLUR_VERTICAL)); } Current_shader->program->Uniforms.setUniformi("tex", 0); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(source_tex); for (int mipmap = 0; mipmap < MAX_MIP_BLUR_LEVELS; ++mipmap) { int bloom_width = width >> mipmap; int bloom_height = height >> mipmap; Current_shader->program->Uniforms.setUniformf("texSize", (pass) ? 1.0f / i2fl(bloom_width) : 1.0f / i2fl(bloom_height)); Current_shader->program->Uniforms.setUniformi("level", mipmap); Current_shader->program->Uniforms.setUniformf("tapSize", 1.0f); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dest_tex, mipmap); glViewport(0, 0, bloom_width, bloom_height); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f); } } } // composite blur to the color texture glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_color_texture, 0); opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_BLOOM_COMP, 0)); Current_shader->program->Uniforms.setUniformi("tex", 0); Current_shader->program->Uniforms.setUniformi("levels", MAX_MIP_BLUR_LEVELS); Current_shader->program->Uniforms.setUniformf("bloom_intensity", Cmdline_bloom_intensity / 100.0f); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Bloom_textures[0]); GL_state.SetAlphaBlendMode( ALPHA_BLEND_ADDITIVE ); glViewport(0, 0, gr_screen.max_w, gr_screen.max_h); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f); GL_state.SetAlphaBlendMode( ALPHA_BLEND_NONE ); // ------ end blur pass -------- // reset viewport, scissor test and exit GL_state.ScissorTest(scissor_test); }
void gr_opengl_post_process_end() { // state switch just the once (for bloom pass and final render-to-screen) GLboolean depth = GL_state.DepthTest(GL_FALSE); GLboolean depth_mask = GL_state.DepthMask(GL_FALSE); GLboolean blend = GL_state.Blend(GL_FALSE); GLboolean cull = GL_state.CullFace(GL_FALSE); GL_state.Texture.SetShaderMode(GL_TRUE); // do bloom, hopefully ;) opengl_post_pass_bloom(); // do tone mapping opengl_post_pass_tonemap(); // Do FXAA if (Cmdline_fxaa && !fxaa_unavailable && !GL_rendering_to_texture) { opengl_post_pass_fxaa(); } // render lightshafts opengl_post_lightshafts(); // now write to the on-screen buffer glBindFramebuffer(GL_FRAMEBUFFER, opengl_get_rtt_framebuffer()); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // set and configure post shader ... int flags = 0; for ( int i = 0; i < (int)Post_effects.size(); i++) { if (Post_effects[i].always_on) { flags |= (1 << i); } } int post_sdr_handle = Post_active_shader_index; if ( post_sdr_handle < 0 ) { // no active shader index? use the always on shader. post_sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, flags); } opengl_shader_set_current(post_sdr_handle); // basic/default uniforms Current_shader->program->Uniforms.setUniformi( "tex", 0 ); Current_shader->program->Uniforms.setUniformi( "depth_tex", 1); Current_shader->program->Uniforms.setUniformf( "timer", static_cast<float>(timer_get_milliseconds() % 100 + 1) ); for (size_t idx = 0; idx < Post_effects.size(); idx++) { if ( GL_shader[post_sdr_handle].flags & (1<<idx) ) { const char *name = Post_effects[idx].uniform_name.c_str(); float value = Post_effects[idx].intensity; Current_shader->program->Uniforms.setUniformf( name, value); } } // now render it to the screen ... glBindFramebuffer(GL_FRAMEBUFFER,0); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); //GL_state.Texture.Enable(Scene_color_texture); GL_state.Texture.Enable(Scene_ldr_texture); GL_state.Texture.SetActiveUnit(1); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_depth_texture); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); //Shadow Map debug window //#define SHADOW_DEBUG #ifdef SHADOW_DEBUG opengl_shader_set_current( &GL_post_shader[8] ); GL_state.Texture.SetActiveUnit(0); // GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY); // GL_state.Texture.Enable(Shadow_map_depth_texture); extern GLuint Shadow_map_texture; extern GLuint Post_shadow_texture_id; GL_state.Texture.Enable(Shadow_map_texture); glUniform1iARB( opengl_shader_get_uniform("shadow_map"), 0); glUniform1iARB( opengl_shader_get_uniform("index"), 0); //opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, Scene_texture_u_scale, Scene_texture_u_scale); //opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.5f); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 1.0f, 1.0f); glUniform1iARB( opengl_shader_get_uniform("index"), 1); //opengl_draw_textured_quad(-1.0f, -0.5f, 0.5f, 0.0f, -0.5f, 0.0f, 0.75f, 0.25f); opengl_draw_textured_quad(-1.0f, -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 1.0f, 1.0f); glUniform1iARB( opengl_shader_get_uniform("index"), 2); opengl_draw_textured_quad(-0.5f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 1.0f, 1.0f); glUniform1iARB( opengl_shader_get_uniform("index"), 3); opengl_draw_textured_quad(-0.5f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 1.0f, 1.0f); opengl_shader_set_current(); #endif /*GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_depth_texture); */ // Done! /*GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_effect_texture); opengl_draw_textured_quad(0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_normal_texture); opengl_draw_textured_quad(-1.0f, -0.0f, 0.0f, 0.0f, 0.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_specular_texture); opengl_draw_textured_quad(0.0f, -0.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); */ GL_state.Texture.SetShaderMode(GL_FALSE); // reset state GL_state.DepthTest(depth); GL_state.DepthMask(depth_mask); GL_state.Blend(blend); GL_state.CullFace(cull); opengl_shader_set_current(); Post_in_frame = false; }
void gr_opengl_post_process_end() { // state switch just the once (for bloom pass and final render-to-screen) GLboolean depth = GL_state.DepthTest(GL_FALSE); GLboolean depth_mask = GL_state.DepthMask(GL_FALSE); GLboolean lighting = GL_state.Lighting(GL_FALSE); GLboolean blend = GL_state.Blend(GL_FALSE); GLboolean cull = GL_state.CullFace(GL_FALSE); GL_state.Texture.SetShaderMode(GL_TRUE); // Do FXAA if (Cmdline_fxaa && !fxaa_unavailable && !GL_rendering_to_texture) { opengl_post_pass_fxaa(); } opengl_shader_set_current( gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_LIGHTSHAFTS, 0) ); float x,y; // should we even be here? if (!Game_subspace_effect && ls_on && !ls_force_off) { int n_lights = light_get_global_count(); for(int idx=0; idx<n_lights; idx++) { vec3d light_dir; vec3d local_light_dir; light_get_global_dir(&light_dir, idx); vm_vec_rotate(&local_light_dir, &light_dir, &Eye_matrix); if (!stars_sun_has_glare(idx)) continue; float dot; if((dot=vm_vec_dot( &light_dir, &Eye_matrix.vec.fvec )) > 0.7f) { x = asinf(vm_vec_dot( &light_dir, &Eye_matrix.vec.rvec ))/PI*1.5f+0.5f; //cant get the coordinates right but this works for the limited glare fov y = asinf(vm_vec_dot( &light_dir, &Eye_matrix.vec.uvec ))/PI*1.5f*gr_screen.clip_aspect+0.5f; GL_state.Uniform.setUniform2f( "sun_pos", x, y); GL_state.Uniform.setUniformi( "scene", 0); GL_state.Uniform.setUniformi( "cockpit", 1); GL_state.Uniform.setUniformf( "density", ls_density); GL_state.Uniform.setUniformf( "falloff", ls_falloff); GL_state.Uniform.setUniformf( "weight", ls_weight); GL_state.Uniform.setUniformf( "intensity", Sun_spot * ls_intensity); GL_state.Uniform.setUniformf( "cp_intensity", Sun_spot * ls_cpintensity); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_depth_texture); GL_state.Texture.SetActiveUnit(1); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Cockpit_depth_texture); GL_state.Color(255, 255, 255, 255); GL_state.Blend(GL_TRUE); GL_state.SetAlphaBlendMode(ALPHA_BLEND_ADDITIVE); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Blend(GL_FALSE); break; } } } if(zbuffer_saved) { zbuffer_saved = false; gr_zbuffer_set(GR_ZBUFF_FULL); glClear(GL_DEPTH_BUFFER_BIT); gr_zbuffer_set(GR_ZBUFF_NONE); vglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Scene_depth_texture, 0); } // do bloom, hopefully ;) bool bloomed = opengl_post_pass_bloom(); // do tone mapping opengl_post_pass_tonemap(); // now write to the on-screen buffer vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, opengl_get_rtt_framebuffer()); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); GL_state.Color(255, 255, 255, 255); // set and configure post shader ... int flags = 0; for ( int i = 0; i < (int)Post_effects.size(); i++) { if (Post_effects[i].always_on) { flags |= (1 << i); } } int post_sdr_handle = Post_active_shader_index; if ( post_sdr_handle < 0 ) { // no active shader index? use the always on shader. post_sdr_handle = gr_opengl_maybe_create_shader(SDR_TYPE_POST_PROCESS_MAIN, flags); } opengl_shader_set_current(post_sdr_handle); // basic/default uniforms GL_state.Uniform.setUniformi( "tex", 0 ); GL_state.Uniform.setUniformi( "depth_tex", 2); GL_state.Uniform.setUniformf( "timer", static_cast<float>(timer_get_milliseconds() % 100 + 1) ); for (size_t idx = 0; idx < Post_effects.size(); idx++) { if ( GL_shader[post_sdr_handle].flags & (1<<idx) ) { const char *name = Post_effects[idx].uniform_name.c_str(); float value = Post_effects[idx].intensity; GL_state.Uniform.setUniformf( name, value); } } // bloom uniforms, but only if we did the bloom if (bloomed) { float intensity = MIN((float)Cmdline_bloom_intensity, 200.0f) * 0.01f; if (Neb2_render_mode != NEB2_RENDER_NONE) { // we need less intensity for full neb missions, so cut it by 30% intensity /= 3.0f; } //GL_state.Uniform.setUniformf( "bloom_intensity", intensity ); GL_state.Uniform.setUniformf( "bloom_intensity", 0.0f ); GL_state.Uniform.setUniformi( "levels" , MAX_MIP_BLUR_LEVELS ); GL_state.Uniform.setUniformi( "bloomed", 1 ); GL_state.Texture.SetActiveUnit(1); GL_state.Texture.SetTarget(GL_TEXTURE_2D); //GL_state.Texture.Enable(Post_bloom_texture_id[2]); GL_state.Texture.Enable(Bloom_textures[0]); } else GL_state.Uniform.setUniformf( "bloom_intensity", 0.0f ); // now render it to the screen ... vglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); //GL_state.Texture.Enable(Scene_color_texture); GL_state.Texture.Enable(Scene_ldr_texture); GL_state.Texture.SetActiveUnit(2); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_depth_texture); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); //Shadow Map debug window //#define SHADOW_DEBUG #ifdef SHADOW_DEBUG opengl_shader_set_current( &GL_post_shader[8] ); GL_state.Texture.SetActiveUnit(0); // GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY); // GL_state.Texture.Enable(Shadow_map_depth_texture); extern GLuint Shadow_map_texture; extern GLuint Post_shadow_texture_id; GL_state.Texture.Enable(Shadow_map_texture); vglUniform1iARB( opengl_shader_get_uniform("shadow_map"), 0); vglUniform1iARB( opengl_shader_get_uniform("index"), 0); //opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, Scene_texture_u_scale, Scene_texture_u_scale); //opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.5f); opengl_draw_textured_quad(-1.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 1.0f, 1.0f); vglUniform1iARB( opengl_shader_get_uniform("index"), 1); //opengl_draw_textured_quad(-1.0f, -0.5f, 0.5f, 0.0f, -0.5f, 0.0f, 0.75f, 0.25f); opengl_draw_textured_quad(-1.0f, -0.5f, 0.0f, 0.0f, -0.5f, 0.0f, 1.0f, 1.0f); vglUniform1iARB( opengl_shader_get_uniform("index"), 2); opengl_draw_textured_quad(-0.5f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 1.0f, 1.0f); vglUniform1iARB( opengl_shader_get_uniform("index"), 3); opengl_draw_textured_quad(-0.5f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 1.0f, 1.0f); opengl_shader_set_current(); #endif /*GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_depth_texture); */ // Done! /*GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_effect_texture); opengl_draw_textured_quad(0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_normal_texture); opengl_draw_textured_quad(-1.0f, -0.0f, 0.0f, 0.0f, 0.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Scene_specular_texture); opengl_draw_textured_quad(0.0f, -0.0f, 0.0f, 0.0f, 1.0f, 1.0f, Scene_texture_u_scale, Scene_texture_u_scale); */ GL_state.Texture.SetActiveUnit(2); GL_state.Texture.Disable(); GL_state.Texture.SetActiveUnit(1); GL_state.Texture.Disable(); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.Disable(); GL_state.Texture.SetShaderMode(GL_FALSE); // reset state GL_state.DepthTest(depth); GL_state.DepthMask(depth_mask); GL_state.Lighting(lighting); GL_state.Blend(blend); GL_state.CullFace(cull); opengl_shader_set_current(); Post_in_frame = false; }