vendredi 24 juin 2016

How to make align objects, autorotated to screen, to pixel grid?


I'm trying to show a rectangular object so that it doesn't change its look on rotations and zoom in OpenSceneGraph. I've found that osg::AutoTransform should work for me. But with the following code it appears to give broken results even if I set texture filters to NEAREST instead of default LINEAR. With LINEAR the result is simply blurry, but with NEAREST it sometimes lacks some texel lines. #include <osg/Node> #include <osgViewer/Viewer> #include <osg/Texture2D> #include <osg/Geode> #include <osg/AutoTransform> osg::ref_ptr<osg::Node> createFixedSizeTexture(osg::Image *image,int W,int H) { osg::Vec3Array& verts = *new osg::Vec3Array(4); verts[0] = osg::Vec3(-W/2., -H/2., 0); verts[1] = osg::Vec3(+W/2., -H/2., 0); verts[2] = osg::Vec3(+W/2., +H/2., 0); verts[3] = osg::Vec3(-W/2., +H/2., 0); osg::Vec2Array& texcoords = *new osg::Vec2Array(4); texcoords[0].set(0,0); texcoords[1].set(1,0); texcoords[2].set(1,1); texcoords[3].set(0,1); osg::Geometry*const geometry = new osg::Geometry; geometry->setVertexArray( &verts ); geometry->setTexCoordArray(0, &texcoords); geometry->addPrimitiveSet( new osg::DrawArrays(GL_QUADS, 0, 4)); osg::Texture2D*const texture = new osg::Texture2D( image ); texture->setResizeNonPowerOfTwoHint(false); geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); osg::Geode*const geode = new osg::Geode; geode->addDrawable( geometry ); return geode; } int main() { static constexpr int W=21, H=15; unsigned bits[W*H]; for(int x=0;x<W;++x) for(int y=0;y<H;++y) bits[x+W*y] = (x&y&1)*0xffffffff; osg::Image *formImage = new osg::Image; formImage->setImage(W, H, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<unsigned char*>(bits), osg::Image::NO_DELETE); osg::AutoTransform *at = new osg::AutoTransform; at->setAutoScaleToScreen(true); at->setAutoRotateMode( osg::AutoTransform::ROTATE_TO_SCREEN ); at->addChild(createFixedSizeTexture(formImage,W,H)); osgViewer::Viewer viewer; viewer.setUpViewInWindow(0, 0, 800, 600); viewer.setSceneData(at); return viewer.run(); } This is due to non-integer screen coordinates of the final object. So to fix this I'll have to align the object to pixel grid. How can I achieve this?

Aucun commentaire:

Enregistrer un commentaire