OpenSceneGraph Forum Forum Index OpenSceneGraph Forum
Official forum which mirrors the existent OSG mailing lists. Messages posted here are forwarded to the mailing list and vice versa.
 
   FAQFAQ    SearchSearch    MemberlistMemberlist    RulesRules    UsergroupsUsergroups    RegisterRegister 
 Mail2Forum SettingsMail2Forum Settings  ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
   AlbumAlbum  OpenSceneGraph IRC ChatOpenSceneGraph IRC Chat   SmartFeedSmartFeed 

problem setting texture min/mag filter


 
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General
View previous topic :: View next topic  
Author Message
antiro42
User


Joined: 01 Sep 2017
Posts: 46

PostPosted: Mon Feb 12, 2018 7:51 am    Post subject:
problem setting texture min/mag filter
Reply with quote

Hi,

I'm trying to use a texture to get some data to a shader. The texure is created by first creating an osg::Image, setting its pixel values manually and then assigning the image to a texture. I have verified that the image is created correctly by writing it to a file.

As for the actual texture generation I use the following code:

Code:

osg::ref_ptr<osg::Image> m_tileDataImg=nullptr;

// some code to create the osg::image
// ...
// ...

auto tileDataTexture=new osg::Texture2D();

tileDataTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT);
tileDataTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT);
tileDataTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
tileDataTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
tileDataTexture->setImage(m_tileDataImg);

drawableNode->getStateSet()->setTextureAttributeAndModes(0,tileDataTexture,osg::StateAttribute::ON);



In my shader I rendered the texture for debugging purposes and realized that the data was changed. After a closer inspection it turned out that the data had been interpolated, hence my suspicion that the "setFilter" code did not work correctly.

My question is whether there is some other thing I need to do to ensure that no interpolation happens when sampling the texture in my shader?

Any help would be greatly appreciated.
Thank you!

Cheers,
antiro
Back to top
View user's profile Send private message
robertosfield
OSG Project Lead


Joined: 18 Mar 2009
Posts: 11802

PostPosted: Mon Feb 12, 2018 9:43 am    Post subject:
problem setting texture min/mag filter
Reply with quote

HI Antiro,

You code looks fine, there isn't anything else you need to do to set
up filter modes.

I haven't heard of issues with setting the filter modes so would
expect it to work. Perhaps what is amiss is either something higher up
- such as the texture not being used in the subgraph that you think it
is being used - or that the filtering is working and you are just
mis-interpreting the results.

Robert.

On 12 February 2018 at 07:51, antiro black <> wrote:
Quote:
Hi,

I'm trying to use a texture to get some data to a shader. The texure is created by first creating an osg::Image, setting its pixel values manually and then assigning the image to a texture. I have verified that the image is created correctly by writing it to a file.

As for the actual texture generation I use the following code:


Code:

osg::ref_ptr<osg::Image> m_tileDataImg=nullptr;

// some code to create the osg::image
// ...
// ...

auto tileDataTexture=new osg::Texture2D();

tileDataTexture->setWrap(osg::Texture::WRAP_S,osg::Texture::REPEAT);
tileDataTexture->setWrap(osg::Texture::WRAP_T,osg::Texture::REPEAT);
tileDataTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
tileDataTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
tileDataTexture->setImage(m_tileDataImg);

drawableNode->getStateSet()->setTextureAttributeAndModes(0,tileDataTexture,osg::StateAttribute:ShockedN);





In my shader I rendered the texture for debugging purposes and realized that the data was changed. After a closer inspection it turned out that the data had been interpolated, hence my suspicion that the "setFilter" code did not work correctly.

My question is whether there is some other thing I need to do to ensure that no interpolation happens when sampling the texture in my shader?

Any help would be greatly appreciated.
Thank you!

Cheers,
antiro

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=72956#72956








------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
antiro42
User


Joined: 01 Sep 2017
Posts: 46

PostPosted: Mon Feb 19, 2018 2:18 pm    Post subject:
Reply with quote

Hi,

Thank you for response robertos, I've been playing around with the code the last few days and it seems like the filters are doing something, it is just not what I expected. I'm wondering if I misinterpreted the meaning of a "NEAREST" filter.

