This is the second time I have tried sending this message. My apologies if it gets delivered twice. However, this message
includes more details than the last one.
I noticed that when porting my application to OSG that some of my
textures in my AC3D models would wrap even though they did not have a
"texrep" line in them. After looking at the code, I found that currently
the AC3D plugin uses GL_REPEAT for all textures. That works great if
your texture makes use of the "texrep" line, but can cause some
unintended wrapping otherwise. So, attached is a patch to use
GL_CLAMP_TO_EDGE by default and GL_REPEAT when necessary. I have also
added a bool to avoid an extra floating point multiplication. The patch
is for the file:
src\osgPlugins\ac\ac3d.cpp
While I have tested the patch, I am unsure the best way to handle things when
more than one object makes use of the same texture. Since the plugin
reuses textures (which is good), it appears that whichever wrap mode
gets set last is the one that is used for all instances of that texture.
One (ugly) solution I found in the method TextureData::toTextureStateSet is to
change:
stateSet->setTextureAttribute(0, mTexture2D.get())
to
stateSet->setTextureAttribute(0, new osg::Texture2D(*mTexture2D.get(),
osg::CopyOp::DEEP_COPY_ALL));
In other words, make a deep copy of the osg::Texture2D object. However, that just seems very inelegant. Is there a better way to
do it? I assume there is a way to handle such a case without duplicating the texture.
Other than that issue, I feel pretty confident in this mod.
Thanks
John Cummings
Index: ac3d.cpp
===================================================================
--- ac3d.cpp (revision 8952)
+++ ac3d.cpp (working copy)
@@ -334,8 +334,7 @@
{
mTexture2D = new osg::Texture2D;
mTexture2D->setDataVariance(osg::Object::STATIC);
- mTexture2D->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
- mTexture2D->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
+ setWrap(osg::Texture2D::CLAMP_TO_EDGE);
std::string absFileName = osgDB::findDataFile(name, options);
if (absFileName.empty())
@@ -353,6 +352,11 @@
mTranslucent = mImage->isImageTranslucent();
return true;
}
+ void setWrap(osg::Texture::WrapMode mode)
+ {
+ mTexture2D->setWrap(osg::Texture2D::WRAP_S, mode);
+ mTexture2D->setWrap(osg::Texture2D::WRAP_T, mode);
+ }
bool valid() const
{
return mImage.valid();
@@ -1101,6 +1105,7 @@
group->setDataVariance(osg::Object::STATIC);
osg::Vec2 textureOffset(0, 0);
osg::Vec2 textureRepeat(1, 1);
+ bool haveTextureRepeat(false);
float creaseAngle = 61;
unsigned objectType = ObjectTypeGroup;
@@ -1153,9 +1158,12 @@
}
textureData = fileData.toTextureData(texname);
+ textureData.setWrap(osg::Texture2D::CLAMP_TO_EDGE);
}
else if (token == "texrep") {
stream >> textureRepeat[0] >> textureRepeat[1];
+ haveTextureRepeat = true;
+ textureData.setWrap(osg::Texture2D::REPEAT);
}
else if (token == "texoff") {
stream >> textureOffset[0] >> textureOffset[1];
@@ -1278,8 +1286,15 @@
if (acceptPrimitive)
{
- texCoord[0] = textureOffset[0] +
texCoord[0]*textureRepeat[0];
- texCoord[1] = textureOffset[1] +
texCoord[1]*textureRepeat[1];
+ if ( haveTextureRepeat )
+ {
+ texCoord[0] = textureOffset[0] +
texCoord[0]*textureRepeat[0];
+ texCoord[1] = textureOffset[1] +
texCoord[1]*textureRepeat[1];
+ }
+ else {
+ texCoord[0] = textureOffset[0] + texCoord[0];
+ texCoord[1] = textureOffset[1] + texCoord[1];
+ }
if (!primitiveBin->vertex(index, texCoord))
{
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org