-
- static const char* drawTypes[] = {
- "NDT_NORMAL",
- "NDT_AIRLIKE",
- "NDT_LIQUID",
- "NDT_FLOWINGLIQUID",
- "NDT_GLASSLIKE",
- "NDT_ALLFACES",
- "NDT_ALLFACES_OPTIONAL",
- "NDT_TORCHLIKE",
- "NDT_SIGNLIKE",
- "NDT_PLANTLIKE",
- "NDT_FENCELIKE",
- "NDT_RAILLIKE",
- "NDT_NODEBOX",
- "NDT_GLASSLIKE_FRAMED",
- "NDT_FIRELIKE",
- "NDT_GLASSLIKE_FRAMED_OPTIONAL",
- "NDT_PLANTLIKE_ROOTED",
- };
-
- for (int i = 0; i < 14; i++){
- shaders_header += "#define ";
- shaders_header += drawTypes[i];
- shaders_header += " ";
- shaders_header += itos(i);
- shaders_header += "\n";
- }
-
- static const char* materialTypes[] = {
- "TILE_MATERIAL_BASIC",
- "TILE_MATERIAL_ALPHA",
- "TILE_MATERIAL_LIQUID_TRANSPARENT",
- "TILE_MATERIAL_LIQUID_OPAQUE",
- "TILE_MATERIAL_WAVING_LEAVES",
- "TILE_MATERIAL_WAVING_PLANTS",
- "TILE_MATERIAL_OPAQUE",
- "TILE_MATERIAL_WAVING_LIQUID_BASIC",
- "TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT",
- "TILE_MATERIAL_WAVING_LIQUID_OPAQUE",
- "TILE_MATERIAL_PLAIN",
- "TILE_MATERIAL_PLAIN_ALPHA",
- };
-
- for (int i = 0; i < 12; i++){
- shaders_header += "#define ";
- shaders_header += materialTypes[i];
- shaders_header += " ";
- shaders_header += itos(i);
- shaders_header += "\n";
- }
-
- shaders_header += "#define MATERIAL_TYPE ";
- shaders_header += itos(material_type);
- shaders_header += "\n";
- shaders_header += "#define DRAW_TYPE ";
- shaders_header += itos(drawtype);
- shaders_header += "\n";
-
- if (g_settings->getBool("generate_normalmaps")) {
- shaders_header += "#define GENERATE_NORMALMAPS 1\n";
- } else {
- shaders_header += "#define GENERATE_NORMALMAPS 0\n";
- }
- shaders_header += "#define NORMALMAPS_STRENGTH ";
- shaders_header += ftos(g_settings->getFloat("normalmaps_strength"));
- shaders_header += "\n";
- float sample_step;
- int smooth = (int)g_settings->getFloat("normalmaps_smooth");
- switch (smooth){
- case 0:
- sample_step = 0.0078125; // 1.0 / 128.0
- break;
- case 1:
- sample_step = 0.00390625; // 1.0 / 256.0
- break;
- case 2:
- sample_step = 0.001953125; // 1.0 / 512.0
- break;
- default:
- sample_step = 0.0078125;
- break;
- }
- shaders_header += "#define SAMPLE_STEP ";
- shaders_header += ftos(sample_step);
- shaders_header += "\n";
-
- if (g_settings->getBool("enable_bumpmapping"))
- shaders_header += "#define ENABLE_BUMPMAPPING\n";
-
- if (g_settings->getBool("enable_parallax_occlusion")){
- int mode = g_settings->getFloat("parallax_occlusion_mode");
- float scale = g_settings->getFloat("parallax_occlusion_scale");
- float bias = g_settings->getFloat("parallax_occlusion_bias");
- int iterations = g_settings->getFloat("parallax_occlusion_iterations");
- shaders_header += "#define ENABLE_PARALLAX_OCCLUSION\n";
- shaders_header += "#define PARALLAX_OCCLUSION_MODE ";
- shaders_header += itos(mode);
- shaders_header += "\n";
- shaders_header += "#define PARALLAX_OCCLUSION_SCALE ";
- shaders_header += ftos(scale);
- shaders_header += "\n";
- shaders_header += "#define PARALLAX_OCCLUSION_BIAS ";
- shaders_header += ftos(bias);
- shaders_header += "\n";
- shaders_header += "#define PARALLAX_OCCLUSION_ITERATIONS ";
- shaders_header += itos(iterations);
- shaders_header += "\n";
- }
-
- shaders_header += "#define USE_NORMALMAPS ";
- if (g_settings->getBool("enable_bumpmapping") || g_settings->getBool("enable_parallax_occlusion"))
- shaders_header += "1\n";
- else
- shaders_header += "0\n";
-
- if (g_settings->getBool("enable_waving_water")){
- shaders_header += "#define ENABLE_WAVING_WATER 1\n";
- shaders_header += "#define WATER_WAVE_HEIGHT ";
- shaders_header += ftos(g_settings->getFloat("water_wave_height"));
- shaders_header += "\n";
- shaders_header += "#define WATER_WAVE_LENGTH ";
- shaders_header += ftos(g_settings->getFloat("water_wave_length"));
- shaders_header += "\n";
- shaders_header += "#define WATER_WAVE_SPEED ";
- shaders_header += ftos(g_settings->getFloat("water_wave_speed"));
- shaders_header += "\n";
- } else{
- shaders_header += "#define ENABLE_WAVING_WATER 0\n";
- }
-
- shaders_header += "#define ENABLE_WAVING_LEAVES ";
- if (g_settings->getBool("enable_waving_leaves"))
- shaders_header += "1\n";
- else
- shaders_header += "0\n";
-
- shaders_header += "#define ENABLE_WAVING_PLANTS ";
- if (g_settings->getBool("enable_waving_plants"))
- shaders_header += "1\n";
- else
- shaders_header += "0\n";
-
- if (g_settings->getBool("tone_mapping"))
- shaders_header += "#define ENABLE_TONE_MAPPING\n";
-
- shaders_header += "#define FOG_START ";
- shaders_header += ftos(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f));
- shaders_header += "\n";
-
- // Call addHighLevelShaderMaterial() or addShaderMaterial()
- const c8* vertex_program_ptr = 0;
- const c8* pixel_program_ptr = 0;
- const c8* geometry_program_ptr = 0;
- if (!vertex_program.empty()) {
- vertex_program = shaders_header + vertex_program;
- vertex_program_ptr = vertex_program.c_str();
- }
- if (!pixel_program.empty()) {
- pixel_program = shaders_header + pixel_program;
- pixel_program_ptr = pixel_program.c_str();
- }
- if (!geometry_program.empty()) {
- geometry_program = shaders_header + geometry_program;
- geometry_program_ptr = geometry_program.c_str();
- }
- ShaderCallback *cb = new ShaderCallback(setter_factories);
- s32 shadermat = -1;
- if(is_highlevel){
- infostream<<"Compiling high level shaders for "<<name<<std::endl;
- shadermat = gpu->addHighLevelShaderMaterial(
- vertex_program_ptr, // Vertex shader program
- "vertexMain", // Vertex shader entry point
- video::EVST_VS_1_1, // Vertex shader version
- pixel_program_ptr, // Pixel shader program
- "pixelMain", // Pixel shader entry point
- video::EPST_PS_1_2, // Pixel shader version
- geometry_program_ptr, // Geometry shader program
- "geometryMain", // Geometry shader entry point
- video::EGST_GS_4_0, // Geometry shader version
- scene::EPT_TRIANGLES, // Geometry shader input
- scene::EPT_TRIANGLE_STRIP, // Geometry shader output
- 0, // Support maximum number of vertices
- cb, // Set-constant callback
- shaderinfo.base_material, // Base material
- 1 // Userdata passed to callback
- );
- if(shadermat == -1){
- errorstream<<"generate_shader(): "
- "failed to generate \""<<name<<"\", "
- "addHighLevelShaderMaterial failed."
- <<std::endl;
- dumpShaderProgram(warningstream, "Vertex", vertex_program);
- dumpShaderProgram(warningstream, "Pixel", pixel_program);
- dumpShaderProgram(warningstream, "Geometry", geometry_program);
- delete cb;
- return shaderinfo;
- }
- }
- else{
- infostream<<"Compiling assembly shaders for "<<name<<std::endl;
- shadermat = gpu->addShaderMaterial(
- vertex_program_ptr, // Vertex shader program
- pixel_program_ptr, // Pixel shader program
- cb, // Set-constant callback
- shaderinfo.base_material, // Base material
- 0 // Userdata passed to callback
- );
-
- if(shadermat == -1){
- errorstream<<"generate_shader(): "
- "failed to generate \""<<name<<"\", "
- "addShaderMaterial failed."
- <<std::endl;
- dumpShaderProgram(warningstream, "Vertex", vertex_program);
- dumpShaderProgram(warningstream,"Pixel", pixel_program);
- delete cb;
- return shaderinfo;
- }
+ if (use_discard && shaderinfo.base_material != video::EMT_SOLID)
+ shaders_header << "#define USE_DISCARD 1\n";
+
+#define PROVIDE(constant) shaders_header << "#define " #constant " " << (int)constant << "\n"
+
+ PROVIDE(NDT_NORMAL);
+ PROVIDE(NDT_AIRLIKE);
+ PROVIDE(NDT_LIQUID);
+ PROVIDE(NDT_FLOWINGLIQUID);
+ PROVIDE(NDT_GLASSLIKE);
+ PROVIDE(NDT_ALLFACES);
+ PROVIDE(NDT_ALLFACES_OPTIONAL);
+ PROVIDE(NDT_TORCHLIKE);
+ PROVIDE(NDT_SIGNLIKE);
+ PROVIDE(NDT_PLANTLIKE);
+ PROVIDE(NDT_FENCELIKE);
+ PROVIDE(NDT_RAILLIKE);
+ PROVIDE(NDT_NODEBOX);
+ PROVIDE(NDT_GLASSLIKE_FRAMED);
+ PROVIDE(NDT_FIRELIKE);
+ PROVIDE(NDT_GLASSLIKE_FRAMED_OPTIONAL);
+ PROVIDE(NDT_PLANTLIKE_ROOTED);
+
+ PROVIDE(TILE_MATERIAL_BASIC);
+ PROVIDE(TILE_MATERIAL_ALPHA);
+ PROVIDE(TILE_MATERIAL_LIQUID_TRANSPARENT);
+ PROVIDE(TILE_MATERIAL_LIQUID_OPAQUE);
+ PROVIDE(TILE_MATERIAL_WAVING_LEAVES);
+ PROVIDE(TILE_MATERIAL_WAVING_PLANTS);
+ PROVIDE(TILE_MATERIAL_OPAQUE);
+ PROVIDE(TILE_MATERIAL_WAVING_LIQUID_BASIC);
+ PROVIDE(TILE_MATERIAL_WAVING_LIQUID_TRANSPARENT);
+ PROVIDE(TILE_MATERIAL_WAVING_LIQUID_OPAQUE);
+ PROVIDE(TILE_MATERIAL_PLAIN);
+ PROVIDE(TILE_MATERIAL_PLAIN_ALPHA);
+
+#undef PROVIDE
+
+ shaders_header << "#define MATERIAL_TYPE " << (int)material_type << "\n";
+ shaders_header << "#define DRAW_TYPE " << (int)drawtype << "\n";
+
+ bool enable_waving_water = g_settings->getBool("enable_waving_water");
+ shaders_header << "#define ENABLE_WAVING_WATER " << enable_waving_water << "\n";
+ if (enable_waving_water) {
+ shaders_header << "#define WATER_WAVE_HEIGHT " << g_settings->getFloat("water_wave_height") << "\n";
+ shaders_header << "#define WATER_WAVE_LENGTH " << g_settings->getFloat("water_wave_length") << "\n";
+ shaders_header << "#define WATER_WAVE_SPEED " << g_settings->getFloat("water_wave_speed") << "\n";
+ }
+
+ shaders_header << "#define ENABLE_WAVING_LEAVES " << g_settings->getBool("enable_waving_leaves") << "\n";
+ shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n";
+ shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n";
+
+ shaders_header << "#define FOG_START " << core::clamp(g_settings->getFloat("fog_start"), 0.0f, 0.99f) << "\n";
+
+ std::string common_header = shaders_header.str();
+
+ std::string vertex_shader = m_sourcecache.getOrLoad(name, "opengl_vertex.glsl");
+ std::string fragment_shader = m_sourcecache.getOrLoad(name, "opengl_fragment.glsl");
+ std::string geometry_shader = m_sourcecache.getOrLoad(name, "opengl_geometry.glsl");
+
+ vertex_shader = common_header + vertex_header + vertex_shader;
+ fragment_shader = common_header + fragment_header + fragment_shader;
+ const char *geometry_shader_ptr = nullptr; // optional
+ if (!geometry_shader.empty()) {
+ geometry_shader = common_header + geometry_header + geometry_shader;
+ geometry_shader_ptr = geometry_shader.c_str();
+ }
+
+ irr_ptr<ShaderCallback> cb{new ShaderCallback(m_setter_factories)};
+ infostream<<"Compiling high level shaders for "<<name<<std::endl;
+ s32 shadermat = gpu->addHighLevelShaderMaterial(
+ vertex_shader.c_str(), nullptr, video::EVST_VS_1_1,
+ fragment_shader.c_str(), nullptr, video::EPST_PS_1_1,
+ geometry_shader_ptr, nullptr, video::EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLES, 0,
+ cb.get(), shaderinfo.base_material, 1);
+ if (shadermat == -1) {
+ errorstream<<"generate_shader(): "
+ "failed to generate \""<<name<<"\", "
+ "addHighLevelShaderMaterial failed."
+ <<std::endl;
+ dumpShaderProgram(warningstream, "Vertex", vertex_shader);
+ dumpShaderProgram(warningstream, "Fragment", fragment_shader);
+ dumpShaderProgram(warningstream, "Geometry", geometry_shader);
+ return shaderinfo;