As I understand it, putting both the min and mag filters on nearest means that, when sampling a location on your texture it will return the color of the nearest pixel. In other words: you will always get a value back that is present in the pixeldata from the image.

However, as far as I can see from my test, this is not the case: I created an image with red pixels on one half (255,0,0) and black pixels on the other half (0,0,0). When sampling the texture to which this image was set and simply drawing the sampled values onto a bigger texture for debugging purposes, I see a red half, a black half and a line of dark red "pixels" separating them. As if the values have been interpolated when sampling.
If i turn off the "nearest" filters this line becomes a gradient, so clearly the filtering is doing something.

Am I just completely misinterpreting the intended behavior of the "nearest" filters? or is there something wrong in the implementation?

Thank you!

Cheers,
antiro
Back to top
View user's profile Send private message
errno (Lionel Lagarde)
User


Joined: 10 Mar 2009
Posts: 57
Location: Toulouse, France

PostPosted: Mon Feb 19, 2018 2:52 pm    Post subject:
problem setting texture min/mag filter
Reply with quote

Hi,

The half red half black pixels may come from some kind of anti-aliasing.
Check your frame buffer settings.

My 2 cents.


On 19/02/2018 15:18, antiro black wrote:
Quote:
Hi,

Thank you for response robertos, I've been playing around with the code the last few days and it seems like the filters are doing something, it is just not what I expected. I'm wondering if I misinterpreted the meaning of a "NEAREST" filter.

As I understand it, putting both the min and mag filters on nearest means that, when sampling a location on your texture it will return the color of the nearest pixel. In other words: you will always get a value back that is present in the pixeldata from the image.

However, as far as I can see from my test, this is not the case: I created an image with red pixels on one half (255,0,0) and black pixels on the other half (0,0,0). When sampling the texture to which this image was set and simply drawing the sampled values onto a bigger texture for debugging purposes, I see a red half, a black half and a line of dark red "pixels" separating them. As if the values have been interpolated when sampling.
If i turn off the "nearest" filters this line becomes a gradient, so clearly the filtering is doing something.

Am I just completely misinterpreting the intended behavior of the "nearest" filters? or is there something wrong in the implementation?

Thank you!

Cheers,
antiro

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=72964#72964










------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message Send e-mail
antiro42
User


Joined: 01 Sep 2017
Posts: 46

PostPosted: Tue Feb 20, 2018 9:38 am    Post subject:
Reply with quote

Hi,

As far as I can tell it does not seem to be rendering related, the shader is really sampling data from the texture that was never in the original image. A summary of my experiments:

Input is an image which is half red (255,0,0) and half black (0,0,0) and it is set as a texture for the shader. min/mag filter is set to nearest.

1: Shader sampling this texture and coloring a bigger output texture with whatever it samples -> result: half red, half black output but the halves are separated by a dark red line (as if locations sampled in between the red and black pixels have returned an _unweighted_ average of the two colors)

2: Same shader, but input texture uses min/mag filter of linear -> result half red/half black output but now separated by a gradient (the expected _weighted_ linear interplation when sampling in between black/red pixels)

3: min/mag filter back at nearest now. To verify that it is not a rendering artifact I changed the shader to output red/black when the input is red/black but purple if the input is something else -> result: the output now has a purple line separating the red/black halves, so clearly I am sampling data that is not in the original image.

It is my understanding that a nearest filter should result in the value of the _single_ nearest pixel being returned when sampling a location in a texture, but my experiments seem to point at an unweighted average of the neighboring pixels values?

Thank you!

Cheers,
antiro
Back to top
View user's profile Send private message
robertosfield
OSG Project Lead


Joined: 18 Mar 2009
Posts: 11802

PostPosted: Tue Feb 20, 2018 11:07 am    Post subject:
problem setting texture min/mag filter
Reply with quote

Hi Antiro,

Without screenshots and a working example that illustrates what you
think is a problem there isn't much we can do to help you. Filtering
has worked from the very early days of the OSG, it's not something
that is known to be problematic, you just set the filter values and
you're done.

