Ejemplo n.º 1
0
/**
 * 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 );
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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));
}
Ejemplo n.º 5
0
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */
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() */
Ejemplo n.º 6
0
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;
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
    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;
    }
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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
        )
      ));
  }
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
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 );
}
Ejemplo n.º 19
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_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 );
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
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);
	}
}
Ejemplo n.º 22
0
  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);


  }
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
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*) &current_package, (char*) mv_matrix.data_array, 16 * sizeof(float) );
      memcpy( ((char*) &current_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);
    }

  
  }

}
Ejemplo n.º 26
0
    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);
        }
    }
Ejemplo n.º 27
0
/**
 * 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;
}
Ejemplo n.º 28
0
/*! 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();
}