realbasic-games
[Top] [All Lists]

Re: Sharing textures

To: REALbasic Games <realbasic-games at lists dot realsoftware dot com>
Subject: Re: Sharing textures
From: Frank Condello <developer at chaoticbox dot com>
Date: Sat, 25 Jun 2005 16:05:14 -0400
Delivered-to: realbasic-games at lists dot realsoftware dot com
References: <485bea6f7e4536c11d2387c99f86ffbf at optonline dot net> <3da8fe35abd7b3c631f548256e816cd8 at mindspring dot com>
On 25-Jun-05, at 2:03 PM, Jeff Quan wrote:

On Jun 25, 2005, at 10:36 AM, Daniel Lurie wrote:

Is there a way to make multiple object 3Ds share the same texture?

At the moment, not without declares. You can use Frank's Quesa Wrappers.

Here's a snippet of code that should work using Quesa Wrappers. This assumes that the obj has a pre-existing texture to be replaced and will ONLY affect the first trimesh's texture. This means, in Meshwork terms, if you've applied multiple materials only the first one will be affected. You'll need to do a bit more legwork to get to the other textures.

Sub UpdateObjTexture(obj As Object3D, texture As Picture)
  Dim tmsh as Trimesh3D
  Dim mat as AttributeSet3D
  Dim tex as TextureShader3D

    // Get existing texture on obj.
    // NOTE: This only affects first trimesh only!
    tmsh = obj.GetFirstTrimeshInShape(i)
    mat = tmsh.GetMaterial
    tex = mat.GetTextureShader

    // Replace texture
    tex.SetTexture texture, tex.kPixelTypeRGB32

That will replace the texel data for each object, but it won't actually share it! The TextureShader3D.SetTexture method actually copies the picture you pass to it (too keep things simple I didn't expose pixmap objects directly in the Quesa wrappers or else something like that might've been possible).

To share a texture you need to assign the *same* TextureShader3D or AttributeSet3D object to a your various meshes:

    ' Create a the textueshader you you wish to share,
' or better yet, use an AttributeSet3D, to share all material attributes:

    Dim mat as AttributeSet3D
    Dim tex as TextureShader3D

    tex = New TextureShader3D(somePicture, tex.kPixelTypeRGB32)
    mat = New AttributeSet3D
    mat.SetTextureShader tex
' Set other "mat" attributes if ya like (colors, transparency, shininess etc.)

' Now apply "mat" to all the objects you want to share the same material
    UpdateObjTexture(obj, mat)
    UpdateObjTexture(obj2, mat)
    ' ... etc ...

The update method would look something like this:

    Sub UpdateObjTexture(obj As Object3D, mat As AttributeSet3D)

        Dim tmsh as Trimesh3D
        tmsh = obj.GetFirstTrimeshInShape(i)
        if tmsh <> Nil then
            tmsh.SetMaterial mat
        end if

    End Sub

Iterating through each Object3D shape and each trimesh in each shape isn't much more work, but keep in mind that the 3DMF format can be a little slippery at times. Textureshader objects can be placed inside display groups to affect all the geometry in that group (same with attribute sets). So although you're replacing the trimesh texture, there may be a stray textureshader or attribute set in the 3DMF data that no longer affects the final render, but still gets uploaded to hardware wasting VRAM/RAM and CPU/GPU resources. This would occur if you used the above method on an object shape created with AddShapePicture for example. To be safe, you should first run through all the shape's display groups and delete any stray texture shaders and attribute sets. That's a bit more work, but the 3DMF format is unpredictable and often requires special attention.

HTH!
Frank.
–––––––––––––––––––––––––––––––––
Open Source RB Goodies and Shareware
<http://developer.chaoticbox.com/>
<http://www.chaoticbox.com/>
–––––––––––––––––––––––––––––––––

_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

<Prev in Thread] Current Thread [Next in Thread>