FYI, the OSG example osgtexture2D creates a partial cube rendered with
textures and steps through different filter modes on the left hand
side wall where the brown/black terrain texture is rendered. When it
cycles through to NEAREST, NEAREST you will see a highly pixelated
result - zoom into this wall to see texels more clearly.

Robert.


------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
antiro42
User


Joined: 01 Sep 2017
Posts: 46

PostPosted: Tue Feb 20, 2018 5:09 pm    Post subject:
Reply with quote

Hi,

I made an executable example based on the osgtexture2D example. I removed the code to render the different walls of the cube with the exception of the filter wall. I kept the rest as close to the original as possible. changes to the code have been marked using comments.

Essentially all I'm doing is generating an input image instead of loading one.

Code:

#include <osg/Node>
#include <osg/Geometry>
#include <osg/Notify>
#include <osg/MatrixTransform>
#include <osg/Texture2D>
#include <osg/DrawPixels>
#include <osg/PolygonOffset>
#include <osg/Geode>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <osgText/Text>

#include <osgViewer/Viewer>

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// filter wall and animation callback.
//

class FilterCallback : public osg::NodeCallback
{
public:

    FilterCallback(osg::Texture2D* texture,osgText::Text* text,double delay=1.0):
        _texture(texture),
        _text(text),
        _delay(delay),
        _currPos(0),
        _prevTime(0.0)
    {
        // start with a mip mapped mode to ensure that
        _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_LINEAR);
        _magFilterList.push_back(osg::Texture2D::LINEAR);
        _textList.push_back("Tri-linear mip mapping (default filtering)\nsetFilter(MIN_FILTER,LINEAR_MIP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");

        _minFilterList.push_back(osg::Texture2D::NEAREST);
        _magFilterList.push_back(osg::Texture2D::NEAREST);
        _textList.push_back("Nearest filtering\nsetFilter(MIN_FILTER,NEAREST)\nsetFilter(MAG_FILTER,NEAREST)");

        _minFilterList.push_back(osg::Texture2D::LINEAR);
        _magFilterList.push_back(osg::Texture2D::LINEAR);
        _textList.push_back("Linear filtering\nsetFilter(MIN_FILTER,LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");

        _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_NEAREST);
        _magFilterList.push_back(osg::Texture2D::LINEAR);
        _textList.push_back("nearest mip mapping (default filtering)\nsetFilter(MIN_FILTER,)\nsetFilter(MAG_FILTER,LINEAR)");

        _minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_NEAREST);
        _magFilterList.push_back(osg::Texture2D::LINEAR);
        _textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,LINEAR_MIPMAP_NEAREST)\nsetFilter(MAG_FILTER,LINEAR)");

        _minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_LINEAR);
        _magFilterList.push_back(osg::Texture2D::LINEAR);
        _textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,NEAREST_MIPMAP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");


        setValues();
    }

    virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
    {
        if (nv->getFrameStamp())
        {
            double currTime = nv->getFrameStamp()->getSimulationTime();
            if (currTime-_prevTime>_delay)
            {
                // update filter modes and text.
                setValues();

                // advance the current position, wrap round if required.
                _currPos++;
                if (_currPos>=_minFilterList.size()) _currPos=0;

                // record time
                _prevTime = currTime;
            }
        }
    }

    void setValues()
    {
        _texture->setFilter(osg::Texture2D::MIN_FILTER,_minFilterList[_currPos]);
        _texture->setFilter(osg::Texture2D::MAG_FILTER,_magFilterList[_currPos]);

        _text->setText(_textList[_currPos]);
    }

protected:

    typedef std::vector<osg::Texture2D::FilterMode> FilterList;
    typedef std::vector<std::string>                TextList;

    osg::ref_ptr<osg::Texture2D>    _texture;
    osg::ref_ptr<osgText::Text>     _text;
    double                          _delay;

    FilterList                      _minFilterList;
    FilterList                      _magFilterList;
    TextList                        _textList;

    unsigned int                    _currPos;
    double                          _prevTime;

};

