What I am trying to do is draw a large quad (purpose to use ground, using a high res google earth jpg). I have been doing this by specifying the end points of the square, and then putting the texture onto it. This works fine.
However this results in only one lighting condition being applied to the entire square/ground. I would like to allow lighting to be variable across the surface - ie if I have a spotlight on the surface, the entire ground will light up in the same color instead of having a gradient across it (as if the ground was subdivided into many polygons with their own lighting calculations).
It would seem there would be an easy way to get OSG to do this - but I do not know it.
Any advice in this regard would be greatly appreciated!
Thank you!
Cheers,
Alden
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=34596#34596
_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Do your constraints allow the use of fragment shaders for per-pixel lighting? It's much
more efficient than creating highly tesselated geometry just to achieve smooth lighting.
/ulrich
I believe what you say would work (I have not used shaders with osg at all) - after searching a bit I was unable to find any good examples - how difficult is that to implement?
Any help would be appreciated here as well :-)
Thanks,
Alden
Ulrich Hertlein wrote:
> On 8/12/10 11:35 , Alden Peterson wrote:
>
> > However this results in only one lighting condition being applied to the entire
> > square/ground. I would like to allow lighting to be variable across the surface - ie
> > if I have a spotlight on the surface, the entire ground will light up in the same color
> > instead of having a gradient across it (as if the ground was subdivided into many
> > polygons with their own lighting calculations).
> >
>
> Do your constraints allow the use of fragment shaders for per-pixel lighting? It's much
> more efficient than creating highly tesselated geometry just to achieve smooth lighting.
>
> /ulrich
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=34641#34641
Posting this here in case someone has a similar question in the future as I was unable to find anything of this sort online to use as an example.
What I ended up doing was splitting up the image into partitions then assigning texture coordinates appropriately.
Code:
//loads in ground image, applies to square
osg::Geode* groundGeode = new osg::Geode;
std::vector<osg::Geometry*> groundGeometry;
//assign coordinates to ground geode
std::vector<osg::Vec3Array*> groundEnds;
std::vector<osg::DrawElementsUInt*> groundDrawElements;
std::vector<osg::Vec2Array*> texCoords;
//colors
osg::ref_ptr<osg::Vec4Array> colorsTex (new osg::Vec4Array());
colorsTex->push_back (osg::Vec4 (1.0f, 1.0, 1.0f, 1.0f));
//normals
osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array());
normals->push_back (osg::Vec3 (0.0f, 0.0f, 1.0f));
//define width (adjusted manually to approximate right size;
int w;
//13250
//12800
w = 12650;
int numbRowCol = 25;
float xl, xr, yb, yt; //x left, x right, y bottom, y top
float txl, txr, tyb, tyt;
int iterator;
iterator = 0;
for (int i = 0; i < numbRowCol; i++) {
for (int j = 0; j < numbRowCol; j++) {
//create new instances of each required class
groundGeometry.push_back(new osg::Geometry() );
groundEnds.push_back(new osg::Vec3Array);
groundDrawElements.push_back(new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0));
texCoords.push_back(new osg::Vec2Array(4));
//assign vertex based on square
xl = -w/2 + w * ((float)i/ (float)numbRowCol);
yb = -w/2 + w * ((float)j/ (float)numbRowCol);
xr = -w/2 + w * ((float)(i+1) / (float)numbRowCol);
yt = -w/2 + w * ((float)(j+1) / (float)numbRowCol);
groundEnds[iterator]->push_back( osg::Vec3( xl , yb , 0 ) ); //bottom left
groundEnds[iterator]->push_back( osg::Vec3( xl , yt , 0 ) ); //top left
groundEnds[iterator]->push_back( osg::Vec3( xr , yt , 0 ) ); //top right
groundEnds[iterator]->push_back( osg::Vec3( xr , yb , 0 ) ); //bottom right
groundGeometry[iterator]->setVertexArray(groundEnds[iterator]);
//create drawable
groundDrawElements[iterator]->push_back(3);
groundDrawElements[iterator]->push_back(2);
groundDrawElements[iterator]->push_back(1);
groundDrawElements[iterator]->push_back(0);
groundGeometry[iterator]->addPrimitiveSet(groundDrawElements[iterator]);
//define texture coordinates
txl = 0.5 + xl/w;
txr = 0.5 + xr/w;
tyb = 0.5 + yb/w;
tyt = 0.5 + yt/w;
(*texCoords[iterator])[0].set(txl, tyb);
(*texCoords[iterator])[1].set(txl, tyt);
(*texCoords[iterator])[2].set(txr, tyt);
(*texCoords[iterator])[3].set(txr, tyb);
groundGeometry[iterator]->setTexCoordArray(0,texCoords[iterator]);
//add current draw element to geode to be rendered
groundGeode->addDrawable(groundGeometry[iterator]);
//colors
groundGeometry[iterator]->setColorArray (colorsTex.get());
groundGeometry[iterator]->setColorBinding (osg::Geometry::BIND_OVERALL);
//normals
groundGeometry[iterator]->setNormalArray (normals.get());
groundGeometry[iterator]->setNormalBinding (osg::Geometry::BIND_OVERALL);
iterator++;
}
}
/*
assign texture for ground
*/
osg::Texture2D* groundTexture = new osg::Texture2D;
// protect from being optimized away as static state:
/groundTexture->setDataVariance(osg::Object::DYNAMIC);
// load an image by reading a file:
osg::Image* groundImage = osgDB::readImageFile("models/textures/background_photoshop.jpg");
if (!groundImage)
{
std::cout << " couldn't find texture." << std::endl;
}
// Assign the texture to the image we read from file:
groundTexture->setImage(groundImage);
// Create a new StateSet with default settings:
osg::StateSet* stateOne = new osg::StateSet();
// Assign texture unit 0 of our new StateSet to the texture
stateOne->setTextureAttributeAndModes(0,groundTexture,osg::StateAttribute::ON);
// Associate this state set with the Geode that contains
// the pyramid:
groundGeode->setStateSet(stateOne);
osg::PositionAttitudeTransform* groundXform = new osg::PositionAttitudeTransform();
groundXform->setPosition(osg::Vec3(0,0.0,0));
groundXform->addChild(groundGeode);
root->addChild(groundXform);
Thank you!
Cheers,
Alden
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=34784#34784