Trouble applying a texture to a generic model (all one color

What I am trying to do it to take a shape from this Panda3D site and apply my own texture to it. My result is that the shape is made one solid color, a color that is indeed in my texture so I am loading the texture fine. In fact, I can easily apply a texture to other models from Panda3D that already have textures on them. So I am missing something here.

This is the model I downloaded: panda3d.org/artinfo.php?cat= … apes–dome

This my code:

import direct.directbase.DirectStart

sky = loader.loadModel(“alice-shapes–dome/dome.egg”)
sky.reparentTo(render)

skytex = loader.loadTexture(“sky_9.bmp”)
sky.setTexture(skytex)

run()

So this is what I need to know:

  1. Why can I put a texture on other objects but not these generic shape objects?
  2. How do I get my texture to appear on this object?

OK, there’s more going on here than meets the eye.

The “model” isn’t actually a single atomic object once it’s loaded into panda. Rather, the model consists of a tree of PandaNodes. The top node is a ModelNode, and then somewhere under the ModelNode are typically several GeomNodes. Each GeomNode might have a different texture attribute.

So when you call “setTexture”, you’re setting a texture attribute on the ModelNode. But under that ModelNode are GeomNodes that also have texture attributes.

During the rendering process, Panda tries to propagate your texture attribute down from the ModelNode to the GeomNodes underneath. But then it encounters the texture attributes on the GeomNodes. Now it has to decide which takes precedence - the texture attribute that you applied to the ModelNode and that got propagated down, or the texture attribute which it read in from the Egg file and applied directly to the GeomNode. It makes this decision based on a priority system. You can control these priorities using setTexture:

model->setTexture(tex, PRIORITY)

The default priority of a texture loaded from an egg file is zero. So if you set a priority of, say, 1, then your texture will override the one from the egg file.

The fact that your previous attempts worked is probably luck. Perhaps the models that you loaded previously happened to be very simple models, with no texture attributes below the root node. In that case, your old code would have worked.

I appreciate the information about how textures actually work and I assume it will prove important as I get further involved in a project, especially with something where I have multiple textures for an object. Something like bullet holes seems like it would require a priority to decide what to draw on top.

However, setting the texture with a priority parameter has not solved my problem. I still only get a solid color on my object. I would appreciate it if someone would try to do what I am trying to do, with the same object, and see if the same problem arises.

The problem you are describing is due to the fact that these particular models don’t have texture coordinates (“UV’s”) assigned to the vertices. That’s probably because these models were never intended to have textures assigned to them.

If you’re not familiar with the concept of texture coordinates, read through the Texturing section in the Panda3d manual.

To solve this problem, you’ll have to generate texture coordinates for these models, for instance by importing them into a modeling package like 3DSMax, or you’ll have to use a different model.

David

Oh, yeah–there’s also one other option, which is to generate texture coordinates on the fly. See the manual about this.

David

Oh, thank you very much. I see what was going on now and everything is working as it should. Again, thank you guys for the quick replies, it is appreciated very much.

Well, bummer. I have the texture on the shape, but it appears as a pattern. Meaning I have the same image repeated thousands of times on my dome. I’ve been messing around with it for a few hours, because I don’t really like asking for answers, and I found some cool things like making the texture appear in relation to the world which creates a cool sort of mirror-like effect. But I really just want to have the texture stretch over the entire object.

I’ve come close by playing around with the .setTexGen parameters (mainly the second one) but the closest I have come is to have the image displayed four time. I also played around with the different U and V wrap settings and they worked, but nothing there would actually stretch my texture to make it cover the entire object. I feel like I’m missing something somewhat obvious, because this is such a basic thing or so it seems.

It will probably help, so here is the important code:
sky = loader.loadModel(“alice-shapes–dome/dome.egg”)
sky.reparentTo(render)
sky.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition)
#TexGenAttrib.MEyeSphereMap is cool also.

skytex = loader.loadTexture(“sky_9.bmp”)
sky.setTexture(skytex,1)
sky.setScale(100, 100, 100)
sky.setTexProjector(TextureStage.getDefault(), render, sky);

Try:


sky.setTexScale(TextureStage.getDefault(), 0.3)

David