osg::Node* createFilterWall(osg::BoundingBox& bb,osg::Image *img)
{
    osg::Group* group = new osg::Group;

    // left hand side of bounding box.
    osg::Vec3 top_left(bb.xMin(),bb.yMin(),bb.zMax());
    osg::Vec3 bottom_left(bb.xMin(),bb.yMin(),bb.zMin());
    osg::Vec3 bottom_right(bb.xMin(),bb.yMax(),bb.zMin());
    osg::Vec3 top_right(bb.xMin(),bb.yMax(),bb.zMax());
    osg::Vec3 center(bb.xMin(),(bb.yMin()+bb.yMax())*0.5f,(bb.zMin()+bb.zMax())*0.5f);
    float height = bb.zMax()-bb.zMin();

    // create the geometry for the wall.
    osg::Geometry* geom = new osg::Geometry;

    osg::Vec3Array* vertices = new osg::Vec3Array(4);
    (*vertices)[0] = top_left;
    (*vertices)[1] = bottom_left;
    (*vertices)[2] = bottom_right;
    (*vertices)[3] = top_right;
    geom->setVertexArray(vertices);

    osg::Vec2Array* texcoords = new osg::Vec2Array(4);
    (*texcoords)[0].set(0.0f,1.0f);
    (*texcoords)[1].set(0.0f,0.0f);
    (*texcoords)[2].set(1.0f,0.0f);
    (*texcoords)[3].set(1.0f,1.0f);
    geom->setTexCoordArray(0,texcoords);

    osg::Vec3Array* normals = new osg::Vec3Array(1);
    (*normals)[0].set(1.0f,0.0f,0.0f);
    geom->setNormalArray(normals, osg::Array::BIND_OVERALL);

    osg::Vec4Array* colors = new osg::Vec4Array(1);
    (*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
    geom->setColorArray(colors, osg::Array::BIND_OVERALL);

    geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));

    osg::Geode* geom_geode = new osg::Geode;
    geom_geode->addDrawable(geom);
    group->addChild(geom_geode);


    // set up the texture state.
    osg::Texture2D* texture = new osg::Texture2D;
    texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
    texture->setImage(img); //////<-- setting image directly from ptr (original used osgDB::readImageFile() )

    osg::StateSet* stateset = geom->getOrCreateStateSet();
    stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);

    // create the text label.

    osgText::Text* text = new osgText::Text;
    text->setDataVariance(osg::Object::DYNAMIC);

    text->setFont("fonts/arial.ttf");
    text->setPosition(center);
    text->setCharacterSize(height*0.03f);
    text->setAlignment(osgText::Text::CENTER_CENTER);
    text->setAxisAlignment(osgText::Text::YZ_PLANE);

    osg::Geode* text_geode = new osg::Geode;
    text_geode->addDrawable(text);

    osg::StateSet* text_stateset = text_geode->getOrCreateStateSet();
    text_stateset->setAttributeAndModes(new osg::PolygonOffset(-1.0f,-1.0f),osg::StateAttribute::ON);

    group->addChild(text_geode);

    // set the update callback to cycle through the various min and mag filter modes.
    group->setUpdateCallback(new FilterCallback(texture,text));

    return group;

}


osg::Node* createModel()
{

    // create the root node which will hold the model.
    osg::Group* root = new osg::Group();

    // turn off lighting
    root->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);

    osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);

/////////// NEW CODE: ///////////////
      int w=10,h=10;
      GLubyte * pixels=(GLubyte*)calloc(w*h*3,sizeof(GLubyte));
   int pixelCount=0;

   for(int i=0;i<100;i++){
      int x=pixelCount%w;
      int y=int(pixelCount/w);

      int xy = y*w + x;
      //pixels[xy*3]=GLubyte(stoi(tile->ToConstScalarToken()->GetRawData()));
      pixels[xy*3]=GLubyte(unsigned(x<6?180:10));
      pixels[xy*3+1]=0;
      pixels[xy*3+2]=0;

      pixelCount++;
   }
   osg::Image* m_tileDataImg = new osg::Image;
   m_tileDataImg->setImage(w,h,1,GL_RGB,GL_RGB,GL_UNSIGNED_BYTE,pixels,osg::Image::NO_DELETE);
