How to bind a texture in osgEarth?

classic Classic list List threaded Threaded
5 messages Options
marlinrowley marlinrowley
Reply | Threaded
Open this post in threaded view
|

How to bind a texture in osgEarth?

Following some of the examples that come along with the osgEarth package.  I'm not quite sure how to bind a texture to a sampler2D.

 osg::ref_ptr<osg::Group> run(osg::Node* earth)
        {
                osg::Group* g = new osg::Group();
                g->addChild(earth);

                // set an image overlay for this node
                osg::Texture2D* tex = new osg::Texture2D(osgDB::readImageFile(imageName));
                if (tex)
                {
                        tex->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
                        tex->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
                        tex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR);
                        tex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR);
                        tex->osg::Texture::setMaxAnisotropy(16.0);
                        g->getOrCreateStateSet()->getOrCreateUniform("texSampler2D", osg::Uniform::SAMPLER_2D);

****WHAT ELSE GOES HERE?****

                }

                // set the shaders in the current state
                g->getOrCreateStateSet()->setAttributeAndModes(setupShader(), osg::StateAttribute::ON);
                return g;
        }
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: How to bind a texture in osgEarth?

Marlin,
I will answer your question, but it probably will not help you achieve you goals. Can you step back and explain what they are?
...
Binding a sampler in OSG requires two steps:

// install your texture at an available texture image unit:
stateSet->setTextureAttributeAndModes(unit, tex, osg::StateAttribute::ON);

// create a uniform with the sampler's name and set it to the same unit.
osg::Uniform* u = new osg::Uniform("texSampler2D", osg::Uniform::SAMPLER_2D);
u->set(unit);
stateSet->addUniform(u);
Glenn Waldron / Pelican Mapping
marlinrowley marlinrowley
Reply | Threaded
Open this post in threaded view
|

Re: How to bind a texture in osgEarth?

Glen,

I am very new to OSG and trying to figure it out is an exercise in frustration.

I'm ultimately trying to create 2d projected textured lights that casts shadows onto the osgEarth globe based on where they are located.

There are several concepts that I haven't grasped yet in trying to achieve this and I'm trying to learn as I go.  That is why I asked for a simple example using the ShadowCaster class so that I can learn from that.

I took one step back and wanted to just get projected textures on the terrain.  But before that, I took another step back and said, let me just read an image file as a texture and just blend it in to the terrain.  That of course, requires a few more steps back into learning how to get texture coordinates, and binding textures to the current texture units.

So, as you see, I'm going further back to the start of all this and can't seem to get any good examples to start my way forward.

-M
marlinrowley marlinrowley
Reply | Threaded
Open this post in threaded view
|

Re: How to bind a texture in osgEarth?

Progress!

// set an image overlay for this node
                osg::Texture2D* tex = new osg::Texture2D(osgDB::readImageFile(imageName));
                if (tex)
                {
                        tex->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
                        tex->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
                        tex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR);
                        tex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR);
                        tex->osg::Texture::setMaxAnisotropy(16.0);
                        g->getOrCreateStateSet()->setTextureAttributeAndModes(1, tex, osg::StateAttribute::ON);
                        osg::Uniform* u = new osg::Uniform("texSampler2D", osg::Uniform::SAMPLER_2D);
                        u->set(1);
                        g->getOrCreateStateSet()->addUniform(u);
                        tex->setUnRefImageDataAfterApply(true);
                }

                // set the shaders in the current state
                g->getOrCreateStateSet()->setAttributeAndModes(setupShader(), osg::StateAttribute::ON);
                return g;

I can now see my texture splattered all over the globe with wraps happening!  Yay!!

So the next question would be:

1) How do I read in the current model-view-projection matrices from the shaders?  I know that with the latest OpenGL spec that you should provide your own matrices. So how do I retrieve those after I've built the osg::MapNode* pointer with it having loaded an .earth file?  Ideally, I would want something like: osg::MapNode* terrainMap;
osg::Node* myNode = terrainMap->load(args);
Matrix4* myMatrix = myNode->getMVPMatrix(); or something like that?

Or is there some built-in variable that already passes this to all the shaders?

2) How to get the texture coordinates of the mapNode?  Are all the tiles using different uv spaces?  In other words, does each tile restart the uv space from 0:1 or is the entire globe a unique uv space?

marlinrowley marlinrowley
Reply | Threaded
Open this post in threaded view
|

Re: How to bind a texture in osgEarth?

Btw, I hardcoded the uv coords in the vertex shader:

uniform mat4 transformMVP;
out vec4 textureCoords;

void Compute_VS(inout vec4 VertexMODEL)
{
    // Just provide the uv coordinates of the point
    textureCoords = gl_MultiTexCoord1;
}

Should I use this approach or is their a cleaner way of getting the coordinates?