void opengl_tnl_set_material_decal(decal_material* material_info) { opengl_tnl_set_material(material_info, false); float u_scale, v_scale; uint32_t array_index; if (gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), material_info->get_texture_type(), &u_scale, &v_scale, &array_index, 0)) { Current_shader->program->Uniforms.setUniformi("diffuseMap", 0); } if (gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE), material_info->get_texture_type(), &u_scale, &v_scale, &array_index, 1)) { Current_shader->program->Uniforms.setUniformi("glowMap", 1); } if (gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE), material_info->get_texture_type(), &u_scale, &v_scale, &array_index, 2)) { Current_shader->program->Uniforms.setUniformi("normalMap", 2); } GL_state.Texture.Enable(3, GL_TEXTURE_2D, Scene_depth_texture); Current_shader->program->Uniforms.setUniformi("gDepthBuffer", 3); if (Current_shader->flags & SDR_FLAG_DECAL_USE_NORMAL_MAP) { GL_state.Texture.Enable(4, GL_TEXTURE_2D, Scene_normal_texture); Current_shader->program->Uniforms.setUniformi("gNormalBuffer", 4); } }
void opengl_tnl_set_material_movie(movie_material* material_info) { opengl_tnl_set_material(material_info, false); Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix); Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix); Current_shader->program->Uniforms.setUniformi("ytex", 0); Current_shader->program->Uniforms.setUniformi("utex", 1); Current_shader->program->Uniforms.setUniformi("vtex", 2); float u_scale, v_scale; uint32_t index; if ( !gr_opengl_tcache_set(material_info->getYtex(), material_info->get_texture_type(), &u_scale, &v_scale, &index, 0) ) { mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->getYtex())); } if ( !gr_opengl_tcache_set(material_info->getUtex(), material_info->get_texture_type(), &u_scale, &v_scale, &index, 1) ) { mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->getUtex())); } if ( !gr_opengl_tcache_set(material_info->getVtex(), material_info->get_texture_type(), &u_scale, &v_scale, &index, 2) ) { mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->getVtex())); } }
void opengl_tnl_set_material(material* material_info, bool set_base_map) { int shader_handle = material_info->get_shader_handle(); int base_map = material_info->get_texture_map(TM_BASE_TYPE); vec4 clr = material_info->get_color(); Assert(shader_handle >= 0); opengl_shader_set_current(shader_handle); if ( Current_shader->shader == SDR_TYPE_PASSTHROUGH_RENDER ) { opengl_shader_set_passthrough(base_map >= 0, material_info->get_texture_type() == TCACHE_TYPE_AABITMAP, &clr, material_info->get_color_scale()); } GL_state.SetAlphaBlendMode(material_info->get_blend_mode()); GL_state.SetZbufferType(material_info->get_depth_mode()); gr_set_cull(material_info->get_cull_mode() ? 1 : 0); gr_zbias(material_info->get_depth_bias()); gr_set_fill_mode(material_info->get_fill_mode()); material::fog &fog_params = material_info->get_fog(); if ( fog_params.enabled ) { gr_fog_set(GR_FOGMODE_FOG, fog_params.r, fog_params.g, fog_params.b, fog_params.dist_near, fog_params.dist_far); } else { gr_fog_set(GR_FOGMODE_NONE, 0, 0, 0); } gr_set_texture_addressing(material_info->get_texture_addressing()); material::clip_plane &clip_params = material_info->get_clip_plane(); if ( clip_params.enabled ) { gr_opengl_set_clip_plane(&clip_params.normal, &clip_params.position); } else { gr_opengl_set_clip_plane(NULL, NULL); } if ( set_base_map && base_map >= 0 ) { float u_scale, v_scale; if ( !gr_opengl_tcache_set(base_map, material_info->get_texture_type(), &u_scale, &v_scale) ) { mprintf(("WARNING: Error setting bitmap texture (%i)!\n", base_map)); } } }
void gr_opengl_render_shield_impact(shield_material *material_info, primitive_type prim_type, vertex_layout *layout, int buffer_handle, int n_verts) { matrix4 impact_transform; matrix4 impact_projection; vec3d min; vec3d max; opengl_tnl_set_material(material_info, false); float radius = material_info->get_impact_radius(); min.xyz.x = min.xyz.y = min.xyz.z = -radius; max.xyz.x = max.xyz.y = max.xyz.z = radius; vm_matrix4_set_orthographic(&impact_projection, &max, &min); matrix impact_orient = material_info->get_impact_orient(); vec3d impact_pos = material_info->get_impact_pos(); vm_matrix4_set_inverse_transform(&impact_transform, &impact_orient, &impact_pos); uint32_t array_index = 0; if ( material_info->get_texture_map(TM_BASE_TYPE) >= 0 ) { float u_scale, v_scale; if ( !gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), material_info->get_texture_type(), &u_scale, &v_scale, &array_index) ) { mprintf(("WARNING: Error setting bitmap texture (%i)!\n", material_info->get_texture_map(TM_BASE_TYPE))); } } Current_shader->program->Uniforms.setUniform3f("hitNormal", impact_orient.vec.fvec); Current_shader->program->Uniforms.setUniformMatrix4f("shieldProjMatrix", impact_projection); Current_shader->program->Uniforms.setUniformMatrix4f("shieldModelViewMatrix", impact_transform); Current_shader->program->Uniforms.setUniformi("shieldMap", 0); Current_shader->program->Uniforms.setUniformi("shieldMapIndex", array_index); Current_shader->program->Uniforms.setUniformi("srgb", High_dynamic_range ? 1 : 0); Current_shader->program->Uniforms.setUniform4f("color", material_info->get_color()); Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", gr_model_view_matrix); Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", gr_projection_matrix); opengl_render_primitives(prim_type, layout, n_verts, buffer_handle, 0, 0); }
void opengl_tnl_set_model_material(model_material *material_info) { float u_scale, v_scale; int render_pass = 0; opengl_tnl_set_material(material_info, false); if ( GL_state.CullFace() ) { GL_state.FrontFaceValue(GL_CW); } gr_opengl_set_center_alpha(material_info->get_center_alpha()); Assert( Current_shader->shader == SDR_TYPE_MODEL ); GL_state.Texture.SetShaderMode(GL_TRUE); Current_shader->program->Uniforms.setUniformMatrix4f("modelViewMatrix", GL_model_view_matrix); Current_shader->program->Uniforms.setUniformMatrix4f("modelMatrix", GL_model_matrix_stack.get_transform()); Current_shader->program->Uniforms.setUniformMatrix4f("viewMatrix", GL_view_matrix); Current_shader->program->Uniforms.setUniformMatrix4f("projMatrix", GL_projection_matrix); Current_shader->program->Uniforms.setUniformMatrix4f("textureMatrix", GL_texture_matrix); vec4 clr = material_info->get_color(); Current_shader->program->Uniforms.setUniform4f("color", clr); if ( Current_shader->flags & SDR_FLAG_MODEL_ANIMATED ) { Current_shader->program->Uniforms.setUniformf("anim_timer", material_info->get_animated_effect_time()); Current_shader->program->Uniforms.setUniformi("effect_num", material_info->get_animated_effect()); Current_shader->program->Uniforms.setUniformf("vpwidth", 1.0f / gr_screen.max_w); Current_shader->program->Uniforms.setUniformf("vpheight", 1.0f / gr_screen.max_h); } if ( Current_shader->flags & SDR_FLAG_MODEL_CLIP ) { bool clip = material_info->is_clipped(); if ( clip ) { material::clip_plane &clip_info = material_info->get_clip_plane(); Current_shader->program->Uniforms.setUniformi("use_clip_plane", 1); Current_shader->program->Uniforms.setUniform3f("clip_normal", clip_info.normal); Current_shader->program->Uniforms.setUniform3f("clip_position", clip_info.position); } else { Current_shader->program->Uniforms.setUniformi("use_clip_plane", 0); } } if ( Current_shader->flags & SDR_FLAG_MODEL_LIGHT ) { int num_lights = MIN(Num_active_gl_lights, GL_max_lights) - 1; float light_factor = material_info->get_light_factor(); Current_shader->program->Uniforms.setUniformi("n_lights", num_lights); Current_shader->program->Uniforms.setUniform4fv("lightPosition", GL_max_lights, opengl_light_uniforms.Position); Current_shader->program->Uniforms.setUniform3fv("lightDirection", GL_max_lights, opengl_light_uniforms.Direction); Current_shader->program->Uniforms.setUniform3fv("lightDiffuseColor", GL_max_lights, opengl_light_uniforms.Diffuse_color); Current_shader->program->Uniforms.setUniform3fv("lightSpecColor", GL_max_lights, opengl_light_uniforms.Spec_color); Current_shader->program->Uniforms.setUniform1iv("lightType", GL_max_lights, opengl_light_uniforms.Light_type); Current_shader->program->Uniforms.setUniform1fv("lightAttenuation", GL_max_lights, opengl_light_uniforms.Attenuation); if ( !material_info->get_center_alpha() ) { Current_shader->program->Uniforms.setUniform3f("diffuseFactor", GL_light_color[0] * light_factor, GL_light_color[1] * light_factor, GL_light_color[2] * light_factor); Current_shader->program->Uniforms.setUniform3f("ambientFactor", GL_light_ambient[0], GL_light_ambient[1], GL_light_ambient[2]); } else { //Current_shader->program->Uniforms.setUniform3f("diffuseFactor", GL_light_true_zero[0], GL_light_true_zero[1], GL_light_true_zero[2]); //Current_shader->program->Uniforms.setUniform3f("ambientFactor", GL_light_true_zero[0], GL_light_true_zero[1], GL_light_true_zero[2]); Current_shader->program->Uniforms.setUniform3f("diffuseFactor", GL_light_color[0] * light_factor, GL_light_color[1] * light_factor, GL_light_color[2] * light_factor); Current_shader->program->Uniforms.setUniform3f("ambientFactor", GL_light_ambient[0], GL_light_ambient[1], GL_light_ambient[2]); } if ( material_info->get_light_factor() > 0.25f && !Cmdline_no_emissive ) { Current_shader->program->Uniforms.setUniform3f("emissionFactor", GL_light_emission[0], GL_light_emission[1], GL_light_emission[2]); } else { Current_shader->program->Uniforms.setUniform3f("emissionFactor", GL_light_zero[0], GL_light_zero[1], GL_light_zero[2]); } Current_shader->program->Uniforms.setUniformf("specPower", Cmdline_ogl_spec); if ( Gloss_override_set ) { Current_shader->program->Uniforms.setUniformf("defaultGloss", Gloss_override); } else { Current_shader->program->Uniforms.setUniformf("defaultGloss", 0.6f); // add user configurable default gloss in the command line later } } if ( Current_shader->flags & SDR_FLAG_MODEL_DIFFUSE_MAP ) { Current_shader->program->Uniforms.setUniformi("sBasemap", render_pass); if ( material_info->is_desaturated() ) { Current_shader->program->Uniforms.setUniformi("desaturate", 1); } else { Current_shader->program->Uniforms.setUniformi("desaturate", 0); } if ( Basemap_color_override_set ) { Current_shader->program->Uniforms.setUniformi("overrideDiffuse", 1); Current_shader->program->Uniforms.setUniform3f("diffuseClr", Basemap_color_override[0], Basemap_color_override[1], Basemap_color_override[2]); } else { Current_shader->program->Uniforms.setUniformi("overrideDiffuse", 0); } switch ( material_info->get_blend_mode() ) { case ALPHA_BLEND_PREMULTIPLIED: Current_shader->program->Uniforms.setUniformi("blend_alpha", 1); break; case ALPHA_BLEND_ADDITIVE: Current_shader->program->Uniforms.setUniformi("blend_alpha", 2); break; default: Current_shader->program->Uniforms.setUniformi("blend_alpha", 0); break; } gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_GLOW_MAP ) { Current_shader->program->Uniforms.setUniformi("sGlowmap", render_pass); if ( Glowmap_color_override_set ) { Current_shader->program->Uniforms.setUniformi("overrideGlow", 1); Current_shader->program->Uniforms.setUniform3f("glowClr", Glowmap_color_override[0], Glowmap_color_override[1], Glowmap_color_override[2]); } else { Current_shader->program->Uniforms.setUniformi("overrideGlow", 0); } gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_SPEC_MAP ) { Current_shader->program->Uniforms.setUniformi("sSpecmap", render_pass); if ( Specmap_color_override_set ) { Current_shader->program->Uniforms.setUniformi("overrideSpec", 1); Current_shader->program->Uniforms.setUniform3f("specClr", Specmap_color_override[0], Specmap_color_override[1], Specmap_color_override[2]); } else { Current_shader->program->Uniforms.setUniformi("overrideSpec", 0); } if ( material_info->get_texture_map(TM_SPEC_GLOSS_TYPE) > 0 ) { gr_opengl_tcache_set(material_info->get_texture_map(TM_SPEC_GLOSS_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); Current_shader->program->Uniforms.setUniformi("gammaSpec", 1); if ( Gloss_override_set ) { Current_shader->program->Uniforms.setUniformi("alphaGloss", 0); } else { Current_shader->program->Uniforms.setUniformi("alphaGloss", 1); } } else { gr_opengl_tcache_set(material_info->get_texture_map(TM_SPECULAR_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); Current_shader->program->Uniforms.setUniformi("gammaSpec", 0); Current_shader->program->Uniforms.setUniformi("alphaGloss", 0); } ++render_pass; if ( Current_shader->flags & SDR_FLAG_MODEL_ENV_MAP ) { matrix4 texture_mat; for ( int i = 0; i < 16; ++i ) { texture_mat.a1d[i] = GL_env_texture_matrix[i]; } if ( material_info->get_texture_map(TM_SPEC_GLOSS_TYPE) > 0 || Gloss_override_set ) { Current_shader->program->Uniforms.setUniformi("envGloss", 1); } else { Current_shader->program->Uniforms.setUniformi("envGloss", 0); } Current_shader->program->Uniforms.setUniformMatrix4f("envMatrix", texture_mat); Current_shader->program->Uniforms.setUniformi("sEnvmap", render_pass); gr_opengl_tcache_set(ENVMAP, TCACHE_TYPE_CUBEMAP, &u_scale, &v_scale, render_pass); ++render_pass; } } if ( Current_shader->flags & SDR_FLAG_MODEL_NORMAL_MAP ) { Current_shader->program->Uniforms.setUniformi("sNormalmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_HEIGHT_MAP ) { Current_shader->program->Uniforms.setUniformi("sHeightmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_HEIGHT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_AMBIENT_MAP ) { Current_shader->program->Uniforms.setUniformi("sAmbientmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_AMBIENT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_MISC_MAP ) { Current_shader->program->Uniforms.setUniformi("sMiscmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_MISC_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_SHADOWS ) { Current_shader->program->Uniforms.setUniformMatrix4f("shadow_mv_matrix", Shadow_view_matrix); Current_shader->program->Uniforms.setUniformMatrix4fv("shadow_proj_matrix", MAX_SHADOW_CASCADES, Shadow_proj_matrix); Current_shader->program->Uniforms.setUniformf("veryneardist", Shadow_cascade_distances[0]); Current_shader->program->Uniforms.setUniformf("neardist", Shadow_cascade_distances[1]); Current_shader->program->Uniforms.setUniformf("middist", Shadow_cascade_distances[2]); Current_shader->program->Uniforms.setUniformf("fardist", Shadow_cascade_distances[3]); Current_shader->program->Uniforms.setUniformi("shadow_map", render_pass); GL_state.Texture.SetActiveUnit(render_pass); GL_state.Texture.SetTarget(GL_TEXTURE_2D_ARRAY); GL_state.Texture.Enable(Shadow_map_texture); ++render_pass; // bump! } if ( Current_shader->flags & SDR_FLAG_MODEL_SHADOW_MAP ) { Current_shader->program->Uniforms.setUniformMatrix4fv("shadow_proj_matrix", MAX_SHADOW_CASCADES, Shadow_proj_matrix); } if ( Current_shader->flags & SDR_FLAG_MODEL_ANIMATED ) { Current_shader->program->Uniforms.setUniformi("sFramebuffer", render_pass); GL_state.Texture.SetActiveUnit(render_pass); GL_state.Texture.SetTarget(GL_TEXTURE_2D); if ( Scene_framebuffer_in_frame ) { GL_state.Texture.Enable(Scene_effect_texture); glDrawBuffer(GL_COLOR_ATTACHMENT0); } else { GL_state.Texture.Enable(Framebuffer_fallback_texture_id); } ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_TRANSFORM ) { Current_shader->program->Uniforms.setUniformi("transform_tex", render_pass); Current_shader->program->Uniforms.setUniformi("buffer_matrix_offset", (int)GL_transform_buffer_offset); GL_state.Texture.SetActiveUnit(render_pass); GL_state.Texture.SetTarget(GL_TEXTURE_BUFFER); GL_state.Texture.Enable(opengl_get_transform_buffer_texture()); ++render_pass; } // Team colors are passed to the shader here, but the shader needs to handle their application. // By default, this is handled through the r and g channels of the misc map, but this can be changed // in the shader; test versions of this used the normal map r and b channels if ( Current_shader->flags & SDR_FLAG_MODEL_TEAMCOLOR ) { team_color &tm_clr = material_info->get_team_color(); vec3d stripe_color; vec3d base_color; stripe_color.xyz.x = tm_clr.stripe.r; stripe_color.xyz.y = tm_clr.stripe.g; stripe_color.xyz.z = tm_clr.stripe.b; base_color.xyz.x = tm_clr.base.r; base_color.xyz.y = tm_clr.base.g; base_color.xyz.z = tm_clr.base.b; Current_shader->program->Uniforms.setUniform3f("stripe_color", stripe_color); Current_shader->program->Uniforms.setUniform3f("base_color", base_color); if ( bm_has_alpha_channel(material_info->get_texture_map(TM_MISC_TYPE)) ) { Current_shader->program->Uniforms.setUniformi("team_glow_enabled", 1); } else { Current_shader->program->Uniforms.setUniformi("team_glow_enabled", 0); } } if ( Current_shader->flags & SDR_FLAG_MODEL_THRUSTER ) { Current_shader->program->Uniforms.setUniformf("thruster_scale", material_info->get_thrust_scale()); } if ( Current_shader->flags & SDR_FLAG_MODEL_FOG ) { material::fog fog_params = material_info->get_fog(); if ( fog_params.enabled ) { Current_shader->program->Uniforms.setUniformf("fogStart", fog_params.dist_near); Current_shader->program->Uniforms.setUniformf("fogScale", 1.0f / (fog_params.dist_far - fog_params.dist_near)); Current_shader->program->Uniforms.setUniform4f("fogColor", i2fl(fog_params.r) / 255.0f, i2fl(fog_params.g) / 255.0f, i2fl(fog_params.b) / 255.0f, 1.0f); } } if ( Current_shader->flags & SDR_FLAG_MODEL_NORMAL_ALPHA ) { Current_shader->program->Uniforms.setUniform2f("normalAlphaMinMax", material_info->get_normal_alpha_min(), material_info->get_normal_alpha_max()); } if ( Current_shader->flags & SDR_FLAG_MODEL_NORMAL_EXTRUDE ) { Current_shader->program->Uniforms.setUniformf("extrudeWidth", material_info->get_normal_extrude_width()); } if ( Deferred_lighting ) { // don't blend if we're drawing to the g-buffers GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE); } }
void opengl_tnl_set_model_material(model_material *material_info) { float u_scale, v_scale; int render_pass = 0; opengl_tnl_set_material(material_info, false, false); if ( GL_state.CullFace() ) { GL_state.FrontFaceValue(GL_CW); } gr_set_center_alpha(material_info->get_center_alpha()); Assert( Current_shader->shader == SDR_TYPE_MODEL ); GL_state.Texture.SetShaderMode(GL_TRUE); if (GL_workaround_clipping_planes) { if (Current_shader->flags & SDR_FLAG_MODEL_CLIP) { GL_state.ClipDistance(0, true); } else { GL_state.ClipDistance(0, false); } } else { if (Current_shader->flags & SDR_FLAG_MODEL_CLIP || Current_shader->flags & SDR_FLAG_MODEL_TRANSFORM) { GL_state.ClipDistance(0, true); } else { GL_state.ClipDistance(0, false); } } uint32_t array_index; if ( Current_shader->flags & SDR_FLAG_MODEL_DIFFUSE_MAP ) { Current_shader->program->Uniforms.setUniformi("sBasemap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_BASE_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_GLOW_MAP ) { Current_shader->program->Uniforms.setUniformi("sGlowmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_GLOW_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_SPEC_MAP ) { Current_shader->program->Uniforms.setUniformi("sSpecmap", render_pass); if ( material_info->get_texture_map(TM_SPEC_GLOSS_TYPE) > 0 ) { gr_opengl_tcache_set(material_info->get_texture_map(TM_SPEC_GLOSS_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); } else { gr_opengl_tcache_set(material_info->get_texture_map(TM_SPECULAR_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); } ++render_pass; if ( Current_shader->flags & SDR_FLAG_MODEL_ENV_MAP ) { Current_shader->program->Uniforms.setUniformi("sEnvmap", render_pass); gr_opengl_tcache_set(ENVMAP, TCACHE_TYPE_CUBEMAP, &u_scale, &v_scale, &array_index, render_pass); Assertion(array_index == 0, "Cube map arrays are not supported yet!"); ++render_pass; } } if ( Current_shader->flags & SDR_FLAG_MODEL_NORMAL_MAP ) { Current_shader->program->Uniforms.setUniformi("sNormalmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_NORMAL_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_HEIGHT_MAP ) { Current_shader->program->Uniforms.setUniformi("sHeightmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_HEIGHT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_AMBIENT_MAP ) { Current_shader->program->Uniforms.setUniformi("sAmbientmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_AMBIENT_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_MISC_MAP ) { Current_shader->program->Uniforms.setUniformi("sMiscmap", render_pass); gr_opengl_tcache_set(material_info->get_texture_map(TM_MISC_TYPE), TCACHE_TYPE_NORMAL, &u_scale, &v_scale, &array_index, render_pass); ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_SHADOWS ) { Current_shader->program->Uniforms.setUniformi("shadow_map", render_pass); GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D_ARRAY, Shadow_map_texture); ++render_pass; // bump! } if ( Current_shader->flags & SDR_FLAG_MODEL_ANIMATED ) { Current_shader->program->Uniforms.setUniformi("sFramebuffer", render_pass); if ( Scene_framebuffer_in_frame ) { GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D, Scene_effect_texture); glDrawBuffer(GL_COLOR_ATTACHMENT0); } else { GL_state.Texture.Enable(render_pass, GL_TEXTURE_2D, Framebuffer_fallback_texture_id); } ++render_pass; } if ( Current_shader->flags & SDR_FLAG_MODEL_TRANSFORM ) { Current_shader->program->Uniforms.setUniformi("transform_tex", render_pass); GL_state.Texture.Enable(render_pass, GL_TEXTURE_BUFFER, opengl_get_transform_buffer_texture()); ++render_pass; } if ( Deferred_lighting ) { // don't blend if we're drawing to the g-buffers GL_state.SetAlphaBlendMode(ALPHA_BLEND_NONE); } }
void opengl_tnl_set_material(material* material_info, bool set_base_map, bool set_clipping) { int shader_handle = material_info->get_shader_handle(); int base_map = material_info->get_texture_map(TM_BASE_TYPE); vec4 clr = material_info->get_color(); Assert(shader_handle >= 0); opengl_shader_set_current(shader_handle); if (material_info->has_buffer_blend_modes()) { Assertion(GLAD_GL_ARB_draw_buffers_blend != 0, "Buffer blend modes are not supported at the moment! Query the capability before using this feature."); auto enable_blend = false; for (auto i = 0; i < (int) material::NUM_BUFFER_BLENDS; ++i) { auto mode = material_info->get_blend_mode(i); GL_state.SetAlphaBlendModei(i, mode); enable_blend = enable_blend || mode != ALPHA_BLEND_NONE; } GL_state.Blend(enable_blend ? GL_TRUE : GL_FALSE); } else { GL_state.SetAlphaBlendMode(material_info->get_blend_mode()); } GL_state.SetZbufferType(material_info->get_depth_mode()); gr_set_cull(material_info->get_cull_mode() ? 1 : 0); gr_zbias(material_info->get_depth_bias()); gr_set_fill_mode(material_info->get_fill_mode()); gr_set_texture_addressing(material_info->get_texture_addressing()); if (set_clipping) { // Only set the clipping state if explicitly requested by the caller to avoid unnecessary state changes auto& clip_params = material_info->get_clip_plane(); if (!clip_params.enabled) { GL_state.ClipDistance(0, false); } else { Assertion(Current_shader != NULL && (Current_shader->shader == SDR_TYPE_MODEL || Current_shader->shader == SDR_TYPE_PASSTHROUGH_RENDER || Current_shader->shader == SDR_TYPE_DEFAULT_MATERIAL), "Clip planes are not supported by this shader!"); GL_state.ClipDistance(0, true); } } GL_state.StencilMask(material_info->get_stencil_mask()); auto& stencilFunc = material_info->get_stencil_func(); GL_state.StencilFunc(convertComparisionFunction(stencilFunc.compare), stencilFunc.ref, stencilFunc.mask); auto& frontStencilOp = material_info->get_front_stencil_op(); GL_state.StencilOpSeparate(GL_FRONT, convertStencilOp(frontStencilOp.stencilFailOperation), convertStencilOp(frontStencilOp.depthFailOperation), convertStencilOp(frontStencilOp.successOperation)); auto& backStencilOp = material_info->get_back_stencil_op(); GL_state.StencilOpSeparate(GL_BACK, convertStencilOp(backStencilOp.stencilFailOperation), convertStencilOp(backStencilOp.depthFailOperation), convertStencilOp(backStencilOp.successOperation)); GL_state.StencilTest(material_info->is_stencil_enabled() ? GL_TRUE : GL_FALSE); auto& color_mask = material_info->get_color_mask(); GL_state.ColorMask(color_mask.x, color_mask.y, color_mask.z, color_mask.w); // This is only needed for the passthrough shader uint32_t array_index = 0; if ( set_base_map && base_map >= 0 ) { float u_scale, v_scale; if ( !gr_opengl_tcache_set(base_map, material_info->get_texture_type(), &u_scale, &v_scale, &array_index) ) { mprintf(("WARNING: Error setting bitmap texture (%i)!\n", base_map)); } } if ( Current_shader->shader == SDR_TYPE_DEFAULT_MATERIAL ) { opengl_shader_set_default_material(base_map >= 0, material_info->get_texture_type() == TCACHE_TYPE_AABITMAP, &clr, material_info->get_color_scale(), array_index, material_info->get_clip_plane()); } }