/////////// END NEW CODE: ///////////////

    root->addChild(createFilterWall(bb,m_tileDataImg)); ///// <-- passing image ptr (original code used image filename)

    return root;
}

int main(int , char **)
{
    // construct the viewer.
    osgViewer::Viewer viewer;

    // add model to viewer.
    viewer.setSceneData( createModel() );

    return viewer.run();
}


Note that the filter wall is on the side of the cube, so you have to rotate it before you see anything.

The input image which I am generating is the following (verified by using osgDB::writeImageFile() to output it):


It might be too small to see, but the important part is that it contains only two colors.


The result I get with nearest filtering:

Suddenly there is a band with an intermediate color which is not present in the input.


The expected result (created by editing the screenshot):


I'm not sure how the images translate to the mailing list, so just in case: this is the imgur album containing the three images: https://imgur.com/a/rNFu0

Thank you!

Cheers,
antiro[img][/img]
Back to top
View user's profile Send private message
robertosfield
OSG Project Lead


Joined: 18 Mar 2009
Posts: 11802

PostPosted: Tue Feb 20, 2018 5:32 pm    Post subject:
problem setting texture min/mag filter
Reply with quote

HI Antiro,

Thanks for the code example. I don't have the time to test right
away. A quick code review and I spotted that the image is 10x10 which
will be rescalled to nearest power of two with the default
construction of osg::Texture2D. Most modern hardware supports non
power of two textures so it should be safe to enable this via:

texture->setResizeNonPowerOfTwoHint(false);

Could you try this and let us know how you get on.

Robert.

On 20 February 2018 at 17:10, antiro black <> wrote:
Quote:
Hi,

I made an executable example based on the osgtexture2D example. I removed the code to render the different walls of the cube with the exception of the filter wall. I kept the rest as close to the original as possible. changes to the code have been marked using comments.

Essentially all I'm doing is generating an input image instead of loading one.


Code:

#include <osg/Node>
#include <osg/Geometry>
#include <osg/Notify>
#include <osg/MatrixTransform>
#include <osg/Texture2D>
#include <osg/DrawPixels>
#include <osg/PolygonOffset>
#include <osg/Geode>

#include <osgDB/Registry>
#include <osgDB/ReadFile>

#include <osgText/Text>

#include <osgViewer/Viewer>

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// filter wall and animation callback.
//

class FilterCallback : public osg::NodeCallback
{
public:

FilterCallback(osg::Texture2D* texture,osgText::Text* text,double delay=1.0):
_texture(texture),
_text(text),
_delay(delay),
_currPos(0),
_prevTime(0.0)
{
// start with a mip mapped mode to ensure that
_minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_LINEAR);
_magFilterList.push_back(osg::Texture2D::LINEAR);
_textList.push_back("Tri-linear mip mapping (default filtering)\nsetFilter(MIN_FILTER,LINEAR_MIP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");

_minFilterList.push_back(osg::Texture2D::NEAREST);
_magFilterList.push_back(osg::Texture2D::NEAREST);
_textList.push_back("Nearest filtering\nsetFilter(MIN_FILTER,NEAREST)\nsetFilter(MAG_FILTER,NEAREST)");

_minFilterList.push_back(osg::Texture2D::LINEAR);
_magFilterList.push_back(osg::Texture2D::LINEAR);
_textList.push_back("Linear filtering\nsetFilter(MIN_FILTER,LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");

_minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_NEAREST);
_magFilterList.push_back(osg::Texture2D::LINEAR);
_textList.push_back("nearest mip mapping (default filtering)\nsetFilter(MIN_FILTER,)\nsetFilter(MAG_FILTER,LINEAR)");

_minFilterList.push_back(osg::Texture2D::LINEAR_MIPMAP_NEAREST);
_magFilterList.push_back(osg::Texture2D::LINEAR);
_textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,LINEAR_MIPMAP_NEAREST)\nsetFilter(MAG_FILTER,LINEAR)");

