multitexturing

edited May 2013 in Help request
Is it possible to apply 2 textures (second with alpha) to an object using orxObject_LinkStructure(object, graphic)?

In my attempts, the second graphic overwrites the first, transparent areas being black (background?). Adding BlendMode = alpha to the second texture did not help.

Another question: how many textures and/or shaders can be assigned to an object all in all?

Comments

  • edited May 2013
    From orxobject on wiki

    Up to 4 shaders can be defined.
  • edited May 2013
    As kulak pointed out, up to 4 shaders can be attached to a single object. Most of the time though (if not all), a single one should be sufficient.

    For multitexturing you need to use a shader, you can attach as many shaders as there are texture units on the hardware.
    For recent desktop GPU, it's usually 32. For iDevices, it's often 8. Not sure about Android devices.

    Btw, when using a shader, you don't have to use the texture that's bound to the object/graphic, it's only a matter of convenience.

    I believe there are a couple of community tutorials using multiple input textures, as well as one using an intermediate render-to-texture to achieve compositing.

    Can you give us more details on the effect you'd like to achieve?
  • edited May 2013
    I have read about the 4 shader limit, what I was wondering about is how that depends/affects textures that are assigned to the object. From your answer it seems that they are independent, which is fair enough.

    My real question is about adding additional overlays on an object with an already-assigned texture. So something like this:

    1. A player object with a player texture is running around, gets hit
    2. Depending on the location of the hit, draw a bullet hole in the character. But the bullet hole depends on the weapon, so we look up appropriate texture from resources and apply it over the top of all previous textures assigned to this object
    3. Character gets hit again, so we draw another bullet hole. End effect: bullet holes keep building up.
    4. (repeat until out of health)

    The way I'm thinking of solving it is by applying small partially transparent textures over a base texture. To this end, I have tried calling orxObject_LinkStructure(object, graphic) on an existing object, but that wipes out the original texture.

    How would one go about doing the above?
  • edited May 2013
    I am not an expert on this, but it appears to me that you can take care of multiple bullet marks in a single shader. Shader can take two variables. One is a list of images for different bullet types and another one is a corresponding list of positions for bullet images.

    I have no idea how image blending would work. It seems to me that you would have to maintain an individual texture image yourself if you want to make a change at the object's graphic level.

    Alpha channel does work. I used code below to add extra green color:
            orxCOLOR col;
            orxCOLOR colRGB;
            //do you want transparency?
            col.fAlpha=1.0f;
            col.vHSV.fH=0.36;//scaling it from 0(red) to 0.36(green)
            col.vHSV.fS=0.71;
            col.vHSV.fV=0.85;
            orxColor_FromHSVToRGB(&colRGB, &col);
            orxObject_SetColor(obj, &colRGB);
    
  • edited May 2013
    As kulak proposed, you could handle it entirely within a shader, but you'd have a limit on the number of marks you can add as arrays must be of fixed size before the shader is compiled.

    The way this situation is usually handled is by using decals though. In this case, you could simply have an orxOBJECT that represent a bullet mark per type of weapon.

    When your character is hit, you create an instance of the correct object on top of your character then you attach it to him, this way the decal will always move with your character.
    If your character isn't in a single piece, you'd attach the decal to the correct limb instead.

    More advance, if you want to clip your decal so that it doesn't go beyond the parent limb/character visually, you can do a 2-pass compositing that would render all your instances in the first pass then apply all the decals in a second one, reusing the texture resulting from the first pass to do some "alpha testing". But I'd really go there only in the polish phase when all the rest is done, personally. :)

    PS: For the weapon lookup, I'd use the config system. Each weapon section would define the name of the decal type, and you can easily to the lookup when receiving damage. I did something very similar to handle impact explosions in Mushroom Stew:
    Each weapon defines a property named Impact, which can have a few different values (RegularImpact, ExplosionImpact, ...) and defines the impact type.

    When an object is hit, we ask the weapon what its Impact is, we then look on the hit object the value of this property and we create the object matching that name.

    It might be more clear with an example:
    [HandGun]
    Impact = RegularImpact
    
    [RocketLauncher]
    Impact = ExplosionImpact
    
    [Character]
    RegularImpact = BloodSplat1 # BloodSplat2 # BloodSplat3
    ExplosionImpact = Gibs
    
    [Wall]
    RegularImpact = Dust1 # Dust2
    ExplosionImpact = Explosion1 # Explosion2
    

    In pseudo-code, we then have:
    OnHit()
    {
      PushSection(DamagingWeapon);
      ImpactType = GetString("Impact");
      PopSection();
      PushSection(MySelf);
      ObjectName = GetString(ImpactType);
      PopSection();
      Object = CreateFromConfig(ObjectName);
      SetPos(Object, HitPos);
    }
    
  • edited May 2013
    I dug through the LinkStructure code, and in fact there is only one structure of any one type (ie graphic) is allowed, the previous one will be unlinked and released.

    As far as gl multitexturing, the only reference in the source for android that I see is in orxDisplay_Android_SetShaderBitmap. Thus, it seems that one cannot apply two textures to the same object without shaders.

    So, as kulak and iarwain said, additonal textures must be brought in via additional objects, or shader code.

    Some more questions:

    1. Is there a recommended reading material on using shaders (specifically passing in data)?

    2. For the case of applying decals via additional objects, z-ordering must be done manually by adding small offsets, correct?
  • edited May 2013
    In my little experimental game I just created a range color effect that's positioned behind the tank. All done in INI file:

    Don't underestimate config power:
    
    [TankRangeTemplate]
    Graphic = @
    Texture = pixel
    Color = (128, 0, 0)
    Position = (0, 0, 0.1)
    Alpha = 0.35
    Repeat = (50, 50, 0)
    Scale = @.Repeat
    
    [TankTemplate]
    Graphic = TankTexture
    Body = Box
    GType = tank
    GBulletOffset = (40., 0., 0.)
    ChildList = TankRangeTemplate
    

    That range rectangle is behind the tank and it is bound to tank position. Best of all coordinates are relative to parent.

    IMO It is impressive.
  • edited May 2013
    edit: nm, i see what you did
  • edited May 2013
    zokzok wrote:
    As far as gl multitexturing, the only reference in the source for android that I see is in orxDisplay_Android_SetShaderBitmap. Thus, it seems that one cannot apply two textures to the same object without shaders.
    You can't actually display anything on the Android version without a shader, orx simply provides a default one that does single texturing + coloring.
    1. Is there a recommended reading material on using shaders (specifically passing in data)?

    There's a simple tutorial about shaders, but shaders are used in a few tutorials/examples around.
    2. For the case of applying decals via additional objects, z-ordering must be done manually by adding small offsets, correct?

    Yes, that's how it's done. However one can use local coordinates in the parent system, which means you can keep a constant offset on Z (like -0.1) and this will work no matter the Z value of your parent.
Sign In or Register to comment.