/** * Either return a precalculated constant value or emit code to * calculate these values dynamically in the case where material calls * are present between begin/end pairs. * * Probably want to shift this to the program compilation phase - if * we always emitted the calculation here, a smart compiler could * detect that it was constant (given a certain set of inputs), and * lift it out of the main loop. That way the programs created here * would be independent of the vertex_buffer details. */ static struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) { if (p->materials & SCENE_COLOR_BITS(side)) { struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); struct ureg material_emission = get_material(p, side, STATE_EMISSION); struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); struct ureg tmp = make_temp(p, material_diffuse); emit_op3(p, OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, material_ambient, material_emission); return tmp; } else return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side ); }
void PathVertex::compute_emitted_radiance( const ShadingContext& shading_context, TextureCache& texture_cache, Spectrum& radiance) const { assert(m_edf); // No radiance if we're too close to the light. if (m_shading_point->get_distance() < m_edf->get_light_near_start()) { radiance.set(0.0f); return; } if (const ShaderGroup* sg = get_material()->get_render_data().m_shader_group) shading_context.execute_osl_emission(*sg, *m_shading_point); // Evaluate the EDF inputs. InputEvaluator input_evaluator(texture_cache); m_edf->evaluate_inputs(input_evaluator, *m_shading_point); // Compute the emitted radiance. m_edf->evaluate( input_evaluator.data(), Vector3f(m_shading_point->get_geometric_normal()), Basis3f(m_shading_point->get_shading_basis()), Vector3f(m_outgoing.get_value()), radiance); }
void *parse_sphere(const parsing_sect_t *section, t_scene *scene) { t_sphere *sphere; t_object *object; t_vec3 position; t_material *material; float radius; vec3_set(&position, 0, 0, 0); if (section->option_count > 0) parse_vec3(section->options[0] + 1, &position); radius = 0.f; if (section->option_count > 1) radius = atof(section->options[1][1]); material = NULL; if (section->option_count > 2) material = get_material(scene, section->options[2][1]); if (material == NULL) die("Unknown material."); sphere = create_sphere(&position, radius, material); object = create_object(section->name, SPHERE, sphere); lst_push_back(scene->objects, object); return (sphere); }
static int parse_cyl_2(char **line, int *i, t_objenv objenv) { t_material *mat; if (!ft_strcmp(line[i[0]], "position")) { if (!parse_mtx_trans(line, i, &objenv.tobj->trans)) return (return_print("Error parsing cylinder position", 0)); else i[1] |= 1; } else if (!ft_strcmp(line[i[0]], "rotation")) { if (!parse_mtx_rot(line, i, &objenv.tobj->rot)) return (return_print("Error parsing cylinder rotation", 0)); } else if (!ft_strcmp(line[i[0]], "material")) { if (line[i[0] + 1] == NULL || !(ft_strlen(line[i[0] + 1]) > 0) || !(mat = get_material(objenv.env, line[++i[0]]))) return (return_print("Error parsing cylinder material", 0)); else objenv.obj->mat = mat; } return (parse_cylinder_3(line, i, (t_cylinder *)objenv.obj)); }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ static void get_material_cb(bContext *C, void *poin, void *poin2) { Scene *scene = CTX_data_scene(C); Main *bmain = CTX_data_main(C); bool not_set = true; Object *cur_object; Object *ob; Material *ma; cur_object = scene->basact ? scene->basact->object : 0; if(cur_object->actcol > 0) { ob = (Object*)cur_object; if(cur_object->totcol >= cur_object->actcol && ob->mat[cur_object->actcol - 1]) { bNodeTree *ntree = ob->mat[cur_object->actcol - 1]->nodetree; if(!ob->mat[cur_object->actcol - 1]->use_nodes) ob->mat[cur_object->actcol - 1]->use_nodes = true; if (ntree) { get_material(bmain, C, scene, ntree, (char*)poin, (int)poin2); not_set = false; } } if(not_set) { ID *id_me = cur_object->data; if (GS(id_me->name) == ID_ME) { Mesh *me = (Mesh*)id_me; if(me->totcol >= cur_object->actcol && me->mat[cur_object->actcol - 1]) { bNodeTree *ntree = me->mat[cur_object->actcol - 1]->nodetree; if(!me->mat[cur_object->actcol - 1]->use_nodes) me->mat[cur_object->actcol - 1]->use_nodes = true; if (ntree) { get_material(bmain, C, scene, ntree, (char*)poin, (int)poin2); not_set = false; } } } } } if(not_set) { ob = (Object*)cur_object; ma = BKE_material_add(bmain, DATA_("LDB Material")); ma->use_nodes = true; ma->nodetree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); assign_material(ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma); get_material(bmain, C, scene, ma->nodetree, (char*)poin, (int)poin2); } } /* get_material_cb() */
mixed get_property(string *path) { object mat; int tmp; mat = get_material(); if(path[0] == "material") if(mat) return mat -> get_property(path[1..]); else return nil;
String CPUParticles2D::get_configuration_warning() const { String warnings; CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr()); if (get_material().is_null() || (mat && !mat->get_particles_animation())) { if (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 || get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) { if (warnings != String()) warnings += "\n"; warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."); } } return warnings; }
static struct ureg get_lightprod( struct tnl_program *p, GLuint light, GLuint side, GLuint property ) { GLuint attrib = material_attrib(side, property); if (p->materials & (1<<attrib)) { struct ureg light_value = register_param3(p, STATE_LIGHT, light, property); struct ureg material_value = get_material(p, side, property); struct ureg tmp = get_temp(p); emit_op2(p, OPCODE_MUL, tmp, 0, light_value, material_value); return tmp; } else return register_param4(p, STATE_LIGHTPROD, light, side, property); }
std::shared_ptr<MeshFormatObject> MeshFormat::spawn_object(const StringIntern& s){ MeshFormatObjectData* d = &get_object_data(s); if(!d){ std::cout<<s<<" was not found\n"; return nullptr; } std::shared_ptr<MeshFormatObject> o(new MeshFormatObject(d,&file)); if(d->materials.size()) o->material=get_material(d->materials[0]); o->parent = &*spawned_nodes[d->parent]; if(!o->parent)o->parent=this; return o; }
int available_items_by_reaction_input(const reaction_input_t &input) { int result = 0; each<item_t>([&result, &input] (entity_t &e, item_t &i) { if (i.item_tag == input.tag && i.claimed == false) { bool ok = true; if (input.required_material) { if (i.material != input.required_material.get()) ok=false; } if (input.required_material_type) { if (get_material(i.material)->spawn_type != input.required_material_type.get()) ok = false; } if (ok) ++result; } }); return result; }
void OpenGLRenderer::create_material(const std::string& name, const std::string& vert_filename, const std::string& frag_filename, int pass) { ScopedContext context(context_pool, 0); Material& material = get_material(name); if (material.frag != 0 || material.vert != 0) { return; } material.pass = pass; QFile vert(vert_filename.c_str()); QFile frag(frag_filename.c_str()); if (!vert.open(QIODevice::ReadOnly) || !frag.open(QIODevice::ReadOnly)) { throw; } QByteArray vert_data = vert.readAll(); QByteArray frag_data = frag.readAll(); if (vert_data.size() == 0 || frag_data.size() == 0) { throw; } const char* vert_list[1] = {vert_data.constData()}; const char* frag_list[1] = {frag_data.constData()}; // TODO cache shader program by filename these material.vert = context.context.sso->glCreateShaderProgramv(GL_VERTEX_SHADER, 1, vert_list); material.frag = context.context.sso->glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, frag_list); context.context.gl->glUniformBlockBinding(material.vert, 0, 0); context.context.gl->glUniformBlockBinding(material.vert, 1, 1); context.context.gl->glUniformBlockBinding(material.frag, 0, 0); context.context.gl->glUniformBlockBinding(material.frag, 1, 3); // TODO convert to one ssbo? context.context.gl->glGenBuffers(1, &material.frag_params); context.context.gl->glBindBuffer(GL_UNIFORM_BUFFER, material.frag_params); context.context.gl->glBufferData(GL_UNIFORM_BUFFER, 65536, nullptr, GL_DYNAMIC_DRAW); material.total_objects = 0; }
const char* set_scene_node_material(const char *node,const char *mat ) { material_t *matPtr; scene_node_t *nodePtr; if ( get_scene_node( node, &nodePtr ) != TCL_OK ) { return "No such node"; } if ( get_material( mat, &matPtr ) != TCL_OK ) { return "No such material"; } nodePtr->mat = matPtr; return NULL; }
std::size_t claim_item_by_reaction_input(const reaction_input_t &input) { std::size_t result = 0; each<item_t>([&result, &input] (entity_t &e, item_t &i) { if (i.item_tag == input.tag && i.claimed == false) { bool ok = true; if (input.required_material) { if (i.material != input.required_material.get()) ok=false; } if (input.required_material_type) { if (get_material(i.material)->spawn_type != input.required_material_type.get()) ok = false; } if (ok) result = e.id; } }); if (result != 0) { emit(item_claimed_message{result, true}); } return result; }
void set_scene_node_material(const std::string& node, const std::string& mat) { SceneNode *nodePtr; if(get_scene_node(node, &nodePtr) != true){ PP_WARNING("No such node"); return; } ppogl::Material *matPtr; if(get_material( mat, &matPtr ) != true){ PP_WARNING("No such material"); return; } nodePtr->mat = matPtr; }
int calc_ldim() { object mat; if(ldim >= 0) return ldim; if(mat = get_material()) { if(capacity >= 0) return ((int)( exp( log( (float)(capacity + 1000000*calc_mass()/mat->get_density()) )/3.0 ) )); else return ((int)( exp( log( (float)(1000000*calc_mass()/mat->get_density()) )/3.0 ) )); } }
ArcballHelper ArcballHelper::create(gst::ProgramPool & programs) { auto camera = std::unique_ptr<gst::Camera>(new gst::OrthoCamera()); auto eye = std::make_shared<gst::CameraNode>(std::move(camera)); auto create_model_node = [&programs]() { auto basic_program = programs.create(BASIC_VS, BASIC_FS); auto basic_pass = std::make_shared<gst::BasicPass>(basic_program); auto vertex_array = std::make_shared<gst::VertexArrayImpl>(); auto mesh = gst::Mesh(vertex_array); auto material = gst::Material::create_free(); auto model = gst::Model(mesh, material, basic_pass); return std::make_shared<gst::ModelNode>(model); }; auto result_node = create_model_node(); result_node->get_mesh().set_draw_mode(gst::DrawMode::LINE_STRIP); auto rim_node = create_model_node(); rim_node->get_mesh().set_draw_mode(gst::DrawMode::LINE_LOOP); rim_node->get_material().get_uniform("opacity") = 0.4f; rim_node->get_pass().set_blend_mode(gst::BlendMode::INTERPOLATIVE); auto drag_node = create_model_node(); drag_node->get_mesh().set_draw_mode(gst::DrawMode::LINE_STRIP); ConstraintNodes constraint_nodes; for (int i = 0; i < 3; i++) { constraint_nodes[i] = create_model_node(); constraint_nodes[i]->get_mesh().set_draw_mode(gst::DrawMode::LINE_STRIP); constraint_nodes[i]->get_pass().set_blend_mode(gst::BlendMode::INTERPOLATIVE); } return ArcballHelper(eye, drag_node, rim_node, result_node, constraint_nodes); }
t_script_material_quantity::t_result t_script_material_quantity::evaluate(t_expression_context_global const& context) const { t_player const* player = select_player_by_target(get_target(), context.map, NULL, NULL, NULL); return player ? (player->get_funds())[get_material()] : 0; }
/* Need to add some addtional parameters to allow lighting in object * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye * space lighting. */ static void build_lighting( struct tnl_program *p ) { const GLboolean twoside = p->state->light_twoside; const GLboolean separate = p->state->separate_specular; GLuint nr_lights = 0, count = 0; struct ureg normal = get_transformed_normal(p); struct ureg lit = get_temp(p); struct ureg dots = get_temp(p); struct ureg _col0 = undef, _col1 = undef; struct ureg _bfc0 = undef, _bfc1 = undef; GLuint i; /* * NOTE: * dots.x = dot(normal, VPpli) * dots.y = dot(normal, halfAngle) * dots.z = back.shininess * dots.w = front.shininess */ for (i = 0; i < MAX_LIGHTS; i++) if (p->state->unit[i].light_enabled) nr_lights++; set_material_flags(p); { if (!p->state->material_shininess_is_zero) { struct ureg shininess = get_material(p, 0, STATE_SHININESS); emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); release_temp(p, shininess); } _col0 = make_temp(p, get_scenecolor(p, 0)); if (separate) _col1 = make_temp(p, get_identity_param(p)); else _col1 = _col0; } if (twoside) { if (!p->state->material_shininess_is_zero) { /* Note that we negate the back-face specular exponent here. * The negation will be un-done later in the back-face code below. */ struct ureg shininess = get_material(p, 1, STATE_SHININESS); emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, negate(swizzle1(shininess,X))); release_temp(p, shininess); } _bfc0 = make_temp(p, get_scenecolor(p, 1)); if (separate) _bfc1 = make_temp(p, get_identity_param(p)); else _bfc1 = _bfc0; } /* If no lights, still need to emit the scenecolor. */ { struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); emit_op1(p, OPCODE_MOV, res0, 0, _col0); } if (separate) { struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); emit_op1(p, OPCODE_MOV, res1, 0, _col1); } if (twoside) { struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); } if (twoside && separate) { struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); } if (nr_lights == 0) { release_temps(p); return; } for (i = 0; i < MAX_LIGHTS; i++) { if (p->state->unit[i].light_enabled) { struct ureg half = undef; struct ureg att = undef, VPpli = undef; count++; if (p->state->unit[i].light_eyepos3_is_zero) { /* Can used precomputed constants in this case. * Attenuation never applies to infinite lights. */ VPpli = register_param3(p, STATE_INTERNAL, STATE_LIGHT_POSITION_NORMALIZED, i); if (!p->state->material_shininess_is_zero) { if (p->state->light_local_viewer) { struct ureg eye_hat = get_eye_position_normalized(p); half = get_temp(p); emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); emit_normalize_vec3(p, half, half); } else { half = register_param3(p, STATE_INTERNAL, STATE_LIGHT_HALF_VECTOR, i); } } } else { struct ureg Ppli = register_param3(p, STATE_INTERNAL, STATE_LIGHT_POSITION, i); struct ureg V = get_eye_position(p); struct ureg dist = get_temp(p); VPpli = get_temp(p); /* Calculate VPpli vector */ emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); /* Normalize VPpli. The dist value also used in * attenuation below. */ emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli); emit_op1(p, OPCODE_RSQ, dist, 0, dist); emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist); /* Calculate attenuation: */ if (!p->state->unit[i].light_spotcutoff_is_180 || p->state->unit[i].light_attenuated) { att = calculate_light_attenuation(p, i, VPpli, dist); } /* Calculate viewer direction, or use infinite viewer: */ if (!p->state->material_shininess_is_zero) { half = get_temp(p); if (p->state->light_local_viewer) { struct ureg eye_hat = get_eye_position_normalized(p); emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); } else { struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir); } emit_normalize_vec3(p, half, half); } release_temp(p, dist); } /* Calculate dot products: */ if (p->state->material_shininess_is_zero) { emit_op2(p, OPCODE_DP3, dots, 0, normal, VPpli); } else { emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); } /* Front face lighting: */ { struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); struct ureg res0, res1; GLuint mask0, mask1; if (count == nr_lights) { if (separate) { mask0 = WRITEMASK_XYZ; mask1 = WRITEMASK_XYZ; res0 = register_output( p, VERT_RESULT_COL0 ); res1 = register_output( p, VERT_RESULT_COL1 ); } else { mask0 = 0; mask1 = WRITEMASK_XYZ; res0 = _col0; res1 = register_output( p, VERT_RESULT_COL0 ); } } else { mask0 = 0; mask1 = 0; res0 = _col0; res1 = _col1; } if (!is_undef(att)) { /* light is attenuated by distance */ emit_op1(p, OPCODE_LIT, lit, 0, dots); emit_op2(p, OPCODE_MUL, lit, 0, lit, att); emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); } else if (!p->state->material_shininess_is_zero) { /* there's a non-zero specular term */ emit_op1(p, OPCODE_LIT, lit, 0, dots); emit_op2(p, OPCODE_ADD, _col0, 0, ambient, _col0); } else { /* no attenutation, no specular */ emit_degenerate_lit(p, lit, dots); emit_op2(p, OPCODE_ADD, _col0, 0, ambient, _col0); } emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0); emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1); release_temp(p, ambient); release_temp(p, diffuse); release_temp(p, specular); } /* Back face lighting: */ if (twoside) { struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); struct ureg res0, res1; GLuint mask0, mask1; if (count == nr_lights) { if (separate) { mask0 = WRITEMASK_XYZ; mask1 = WRITEMASK_XYZ; res0 = register_output( p, VERT_RESULT_BFC0 ); res1 = register_output( p, VERT_RESULT_BFC1 ); } else { mask0 = 0; mask1 = WRITEMASK_XYZ; res0 = _bfc0; res1 = register_output( p, VERT_RESULT_BFC0 ); } } else { res0 = _bfc0; res1 = _bfc1; mask0 = 0; mask1 = 0; } /* For the back face we need to negate the X and Y component * dot products. dots.Z has the negated back-face specular * exponent. We swizzle that into the W position. This * negation makes the back-face specular term positive again. */ dots = negate(swizzle(dots,X,Y,W,Z)); if (!is_undef(att)) { emit_op1(p, OPCODE_LIT, lit, 0, dots); emit_op2(p, OPCODE_MUL, lit, 0, lit, att); emit_op3(p, OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); } else if (!p->state->material_shininess_is_zero) { emit_op1(p, OPCODE_LIT, lit, 0, dots); emit_op2(p, OPCODE_ADD, _bfc0, 0, ambient, _bfc0); /**/ } else { emit_degenerate_lit(p, lit, dots); emit_op2(p, OPCODE_ADD, _bfc0, 0, ambient, _bfc0); } emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); /* restore dots to its original state for subsequent lights * by negating and swizzling again. */ dots = negate(swizzle(dots,X,Y,W,Z)); release_temp(p, ambient); release_temp(p, diffuse); release_temp(p, specular); } release_temp(p, half); release_temp(p, VPpli); release_temp(p, att); } } release_temps( p ); }
/* Need to add some addtional parameters to allow lighting in object * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye * space lighting. */ static void build_lighting( struct tnl_program *p ) { const GLboolean twoside = p->state->light_twoside; const GLboolean separate = p->state->separate_specular; GLuint nr_lights = 0, count = 0; struct ureg normal = get_eye_normal(p); struct ureg lit = get_temp(p); struct ureg dots = get_temp(p); struct ureg _col0 = undef, _col1 = undef; struct ureg _bfc0 = undef, _bfc1 = undef; GLuint i; for (i = 0; i < MAX_LIGHTS; i++) if (p->state->unit[i].light_enabled) nr_lights++; set_material_flags(p); { struct ureg shininess = get_material(p, 0, STATE_SHININESS); emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); release_temp(p, shininess); _col0 = make_temp(p, get_scenecolor(p, 0)); if (separate) _col1 = make_temp(p, get_identity_param(p)); else _col1 = _col0; } if (twoside) { struct ureg shininess = get_material(p, 1, STATE_SHININESS); emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, ureg_negate(swizzle1(shininess,X))); release_temp(p, shininess); _bfc0 = make_temp(p, get_scenecolor(p, 1)); if (separate) _bfc1 = make_temp(p, get_identity_param(p)); else _bfc1 = _bfc0; } /* If no lights, still need to emit the scenecolor. */ /* KW: changed to do this always - v1.17 "Fix lighting alpha result"? */ if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) { struct ureg res0 = register_output( p, VERT_RESULT_COL0 ); emit_op1(p, OPCODE_MOV, res0, 0, _col0); if (twoside) { struct ureg res0 = register_output( p, VERT_RESULT_BFC0 ); emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); } } if (separate && (p->state->fragprog_inputs_read & FRAG_BIT_COL1)) { struct ureg res1 = register_output( p, VERT_RESULT_COL1 ); emit_op1(p, OPCODE_MOV, res1, 0, _col1); if (twoside) { struct ureg res1 = register_output( p, VERT_RESULT_BFC1 ); emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); } } if (nr_lights == 0) { release_temps(p); return; } for (i = 0; i < MAX_LIGHTS; i++) { if (p->state->unit[i].light_enabled) { struct ureg half = undef; struct ureg att = undef, VPpli = undef; count++; if (p->state->unit[i].light_eyepos3_is_zero) { /* Can used precomputed constants in this case. * Attenuation never applies to infinite lights. */ VPpli = register_param3(p, STATE_LIGHT, i, STATE_POSITION_NORMALIZED); if (p->state->light_local_viewer) { struct ureg eye_hat = get_eye_position_normalized(p); half = get_temp(p); emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); emit_normalize_vec3(p, half, half); } else { half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR); } } else { struct ureg Ppli = register_param3(p, STATE_LIGHT, i, STATE_POSITION); struct ureg V = get_eye_position(p); struct ureg dist = get_temp(p); VPpli = get_temp(p); half = get_temp(p); /* Calulate VPpli vector */ emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); /* Normalize VPpli. The dist value also used in * attenuation below. */ emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli); emit_op1(p, OPCODE_RSQ, dist, 0, dist); emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist); /* Calculate attenuation: */ if (!p->state->unit[i].light_spotcutoff_is_180 || p->state->unit[i].light_attenuated) { att = calculate_light_attenuation(p, i, VPpli, dist); } /* Calculate viewer direction, or use infinite viewer: */ if (p->state->light_local_viewer) { struct ureg eye_hat = get_eye_position_normalized(p); emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); } else { struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir); } emit_normalize_vec3(p, half, half); release_temp(p, dist); } /* Calculate dot products: */ emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); /* Front face lighting: */ { struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT); struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE); struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR); struct ureg res0, res1; GLuint mask0, mask1; emit_op1(p, OPCODE_LIT, lit, 0, dots); if (!is_undef(att)) emit_op2(p, OPCODE_MUL, lit, 0, lit, att); mask0 = 0; mask1 = 0; res0 = _col0; res1 = _col1; if (count == nr_lights) { if (separate) { mask0 = WRITEMASK_XYZ; mask1 = WRITEMASK_XYZ; if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) res0 = register_output( p, VERT_RESULT_COL0 ); if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) res1 = register_output( p, VERT_RESULT_COL1 ); } else { mask1 = WRITEMASK_XYZ; if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) res1 = register_output( p, VERT_RESULT_COL0 ); } } emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0); emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1); release_temp(p, ambient); release_temp(p, diffuse); release_temp(p, specular); } /* Back face lighting: */ if (twoside) { struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT); struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE); struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR); struct ureg res0, res1; GLuint mask0, mask1; emit_op1(p, OPCODE_LIT, lit, 0, ureg_negate(swizzle(dots,X,Y,W,Z))); if (!is_undef(att)) emit_op2(p, OPCODE_MUL, lit, 0, lit, att); mask0 = 0; mask1 = 0; res0 = _bfc0; res1 = _bfc1; if (count == nr_lights) { if (separate) { mask0 = WRITEMASK_XYZ; mask1 = WRITEMASK_XYZ; if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) res0 = register_output( p, VERT_RESULT_BFC0 ); if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) res1 = register_output( p, VERT_RESULT_BFC1 ); } else { mask1 = WRITEMASK_XYZ; if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) res1 = register_output( p, VERT_RESULT_BFC0 ); } } emit_op3(p, OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); release_temp(p, ambient); release_temp(p, diffuse); release_temp(p, specular); } release_temp(p, half); release_temp(p, VPpli); release_temp(p, att); } } release_temps( p ); }
int Creature::deal_projectile_attack(Creature *source, double missed_by, const projectile &proj, dealt_damage_instance &dealt_dam) { bool u_see_this = g->u_see(this); body_part bp_hit; int side = rng(0, 1); // do 10,speed because speed could potentially be > 10000 if (dodge_roll() >= dice(10, proj.speed)) { if (is_player()) add_msg(_("You dodge %s projectile!"), source->disp_name(true).c_str()); else if (u_see_this) add_msg(_("%s dodges %s projectile."), disp_name().c_str(), source->disp_name(true).c_str()); return 0; } // Bounce applies whether it does damage or not. if (proj.proj_effects.count("BOUNCE")) { add_effect("bounced", 1); } double hit_value = missed_by + rng_float(-0.5, 0.5); // headshots considered elsewhere if (hit_value <= 0.4) { bp_hit = bp_torso; } else if (one_in(4)) { bp_hit = bp_legs; } else { bp_hit = bp_arms; } double monster_speed_penalty = std::max(double(get_speed()) / 80., 1.0); double goodhit = missed_by / monster_speed_penalty; double damage_mult = 1.0; std::string message = ""; game_message_type gmtSCTcolor = m_neutral; if (goodhit <= .1) { message = _("Headshot!"); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_headshot; damage_mult *= rng_float(2.45, 3.35); bp_hit = bp_head; // headshot hits the head, of course } else if (goodhit <= .2) { message = _("Critical!"); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_critical; damage_mult *= rng_float(1.75, 2.3); } else if (goodhit <= .4) { message = _("Good hit!"); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_good; damage_mult *= rng_float(1, 1.5); } else if (goodhit <= .6) { damage_mult *= rng_float(0.5, 1); } else if (goodhit <= .8) { message = _("Grazing hit."); source->add_msg_if_player(m_good, message.c_str()); gmtSCTcolor = m_grazing; damage_mult *= rng_float(0, .25); } else { damage_mult *= 0; } // copy it, since we're mutating damage_instance impact = proj.impact; if( item(proj.ammo->id, 0).has_flag("NOGIB") ) { impact.add_effect("NOGIB"); } impact.mult_damage(damage_mult); dealt_dam = deal_damage(source, bp_hit, side, impact); dealt_dam.bp_hit = bp_hit; // Apply ammo effects to target. const std::string target_material = get_material(); if (proj.proj_effects.count("FLAME")) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood" ) ) { add_effect("onfire", rng(8, 20)); } else if (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) { add_effect("onfire", rng(5, 10)); } } else if (proj.proj_effects.count("INCENDIARY") ) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood") ) { add_effect("onfire", rng(2, 6)); } else if ( (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) && one_in(4) ) { add_effect("onfire", rng(1, 4)); } } else if (proj.proj_effects.count("IGNITE")) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood") ) { add_effect("onfire", rng(6, 6)); } else if (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) { add_effect("onfire", rng(10, 10)); } } int stun_strength = 0; if (proj.proj_effects.count("BEANBAG")) { stun_strength = 4; } if(proj.proj_effects.count("WHIP")) { stun_strength = rng(4, 10); } if (proj.proj_effects.count("LARGE_BEANBAG")) { stun_strength = 16; } if( stun_strength > 0 ) { switch( get_size() ) { case MS_TINY: stun_strength *= 4; break; case MS_SMALL: stun_strength *= 2; break; case MS_MEDIUM: default: break; case MS_LARGE: stun_strength /= 2; break; case MS_HUGE: stun_strength /= 4; break; } add_effect( "stunned", rng(stun_strength / 2, stun_strength) ); } if(u_see_this) { if (damage_mult == 0) { if(source != NULL) { add_msg(source->is_player() ? _("You miss!") : _("The shot misses!")); } } else if (dealt_dam.total_damage() == 0) { add_msg(_("The shot reflects off %s %s!"), disp_name(true).c_str(), skin_name().c_str()); } else if (source != NULL) { if (source->is_player()) { //player hits monster ranged nc_color color; std::string health_bar = ""; get_HP_Bar(dealt_dam.total_damage(), this->get_hp_max(), color, health_bar, true); SCT.add(this->xpos(), this->ypos(), direction_from(0, 0, this->xpos() - source->xpos(), this->ypos() - source->ypos()), health_bar, m_good, message, gmtSCTcolor); if (this->get_hp() > 0) { get_HP_Bar(this->get_hp(), this->get_hp_max(), color, health_bar, true); SCT.add(this->xpos(), this->ypos(), direction_from(0, 0, this->xpos() - source->xpos(), this->ypos() - source->ypos()), health_bar, m_good, "hp", m_neutral, "hp"); } else { SCT.removeCreatureHP(); } add_msg(m_good, _("You hit the %s for %d damage."), disp_name().c_str(), dealt_dam.total_damage()); } else if(this->is_player()) { //monster hits player ranged add_msg_if_player( m_bad, _( "You were hit in the %s for %d damage." ), body_part_name( bp_hit, side ).c_str( ), dealt_dam.total_damage( ) ); } else if( u_see_this ) { add_msg(_("%s shoots %s."), source->disp_name().c_str(), disp_name().c_str()); } } } return 0; }
void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { CSGShape *cs = Object::cast_to<CSGShape>(p_gizmo->get_spatial_node()); p_gizmo->clear(); Ref<Material> material = get_material("shape_material", p_gizmo); Ref<Material> handles_material = get_material("handles"); PoolVector<Vector3> faces = cs->get_brush_faces(); Vector<Vector3> lines; lines.resize(faces.size() * 2); { PoolVector<Vector3>::Read r = faces.read(); for (int i = 0; i < lines.size(); i += 6) { int f = i / 6; for (int j = 0; j < 3; j++) { int j_n = (j + 1) % 3; lines.write[i + j * 2 + 0] = r[f * 3 + j]; lines.write[i + j * 2 + 1] = r[f * 3 + j_n]; } } } p_gizmo->add_lines(lines, material); p_gizmo->add_collision_segments(lines); if (Object::cast_to<CSGSphere>(cs)) { CSGSphere *s = Object::cast_to<CSGSphere>(cs); float r = s->get_radius(); Vector<Vector3> handles; handles.push_back(Vector3(r, 0, 0)); p_gizmo->add_handles(handles, handles_material); } if (Object::cast_to<CSGBox>(cs)) { CSGBox *s = Object::cast_to<CSGBox>(cs); Vector<Vector3> handles; handles.push_back(Vector3(s->get_width() * 0.5, 0, 0)); handles.push_back(Vector3(0, s->get_height() * 0.5, 0)); handles.push_back(Vector3(0, 0, s->get_depth() * 0.5)); p_gizmo->add_handles(handles, handles_material); } if (Object::cast_to<CSGCylinder>(cs)) { CSGCylinder *s = Object::cast_to<CSGCylinder>(cs); Vector<Vector3> handles; handles.push_back(Vector3(s->get_radius(), 0, 0)); handles.push_back(Vector3(0, s->get_height() * 0.5, 0)); p_gizmo->add_handles(handles, handles_material); } if (Object::cast_to<CSGTorus>(cs)) { CSGTorus *s = Object::cast_to<CSGTorus>(cs); Vector<Vector3> handles; handles.push_back(Vector3(s->get_inner_radius(), 0, 0)); handles.push_back(Vector3(s->get_outer_radius(), 0, 0)); p_gizmo->add_handles(handles, handles_material); } }
void LowQualitySplattingSubRenderer:: render_sub_pass(Pipeline& pipe, PipelinePassDescription const& desc, gua::plod_shared_resources& shared_resources, std::vector<node::Node*>& sorted_models, std::unordered_map<node::PLodNode*, std::unordered_set<lamure::node_t> >& nodes_in_frustum_per_model, lamure::context_t context_id, lamure::view_t lamure_view_id ) { auto const& camera = pipe.current_viewstate().camera; RenderContext const& ctx(pipe.get_context()); auto& target = *pipe.current_viewstate().target; scm::gl::context_all_guard context_guard(ctx.render_context); ctx.render_context->set_rasterizer_state(no_backface_culling_rasterizer_state_); bool write_depth = true; target.bind(ctx, write_depth); target.set_viewport(ctx); MaterialShader* current_material(nullptr); std::shared_ptr<ShaderProgram> current_material_program; bool program_changed = false; std::string const gpu_query_name_depth_pass = "******" + std::to_string(pipe.current_viewstate().viewpoint_uuid) + " / PLodRenderer::DepthPass"; pipe.begin_gpu_query(ctx, gpu_query_name_depth_pass); int view_id(camera.config.get_view_id()); //loop through all models and render depth pass for (auto const& object : sorted_models) { auto plod_node(reinterpret_cast<node::PLodNode*>(object)); current_material = plod_node->get_material()->get_shader(); current_material_program = _get_material_dependent_shader_program(current_material, current_material_program, program_changed); lamure::ren::controller* controller = lamure::ren::controller::get_instance(); lamure::model_t model_id = controller->deduce_model_id(plod_node->get_geometry_description()); std::unordered_set<lamure::node_t>& nodes_in_frustum = nodes_in_frustum_per_model[plod_node]; auto const& plod_resource = plod_node->get_geometry(); if (plod_resource && current_material_program) { if (program_changed) { current_material_program->unuse(ctx); current_material_program->use(ctx); current_material_program->set_uniform(ctx, target.get_depth_buffer()->get_handle(ctx), "gua_gbuffer_depth"); } plod_node->get_material()->apply_uniforms(ctx, current_material_program.get(), view_id); _upload_model_dependent_uniforms(current_material_program, ctx, plod_node, pipe); ctx.render_context->apply(); plod_resource->draw(ctx, context_id, lamure_view_id, model_id, controller->get_context_memory(context_id, lamure::ren::bvh::primitive_type::POINTCLOUD, ctx.render_device), nodes_in_frustum, scm::gl::primitive_topology::PRIMITIVE_POINT_LIST); program_changed = false; } else { Logger::LOG_WARNING << "PLodRenderer::render(): Cannot find ressources for node: " << plod_node->get_name() << std::endl; } } target.unbind(ctx); pipe.end_gpu_query(ctx, gpu_query_name_depth_pass); }
int calc_mass() { object mat; if(mass >= 0) return mass; mat = get_material(); if(mat && ldim >= 0) return ldim*ldim*ldim /1000 * mat->get_density() / 1000; }
t_script_material_quantity::t_result t_script_material_quantity::evaluate(t_expression_context_army const& context) const { t_player const* player = select_player_by_target(get_target(), context.map, NULL, context.army_owner, context.opposing_army_owner); return player ? (player->get_funds())[get_material()] : 0; }
void SPointsRenderer::render(Pipeline& pipe, PipelinePassDescription const& desc) { /////////////////////////////////////////////////////////////////////////// // retrieve current view state /////////////////////////////////////////////////////////////////////////// auto& scene = *pipe.current_viewstate().scene; auto const& camera = pipe.current_viewstate().camera; // auto const& frustum = pipe.current_viewstate().frustum; auto& target = *pipe.current_viewstate().target; auto const& ctx(pipe.get_context()); if (!initialized_) { initialized_ = true; points_rasterizer_state_ = ctx.render_device ->create_rasterizer_state(scm::gl::FILL_SOLID, scm::gl::CULL_NONE, scm::gl::ORIENT_CCW, false, false, 0.0, false, false, scm::gl::point_raster_state(true)); } auto objects(scene.nodes.find(std::type_index(typeid(node::SPointsNode)))); int view_id(camera.config.get_view_id()); if (objects != scene.nodes.end() && objects->second.size() > 0) { float last_known_point_size = std::numeric_limits<float>::max(); for (auto& o : objects->second) { auto spoints_node(reinterpret_cast<node::SPointsNode*>(o)); auto spoints_desc(spoints_node->get_spoints_description()); if (!GeometryDatabase::instance()->contains(spoints_desc)) { gua::Logger::LOG_WARNING << "SPointsRenderer::draw(): No such spoints." << spoints_desc << ", " << std::endl; continue; } auto spoints_resource = std::static_pointer_cast<SPointsResource>( GeometryDatabase::instance()->lookup(spoints_desc)); if (!spoints_resource) { gua::Logger::LOG_WARNING << "SPointsRenderer::draw(): Invalid spoints." << std::endl; continue; } auto const& model_matrix(spoints_node->get_cached_world_transform()); auto normal_matrix(scm::math::transpose( scm::math::inverse(spoints_node->get_cached_world_transform()))); auto view_matrix(pipe.current_viewstate().frustum.get_view()); scm::math::mat4f mv_matrix = scm::math::mat4f(view_matrix) * scm::math::mat4f(model_matrix); scm::math::mat4f projection_matrix = scm::math::mat4f(pipe.current_viewstate().frustum.get_projection()); const float scaling = scm::math::length( (model_matrix * view_matrix) * scm::math::vec4d(1.0, 0.0, 0.0, 0.0)); spoints::matrix_package current_package; memcpy((char*) ¤t_package, (char*) mv_matrix.data_array, 16 * sizeof(float) ); memcpy( ((char*) ¤t_package) + 16 * sizeof(float), (char*) projection_matrix.data_array, 16 * sizeof(float) ); scm::math::vec2ui const& render_target_dims = camera.config.get_resolution(); current_package.res_xy[0] = render_target_dims.x; current_package.res_xy[1] = render_target_dims.y; auto camera_id = pipe.current_viewstate().viewpoint_uuid; //auto view_direction = pipe.current_viewstate().view_direction; //std::size_t gua_view_id = (camera_id << 8) | (std::size_t(view_direction)); bool is_camera = (!pipe.current_viewstate().shadow_mode); bool stereo_mode = (pipe.current_viewstate().camera.config.get_enable_stereo()); std::size_t view_uuid = camera_id; spoints::camera_matrix_package cm_package; cm_package.k_package.is_camera = is_camera; cm_package.k_package.view_uuid = view_uuid; cm_package.k_package.stereo_mode = stereo_mode; cm_package.k_package.framecount = pipe.get_context().framecount; cm_package.k_package.render_context_id = pipe.get_context().id; cm_package.mat_package = current_package; spoints_resource->push_matrix_package(cm_package); spoints_resource->update_buffers(pipe.get_context(), pipe); //auto const& spoints_data = spointsdata_[spoints_resource->uuid()]; // get material dependent shader std::shared_ptr<ShaderProgram> current_shader; MaterialShader* current_material = spoints_node->get_material()->get_shader(); if (current_material) { auto shader_iterator = programs_.find(current_material); if (shader_iterator != programs_.end()) { current_shader = shader_iterator->second; } else { auto smap = global_substitution_map_; for (const auto& i : current_material->generate_substitution_map()) smap[i.first] = i.second; current_shader = std::make_shared<ShaderProgram>(); current_shader->set_shaders( program_stages_, std::list<std::string>(), false, smap); programs_[current_material] = current_shader; } } else { Logger::LOG_WARNING << "SPointsPass::render(): Cannot find material: " << spoints_node->get_material()->get_shader_name() << std::endl; } current_shader->use(ctx); current_shader->set_uniform( ctx, scm::math::mat4f(model_matrix), "kinect_model_matrix"); float const screen_space_point_size = spoints_node->get_screen_space_point_size(); current_shader->set_uniform( ctx, screen_space_point_size, "point_size"); bool write_depth = true; target.bind(ctx, write_depth); target.set_viewport(ctx); ctx.render_context->set_rasterizer_state(points_rasterizer_state_); ctx.render_context->apply(); spoints_resource->draw(ctx); target.unbind(ctx); } } }
void ces_render_system::draw_recursively_lights(const ces_entity_shared_ptr& entity, const std::string &technique_name, i32 technique_pass) { ces_scene_component *scene_component = unsafe_get_scene_component(entity); assert(scene_component); if(!scene_component) { return; } glm::vec4 game_object_bound = ces_geometry_extension::get_absolute_bound(entity); glm::vec4 camera_bound = scene_component->get_camera()->bound; bool is_in_frustum = glm::intersect(game_object_bound, camera_bound); ces_light_compoment *light_component = unsafe_get_light_component(entity); if(light_component && is_in_frustum) { ces_material_component* material_component = unsafe_get_material_component(entity); ces_geometry_component* geometry_component = unsafe_get_geometry_component(entity); ces_transformation_component* transformation_component = unsafe_get_transformation_component(entity); ces_light_mask_component* light_mask_component = unsafe_get_light_mask_component(entity); if(material_component && geometry_component && transformation_component) { material_shared_ptr material = material_component->get_material(technique_name, technique_pass); mesh_shared_ptr light_main_mesh = geometry_component->get_mesh(); mesh_shared_ptr light_mask_mesh = light_mask_component->get_mask_mesh(); mesh_shared_ptr screed_quad_mesh = mesh_constructor::create_screen_quad(); if(material && entity->visible && material->get_shader()->is_commited() && light_main_mesh && light_mask_mesh) { auto draw_light_mask = [=]() { gl_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); gl_depth_mask(GL_FALSE); material->set_stencil_function(GL_ALWAYS); material->set_stencil_function_parameter_1(1); material->set_stencil_function_parameter_2(255); material->set_stencil_mask_parameter(1); material->set_custom_shader_uniform(0, k_light_mask_vs_flag_uniform); material->set_custom_shader_uniform(1, k_light_mask_fs_flag_uniform); material_component->on_bind(technique_name, technique_pass, material); material->get_shader()->set_mat4(scene_component->get_camera()->get_mat_p(), e_shader_uniform_mat_p); material->get_shader()->set_mat4(scene_component->get_camera()->get_mat_v(), e_shader_uniform_mat_v); material->get_shader()->set_mat4(glm::mat4(1.f), e_shader_uniform_mat_m); light_mask_mesh->bind(material->get_shader()->get_guid(), material->get_shader()->get_attributes()); light_mask_mesh->draw(); light_mask_mesh->unbind(material->get_shader()->get_guid(), material->get_shader()->get_attributes()); material_component->on_unbind(technique_name, technique_pass, material); std::list<ces_entity_weak_ptr> luminous_entities = light_component->get_luminous_entities(); for(const auto& weak_luminous_entity : luminous_entities) { if(!weak_luminous_entity.expired()) { auto luminous_entity = weak_luminous_entity.lock(); auto luminous_transformation_component = luminous_entity->get_component<ces_transformation_component>(); auto luminous_geometry_component = luminous_entity->get_component<ces_geometry_component>(); auto luminous_material_component = luminous_entity->get_component<ces_material_component>(); material_shared_ptr luminous_material = luminous_material_component->get_material(technique_name, technique_pass); if(luminous_material && luminous_material->get_shader()->is_commited()) { mesh_shared_ptr luminous_mesh = luminous_geometry_component->get_mesh(); luminous_material_component->on_bind(technique_name, technique_pass, luminous_material); glm::mat4 mat_m = luminous_transformation_component->get_absolute_transformation(); luminous_material->get_shader()->set_mat4(mat_m, e_shader_uniform_mat_m); luminous_mesh->bind(luminous_material->get_shader()->get_guid(), luminous_material->get_shader()->get_attributes()); luminous_mesh->draw(); luminous_mesh->unbind(luminous_material->get_shader()->get_guid(), luminous_material->get_shader()->get_attributes()); luminous_material_component->on_unbind(technique_name, technique_pass, luminous_material); } } } gl_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); gl_depth_mask(GL_TRUE); }; auto draw_light = [=]() { glm::mat4 mat_m = transformation_component->get_absolute_transformation(); material->set_stencil_function(GL_EQUAL); material->set_stencil_function_parameter_1(1); material->set_stencil_function_parameter_2(255); material->set_stencil_mask_parameter(0); material->set_blending_function_source(GL_SRC_ALPHA); material->set_blending_function_destination(GL_ONE); material->set_custom_shader_uniform(0, k_light_mask_vs_flag_uniform); material->set_custom_shader_uniform(0, k_light_mask_fs_flag_uniform); material_component->on_bind(technique_name, technique_pass, material); material->get_shader()->set_mat4(mat_m, e_shader_uniform_mat_m); light_main_mesh->bind(material->get_shader()->get_guid(), material->get_shader()->get_attributes()); light_main_mesh->draw(); light_main_mesh->unbind(material->get_shader()->get_guid(), material->get_shader()->get_attributes()); material_component->on_unbind(technique_name, technique_pass, material); }; auto clear_light_mask = [=]() { gl_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); gl_depth_mask(GL_FALSE); material->set_stencil_function(GL_ALWAYS); material->set_stencil_function_parameter_1(0); material->set_stencil_function_parameter_2(255); material->set_stencil_mask_parameter(1); material->set_custom_shader_uniform(1, k_light_mask_vs_flag_uniform); material->set_custom_shader_uniform(1, k_light_mask_fs_flag_uniform); material_component->on_bind(technique_name, technique_pass, material); material->get_shader()->set_mat4(glm::mat4(1.f), e_shader_uniform_mat_m); screed_quad_mesh->bind(material->get_shader()->get_guid(), material->get_shader()->get_attributes()); screed_quad_mesh->draw(); screed_quad_mesh->unbind(material->get_shader()->get_guid(), material->get_shader()->get_attributes()); gl_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); gl_depth_mask(GL_TRUE); material_component->on_unbind(technique_name, technique_pass, material); }; draw_light_mask(); draw_light(); clear_light_mask(); } } } std::list<ces_entity_shared_ptr> children = entity->children; for(const auto& child : children) { ces_render_system::draw_recursively_lights(child, technique_name, technique_pass); } }
/** * Attempts to harm a creature with a projectile. * * @param source Pointer to the creature who shot the projectile. * @param attack A structure describing the attack and its results. */ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack &attack ) { const double missed_by = attack.missed_by; if( missed_by >= 1.0 ) { // Total miss return; } const projectile &proj = attack.proj; dealt_damage_instance &dealt_dam = attack.dealt_dam; const auto &proj_effects = proj.proj_effects; const bool u_see_this = g->u.sees(*this); const int avoid_roll = dodge_roll(); // Do dice(10, speed) instead of dice(speed, 10) because speed could potentially be > 10000 const int diff_roll = dice( 10, proj.speed ); // Partial dodge, capped at [0.0, 1.0], added to missed_by const double dodge_rescaled = avoid_roll / static_cast<double>( diff_roll ); const double goodhit = missed_by + std::max( 0.0, std::min( 1.0, dodge_rescaled ) ) ; if( goodhit >= 1.0 ) { // "Avoid" rather than "dodge", because it includes removing self from the line of fire // rather than just Matrix-style bullet dodging if( source != nullptr && g->u.sees( *source ) ) { add_msg_player_or_npc( m_warning, _("You avoid %s projectile!"), _("<npcname> avoids %s projectile."), source->disp_name(true).c_str() ); } else { add_msg_player_or_npc( m_warning, _("You avoid an incoming projectile!"), _("<npcname> avoids an incoming projectile.") ); } attack.missed_by = 1.0; // Arbitrary value return; } // Bounce applies whether it does damage or not. if( proj.proj_effects.count( "BOUNCE" ) ) { add_effect("bounced", 1); } body_part bp_hit; double hit_value = missed_by + rng_float(-0.5, 0.5); // Headshots considered elsewhere if( hit_value <= 0.4 ) { bp_hit = bp_torso; } else if (one_in(4)) { if( one_in(2)) { bp_hit = bp_leg_l; } else { bp_hit = bp_leg_r; } } else { if( one_in(2)) { bp_hit = bp_arm_l; } else { bp_hit = bp_arm_r; } } double damage_mult = 1.0; std::string message = ""; game_message_type gmtSCTcolor = m_neutral; if( goodhit < 0.1 ) { message = _("Headshot!"); gmtSCTcolor = m_headshot; damage_mult *= rng_float(2.45, 3.35); bp_hit = bp_head; // headshot hits the head, of course } else if( goodhit < 0.2 ) { message = _("Critical!"); gmtSCTcolor = m_critical; damage_mult *= rng_float(1.75, 2.3); } else if( goodhit < 0.4 ) { message = _("Good hit!"); gmtSCTcolor = m_good; damage_mult *= rng_float(1, 1.5); } else if( goodhit < 0.6 ) { damage_mult *= rng_float(0.5, 1); } else if( goodhit < 0.8 ) { message = _("Grazing hit."); gmtSCTcolor = m_grazing; damage_mult *= rng_float(0, .25); } else { damage_mult *= 0; } if( source != nullptr && !message.empty() ) { source->add_msg_if_player(m_good, message.c_str()); } attack.missed_by = goodhit; // copy it, since we're mutating damage_instance impact = proj.impact; if( proj_effects.count("NOGIB") > 0 ) { impact.add_effect("NOGIB"); } impact.mult_damage(damage_mult); dealt_dam = deal_damage(source, bp_hit, impact); dealt_dam.bp_hit = bp_hit; // Apply ammo effects to target. const std::string target_material = get_material(); if (proj.proj_effects.count("FLAME")) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood" ) ) { add_effect("onfire", rng(8, 20)); } else if (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) { add_effect("onfire", rng(5, 10)); } } else if (proj.proj_effects.count("INCENDIARY") ) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood") ) { add_effect("onfire", rng(2, 6)); } else if ( (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) && one_in(4) ) { add_effect("onfire", rng(1, 4)); } } else if (proj.proj_effects.count("IGNITE")) { if (0 == target_material.compare("veggy") || 0 == target_material.compare("cotton") || 0 == target_material.compare("wool") || 0 == target_material.compare("paper") || 0 == target_material.compare("wood") ) { add_effect("onfire", rng(6, 6)); } else if (0 == target_material.compare("flesh") || 0 == target_material.compare("iflesh") ) { add_effect("onfire", rng(10, 10)); } } if( bp_hit == bp_head && proj_effects.count( "BLINDS_EYES" ) ) { // TODO: Change this to require bp_eyes add_env_effect( "blind", bp_eyes, 5, rng( 3, 10 ) ); } if( proj_effects.count( "APPLY_SAP" ) ) { add_effect( "sap", dealt_dam.total_damage() ); } int stun_strength = 0; if (proj.proj_effects.count("BEANBAG")) { stun_strength = 4; } if (proj.proj_effects.count("LARGE_BEANBAG")) { stun_strength = 16; } if( stun_strength > 0 ) { switch( get_size() ) { case MS_TINY: stun_strength *= 4; break; case MS_SMALL: stun_strength *= 2; break; case MS_MEDIUM: default: break; case MS_LARGE: stun_strength /= 2; break; case MS_HUGE: stun_strength /= 4; break; } add_effect( "stunned", rng(stun_strength / 2, stun_strength) ); } if(u_see_this) { if( damage_mult == 0 ) { if( source != nullptr ) { add_msg( source->is_player() ? _("You miss!") : _("The shot misses!") ); } } else if( dealt_dam.total_damage() == 0 ) { //~ 1$ - monster name, 2$ - monster's bodypart add_msg(_("The shot reflects off %1$s %2$s!"), disp_name(true).c_str(), skin_name().c_str()); } else if( is_player() ) { //monster hits player ranged //~ Hit message. 1$s is bodypart name in accusative. 2$d is damage value. add_msg_if_player(m_bad, _( "You were hit in the %1$s for %2$d damage." ), body_part_name_accusative(bp_hit).c_str( ), dealt_dam.total_damage()); } else if( source != nullptr ) { if( source->is_player() ) { //player hits monster ranged SCT.add(posx(), posy(), direction_from(0, 0, posx() - source->posx(), posy() - source->posy()), get_hp_bar(dealt_dam.total_damage(), get_hp_max(), true).first, m_good, message, gmtSCTcolor); if (get_hp() > 0) { SCT.add(posx(), posy(), direction_from(0, 0, posx() - source->posx(), posy() - source->posy()), get_hp_bar(get_hp(), get_hp_max(), true).first, m_good, //~ "hit points", used in scrolling combat text _("hp"), m_neutral, "hp"); } else { SCT.removeCreatureHP(); } add_msg(m_good, _("You hit %s for %d damage."), disp_name().c_str(), dealt_dam.total_damage()); } else if( u_see_this ) { //~ 1$ - shooter, 2$ - target add_msg(_("%1$s shoots %2$s."), source->disp_name().c_str(), disp_name().c_str()); } } } check_dead_state(); attack.hit_critter = this; attack.missed_by = goodhit; }
/*! loads an .a2mtl material file * @param filename the materials filename */ void a2ematerial::load_material(const string& filename_) { filename = filename_; // read mat data if(!file_io::file_to_buffer(filename, buffer)) return; const string mat_data = buffer.str(); // check if we have a xml (mat) file if(mat_data.length() < 5 || mat_data.substr(0, 5) != "<?xml") { log_error("invalid a2e-material file %s!", filename); return; } xmlDoc* doc = xmlReadMemory(mat_data.c_str(), (int)mat_data.size(), nullptr, (const char*)"UTF-8", 0); xmlNode* root = xmlDocGetRootElement(doc); size_t object_count = 0; size_t object_id = 0; a2ematerial::material* cur_material = nullptr; xmlNode* cur_node = nullptr; stack<xmlNode*> node_stack; node_stack.push(root); while(!node_stack.empty()) { cur_node = node_stack.top(); node_stack.pop(); if(cur_node->next != nullptr) node_stack.push(cur_node->next); if(cur_node->type == XML_ELEMENT_NODE) { xmlElement* cur_elem = (xmlElement*)cur_node; string node_name = (const char*)cur_elem->name; if(cur_node->children != nullptr) node_stack.push(cur_node->children); if(node_name == "a2e_material") { size_t version = x->get_attribute<size_t>(cur_elem->attributes, "version"); if(version != A2E_MATERIAL_VERSION) { log_error("wrong version %u in material %s - should be %u!", version, filename, A2E_MATERIAL_VERSION); return; } object_count = x->get_attribute<size_t>(cur_elem->attributes, "object_count"); } else if(node_name == "material") { // get material info size_t id = x->get_attribute<size_t>(cur_elem->attributes, "id"); string type = x->get_attribute<string>(cur_elem->attributes, "type"); string model = x->get_attribute<string>(cur_elem->attributes, "model"); // create material materials.push_back(*new material()); cur_material = &materials.back(); cur_material->id = (ssize_t)id; cur_material->mat_type = (type == "diffuse" ? MATERIAL_TYPE::DIFFUSE : (type == "parallax" ? MATERIAL_TYPE::PARALLAX : MATERIAL_TYPE::NONE)); cur_material->lm_type = (model == "phong" ? LIGHTING_MODEL::PHONG : (model == "ashikhmin_shirley" ? LIGHTING_MODEL::ASHIKHMIN_SHIRLEY : LIGHTING_MODEL::NONE)); switch(cur_material->mat_type) { case MATERIAL_TYPE::DIFFUSE: cur_material->mat = new diffuse_material(); ((diffuse_material*)cur_material->mat)->diffuse_texture = dummy_texture; ((diffuse_material*)cur_material->mat)->specular_texture = default_specular; ((diffuse_material*)cur_material->mat)->reflectance_texture = default_specular; break; case MATERIAL_TYPE::PARALLAX: cur_material->mat = new parallax_material(); ((parallax_material*)cur_material->mat)->diffuse_texture = dummy_texture; ((parallax_material*)cur_material->mat)->specular_texture = default_specular; ((parallax_material*)cur_material->mat)->reflectance_texture = default_specular; ((parallax_material*)cur_material->mat)->height_texture = dummy_texture; ((parallax_material*)cur_material->mat)->normal_texture = dummy_texture; break; case MATERIAL_TYPE::NONE: cur_material->mat = new material_object(); break; } switch(cur_material->lm_type) { case LIGHTING_MODEL::PHONG: cur_material->model = new phong_model(); break; case LIGHTING_MODEL::ASHIKHMIN_SHIRLEY: cur_material->model = new ashikhmin_shirley_model(); break; case LIGHTING_MODEL::NONE: log_error("unknown lighting model type \"%s\" (%d)!", model, cur_material->lm_type); return; } // get material data for(xmlNode* material_node = cur_node->children; material_node; material_node = material_node->next) { xmlElement* material_elem = (xmlElement*)material_node; string material_name = (const char*)material_elem->name; if(material_name == "texture") { string texture_filename = x->get_attribute<string>(material_elem->attributes, "file"); string texture_type_str = x->get_attribute<string>(material_elem->attributes, "type"); TEXTURE_TYPE texture_type = (TEXTURE_TYPE)0; if(texture_type_str == "diffuse") texture_type = TEXTURE_TYPE::DIFFUSE; else if(texture_type_str == "specular") texture_type = TEXTURE_TYPE::SPECULAR; else if(texture_type_str == "reflectance") texture_type = TEXTURE_TYPE::REFLECTANCE; else if(texture_type_str == "height") texture_type = TEXTURE_TYPE::HEIGHT; else if(texture_type_str == "normal") texture_type = TEXTURE_TYPE::NORMAL; else if(texture_type_str == "anisotropic") texture_type = TEXTURE_TYPE::ANISOTROPIC; else { log_error("unknown texture type %s!", texture_type_str.c_str()); return; } // type/mat/model checking switch(cur_material->mat_type) { case MATERIAL_TYPE::DIFFUSE: if(texture_type == TEXTURE_TYPE::HEIGHT || texture_type == TEXTURE_TYPE::NORMAL) { log_error("invalid texture type/tag \"%s\" for diffuse material!", texture_type_str.c_str()); continue; } break; case MATERIAL_TYPE::PARALLAX: // everything allowed for parallax-mapping case MATERIAL_TYPE::NONE: break; } switch(cur_material->lm_type) { case LIGHTING_MODEL::PHONG: if(texture_type == TEXTURE_TYPE::ANISOTROPIC) { log_error("invalid texture type/tag \"%s\" for phong material (anisotropic type is not allowed)!", texture_type_str.c_str()); continue; } break; case LIGHTING_MODEL::ASHIKHMIN_SHIRLEY: case LIGHTING_MODEL::NONE: break; } // get filtering and wrapping modes (if they are specified) GLenum wrap_s = GL_REPEAT, wrap_t = GL_REPEAT; // default values TEXTURE_FILTERING filtering = TEXTURE_FILTERING::AUTOMATIC; for(unsigned int i = 0; i < 2; i++) { const char* wrap_mode = (i == 0 ? "wrap_s" : "wrap_t"); GLenum& wrap_ref = (i == 0 ? wrap_s : wrap_t); if(x->is_attribute(material_elem->attributes, wrap_mode)) { string wrap_str = x->get_attribute<string>(material_elem->attributes, wrap_mode); if(wrap_str == "clamp_to_edge") wrap_ref = GL_CLAMP_TO_EDGE; else if(wrap_str == "repeat") wrap_ref = GL_REPEAT; else if(wrap_str == "mirrored_repeat") wrap_ref = GL_MIRRORED_REPEAT; else { log_error("unknown wrap mode \"%s\" for %s!", wrap_str.c_str(), wrap_mode); } } } if(x->is_attribute(material_elem->attributes, "filtering")) { string filtering_str = x->get_attribute<string>(material_elem->attributes, "filtering"); if(filtering_str == "automatic") filtering = TEXTURE_FILTERING::AUTOMATIC; else if(filtering_str == "point") filtering = TEXTURE_FILTERING::POINT; else if(filtering_str == "linear") filtering = TEXTURE_FILTERING::LINEAR; else if(filtering_str == "bilinear") filtering = TEXTURE_FILTERING::BILINEAR; else if(filtering_str == "trilinear") filtering = TEXTURE_FILTERING::TRILINEAR; else { log_error("unknown filtering mode \"%s\"!", filtering_str.c_str()); } } a2e_texture tex = t->add_texture(floor::data_path(texture_filename.c_str()), filtering, engine::get_anisotropic(), (GLint)wrap_s, (GLint)wrap_t); switch(texture_type) { case TEXTURE_TYPE::DIFFUSE: ((diffuse_material*)cur_material->mat)->diffuse_texture = tex; break; case TEXTURE_TYPE::SPECULAR: ((diffuse_material*)cur_material->mat)->specular_texture = tex; break; case TEXTURE_TYPE::REFLECTANCE: ((diffuse_material*)cur_material->mat)->reflectance_texture = tex; break; case TEXTURE_TYPE::HEIGHT: ((parallax_material*)cur_material->mat)->height_texture = tex; break; case TEXTURE_TYPE::NORMAL: ((parallax_material*)cur_material->mat)->normal_texture = tex; break; case TEXTURE_TYPE::ANISOTROPIC: if(cur_material->lm_type == LIGHTING_MODEL::ASHIKHMIN_SHIRLEY) { ((ashikhmin_shirley_model*)cur_material->model)->anisotropic_texture = tex; } break; } } // ashikhmin/shirley only else if(material_name == "ashikhmin_shirley" || material_name == "const_isotropic" || material_name == "const_anisotropic") { if(cur_material->lm_type != LIGHTING_MODEL::ASHIKHMIN_SHIRLEY) { log_error("<%s> is an ashikhmin/shirley lighting-model only tag!", material_name.c_str()); continue; } if(material_name == "ashikhmin_shirley") { // no attributes atm } else if(material_name == "const_anisotropic") { float2 roughness(1.0f); string roughness_str = x->get_attribute<string>(material_elem->attributes, "roughness"); vector<string> roughness_arr = core::tokenize(roughness_str, ','); if(roughness_arr.size() < 2 || roughness_arr[0].length() == 0 || roughness_arr[1].length() == 0) { log_error("invalid anisotropic roughness value \"%s\"!", roughness_str.c_str()); return; } if(cur_material->lm_type == LIGHTING_MODEL::ASHIKHMIN_SHIRLEY) { ashikhmin_shirley_model* as_model = (ashikhmin_shirley_model*)cur_material->model; as_model->anisotropic_roughness.set(stof(roughness_arr[0]), stof(roughness_arr[1])); } else { log_error("invalid lighting model type for \"const_anisotropic\"!"); return; } } } // parallax mapping only else if(material_name == "pom") { if(cur_material->mat_type != MATERIAL_TYPE::PARALLAX) { log_error("<pom> is a parallax-mapping only tag!"); continue; } ((parallax_material*)cur_material->mat)->parallax_occlusion = (x->get_attribute<string>(material_elem->attributes, "value") == "true" ? true : false); } } } else if(node_name == "object") { size_t material_id = x->get_attribute<size_t>(cur_elem->attributes, "material_id"); const material* mat = nullptr; try { mat = &get_material(material_id); } catch(...) { log_error("invalid object mapping for object #%d!", object_id); if(object_id == 0) return; // no default possible, abort // set to default and continue mat = mapping[0]->mat; } bool blending = false; if(x->is_attribute(cur_elem->attributes, "blending")) { blending = x->get_attribute<bool>(cur_elem->attributes, "blending"); } mapping[object_id] = new object_mapping((material*)mat, blending); object_id++; } } } if(object_id == 0) { log_error("at least one object mapping is required!"); return; } if(object_count < mapping.size()) { log_error("less object mappings specified than required by object count!"); return; } xmlFreeDoc(doc); xmlCleanupParser(); }