_minFilterList.push_back(osg::Texture2D::NEAREST_MIPMAP_LINEAR);
_magFilterList.push_back(osg::Texture2D::LINEAR);
_textList.push_back("bi-linear mip mapping\nsetFilter(MIN_FILTER,NEAREST_MIPMAP_LINEAR)\nsetFilter(MAG_FILTER,LINEAR)");


setValues();
}

virtual void operator()(osg::Node*, osg::NodeVisitor* nv)
{
if (nv->getFrameStamp())
{
double currTime = nv->getFrameStamp()->getSimulationTime();
if (currTime-_prevTime>_delay)
{
// update filter modes and text.
setValues();

// advance the current position, wrap round if required.
_currPos++;
if (_currPos>=_minFilterList.size()) _currPos=0;

// record time
_prevTime = currTime;
}
}
}

void setValues()
{
_texture->setFilter(osg::Texture2D::MIN_FILTER,_minFilterList[_currPos]);
_texture->setFilter(osg::Texture2D::MAG_FILTER,_magFilterList[_currPos]);

_text->setText(_textList[_currPos]);
}

protected:

typedef std::vector<osg::Texture2D::FilterMode> FilterList;
typedef std::vector<std::string> TextList;

osg::ref_ptr<osg::Texture2D> _texture;
osg::ref_ptr<osgText::Text> _text;
double _delay;

FilterList _minFilterList;
FilterList _magFilterList;
TextList _textList;

unsigned int _currPos;
double _prevTime;

};

osg::Node* createFilterWall(osg::BoundingBox& bb,osg::Image *img)
{
osg::Group* group = new osg::Group;

// left hand side of bounding box.
osg::Vec3 top_left(bb.xMin(),bb.yMin(),bb.zMax());
osg::Vec3 bottom_left(bb.xMin(),bb.yMin(),bb.zMin());
osg::Vec3 bottom_right(bb.xMin(),bb.yMax(),bb.zMin());
osg::Vec3 top_right(bb.xMin(),bb.yMax(),bb.zMax());
osg::Vec3 center(bb.xMin(),(bb.yMin()+bb.yMax())*0.5f,(bb.zMin()+bb.zMax())*0.5f);
float height = bb.zMax()-bb.zMin();

// create the geometry for the wall.
osg::Geometry* geom = new osg::Geometry;

osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = top_left;
(*vertices)[1] = bottom_left;
(*vertices)[2] = bottom_right;
(*vertices)[3] = top_right;
geom->setVertexArray(vertices);

osg::Vec2Array* texcoords = new osg::Vec2Array(4);
(*texcoords)[0].set(0.0f,1.0f);
(*texcoords)[1].set(0.0f,0.0f);
(*texcoords)[2].set(1.0f,0.0f);
(*texcoords)[3].set(1.0f,1.0f);
geom->setTexCoordArray(0,texcoords);

osg::Vec3Array* normals = new osg::Vec3Array(1);
(*normals)[0].set(1.0f,0.0f,0.0f);
geom->setNormalArray(normals, osg::Array::BIND_OVERALL);

osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
geom->setColorArray(colors, osg::Array::BIND_OVERALL);

geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4));

osg::Geode* geom_geode = new osg::Geode;
geom_geode->addDrawable(geom);
group->addChild(geom_geode);


// set up the texture state.
osg::Texture2D* texture = new osg::Texture2D;
texture->setDataVariance(osg::Object::DYNAMIC); // protect from being optimized away as static state.
texture->setImage(img); //////<-- setting image directly from ptr (original used osgDB::readImageFile() )

osg::StateSet* stateset = geom->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute:ShockedN);

// create the text label.

osgText::Text* text = new osgText::Text;
text->setDataVariance(osg::Object::DYNAMIC);

text->setFont("fonts/arial.ttf");
text->setPosition(center);
text->setCharacterSize(height*0.03f);
text->setAlignment(osgText::Text::CENTER_CENTER);
text->setAxisAlignment(osgText::Text::YZ_PLANE);

osg::Geode* text_geode = new osg::Geode;
text_geode->addDrawable(text);

