void opengl_uniform_state::setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *val) { size_t uniform_index = findUniform(name); bool resident = false; if ( uniform_index != (size_t)-1) { Assert( (size_t)uniform_index < uniforms.size() ); uniform_bind *bind_info = &uniforms[uniform_index]; if ( bind_info->type == uniform_bind::MATRIX4 && bind_info->count == count ) { bool equal = true; // if the values are close enough, pass. for ( int i = 0; i < count; ++i ) { if ( !vm_matrix_equal(val[i], uniform_data_matrix4[bind_info->index+i]) ) { equal = false; break; } } if ( equal ) { return; } resident = true; for ( int i = 0; i < count; ++i ) { uniform_data_matrix4[bind_info->index+i] = val[i]; } } } if ( !resident ) { // uniform doesn't exist in our previous uniform block so queue this new value for ( int i = 0; i < count; ++i ) { uniform_data_matrix4.push_back(val[i]); } uniform_bind new_bind; new_bind.count = count; new_bind.index = uniform_data_matrix4.size() - count; // new_bind.index = num_matrix_uniforms - count; new_bind.type = uniform_bind::MATRIX4; new_bind.name = name; uniforms.push_back(new_bind); uniform_lookup[name] = uniforms.size()-1; } glUniformMatrix4fv(opengl_shader_get_uniform(name.c_str()), count, GL_FALSE, (const GLfloat*)val); }
void opengl_uniform_state::setUniformMatrix4f(const SCP_string &name, const matrix4 &val) { size_t uniform_index = findUniform(name); bool resident = false; if ( uniform_index != (size_t)-1) { Assert( (size_t)uniform_index < uniforms.size() ); uniform_bind *bind_info = &uniforms[uniform_index]; if ( bind_info->type == uniform_bind::MATRIX4 && bind_info->count == 1 ) { if ( vm_matrix_equal(uniform_data_matrix4[bind_info->index], val) ) { return; } uniform_data_matrix4[bind_info->index] = val; resident = true; } } if ( !resident ) { // uniform doesn't exist in our previous uniform block so queue this new value //matrix_uniform_data[num_matrix_uniforms] = val; //memcpy(&(matrix_uniform_data[num_matrix_uniforms]), &val, sizeof(matrix4)); uniform_data_matrix4.push_back(val); // num_matrix_uniforms += 1; uniform_bind new_bind; new_bind.count = 1; new_bind.index = uniform_data_matrix4.size() - 1; // new_bind.index = num_matrix_uniforms - 1; new_bind.type = uniform_bind::MATRIX4; new_bind.name = name; uniforms.push_back(new_bind); uniform_lookup[name] = uniforms.size()-1; } glUniformMatrix4fv(opengl_shader_get_uniform(name.c_str()), 1, GL_FALSE, (const GLfloat*)&val); }
void opengl_uniform_state::setUniform4f(const SCP_string &name, const vec4 &val) { size_t uniform_index = findUniform(name); bool resident = false; if (uniform_index != (size_t)-1) { Assert( (size_t)uniform_index < uniforms.size() ); uniform_bind *bind_info = &uniforms[uniform_index]; if ( bind_info->type == uniform_bind::VEC4 ) { if ( vm_vec_equal(uniform_data_vec4[bind_info->index], val) ) { // if the values are close enough, pass. return; } uniform_data_vec4[bind_info->index] = val; resident = true; } } if ( !resident ) { // uniform doesn't exist in our previous uniform block so queue this new value uniform_data_vec4.push_back(val); uniform_bind new_bind; new_bind.count = 1; new_bind.index = uniform_data_vec4.size() - 1; new_bind.type = uniform_bind::VEC4; new_bind.name = name; uniforms.push_back(new_bind); uniform_lookup[name] = uniforms.size()-1; } glUniform4f(opengl_shader_get_uniform(name.c_str()), val.a1d[0], val.a1d[1], val.a1d[2], val.a1d[3]); }
void opengl_uniform_state::setUniformf(const SCP_string &name, const float val) { size_t uniform_index = findUniform(name); bool resident = false; if ( uniform_index != (size_t) -1) { Assert( (size_t)uniform_index < uniforms.size() ); uniform_bind *bind_info = &uniforms[uniform_index]; if ( bind_info->type == uniform_bind::FLOAT ) { if ( fl_equal(uniform_data_floats[bind_info->index], val) ) { return; } uniform_data_floats[bind_info->index] = val; resident = true; } } if ( !resident ) { // uniform doesn't exist in our previous uniform block so queue this new value uniform_data_floats.push_back(val); uniform_bind new_bind; new_bind.count = 1; new_bind.index = uniform_data_floats.size() - 1; new_bind.type = uniform_bind::FLOAT; new_bind.name = name; uniforms.push_back(new_bind); uniform_lookup[name] = uniforms.size()-1; } glUniform1f(opengl_shader_get_uniform(name.c_str()), val); }
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; }