osg::StateSet* text_stateset = text_geode->getOrCreateStateSet();
text_stateset->setAttributeAndModes(new osg::PolygonOffset(-1.0f,-1.0f),osg::StateAttribute:ShockedN);

group->addChild(text_geode);

// set the update callback to cycle through the various min and mag filter modes.
group->setUpdateCallback(new FilterCallback(texture,text));

return group;

}


osg::Node* createModel()
{

// create the root node which will hold the model.
osg::Group* root = new osg::Group();

// turn off lighting
root->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);

osg::BoundingBox bb(0.0f,0.0f,0.0f,1.0f,1.0f,1.0f);

/////////// NEW CODE: ///////////////
int w=10,h=10;
GLubyte * pixels=(GLubyte*)calloc(w*h*3,sizeof(GLubyte));
int pixelCount=0;

for(int i=0;i<100;i++){
int x=pixelCount%w;
int y=int(pixelCount/w);

int xy = y*w + x;
//pixels[xy*3]=GLubyte(stoi(tile->ToConstScalarToken()->GetRawData()));
pixels[xy*3]=GLubyte(unsigned(x<6?180:10));
pixels[xy*3+1]=0;
pixels[xy*3+2]=0;

pixelCount++;
}
osg::Image* m_tileDataImg = new osg::Image;
m_tileDataImg->setImage(w,h,1,GL_RGB,GL_RGB,GL_UNSIGNED_BYTE,pixels,osg::Image::NO_DELETE);
/////////// END NEW CODE: ///////////////

root->addChild(createFilterWall(bb,m_tileDataImg)); ///// <-- passing image ptr (original code used image filename)

return root;
}

int main(int , char **)
{
// construct the viewer.
osgViewer::Viewer viewer;

// add model to viewer.
viewer.setSceneData( createModel() );

return viewer.run();
}




Note that the filter wall is on the side of the cube, so you have to rotate it before you see anything.

The input image which I am generating is the following (verified by using osgDB::writeImageFile() to output it):

[Image: https://i.imgur.com/8YUX0UD.png ]
It might be too small to see, but the important part is that it contains only two colors.


The result I get with nearest filtering:
[Image: https://i.imgur.com/h6MIpI9.png ]
Suddenly there is a band with an intermediate color which is not present in the input.


The expected result (created by editing the screenshot):
[Image: https://i.imgur.com/Plew0gD.png ]

I'm not sure how the images translate to the mailing list, so just in case: this is the imgur album containing the three images: https://imgur.com/a/rNFu0

Thank you!

Cheers,
antiro[img][/img]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=72972#72972








------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
antiro42
User


Joined: 01 Sep 2017
Posts: 46

PostPosted: Tue Feb 20, 2018 6:35 pm    Post subject:
Reply with quote

Hi Robertos,

setting "texture->setResizeNonPowerOfTwoHint(false);" fixed the problem....

After being stuck on this problem for more than a week I can safely say that I would never have found that without your help. I checked the data after generating the image at which point it was still OK, but found problems when it was sampled in the shader, which is why expected a problem with the sampling.

Being new to OSG (and used to pure openGL) I hadn't realized that OSG would be modifying the data before it got to the graphics card so I was looking in the wrong place.

So, thanks again! You saved me many more days of hitting my head against the wall!

Cheers,
antiro
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum

Similar Topics
Topic Author Forum Replies Posted
No new posts osgText: problem with SCREEN_COORDS mode gwaldron General 9 Thu May 17, 2018 3:56 pm View latest post
No new posts Setting OpenGL and graphics card sett... Chris Hanson General 2 Thu May 10, 2018 6:16 pm View latest post
No new posts DXT texture compression urbanchaos General [forum] 9 Tue May 08, 2018 12:13 pm View latest post
No new posts [customizing manipulator] problem wit... mp3butcher General 1 Tue Apr 24, 2018 3:19 pm View latest post
No new posts How do I create a graphics context on... srinivas General 3 Tue Apr 24, 2018 11:40 am View latest post


Board Security Anti Bot Question MOD - phpBB MOD against Spam Bots
Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP