Hello Sebastian
> Can you explain the need for the FakeGLBeginEndAdapter?
> I guess it is needed for ShapeDrawables only?
Yes. It's only for ShapeDrawables.
I tried to find the best way to convert osg::Shape into osg::Geometry
without reinventing the wheel.
And in OSG I found a class named DrawShapeVisitor, which does perfectly what I
want,
but from my point of view, it has two drawbacks :
- it directly sends vertices to rendering through the osg::GLBeginEndAdapter.
- it is defined in a file ShapeDrawable.cpp so I cannot include it from the
application
So I wrote ShapeToGeometryVisitor ( which is a copy of DrawShapeVisitor, with
major changes in the End() method ) and FakeGLBeginEndAdapter that derives
from osg::GLBeginEndAdapter.
FakeGLBeginEndAdapter stores incoming vertices into the osg::Geometry object
instead of calling glDrawArrays() like osg::GLBeginEndAdapter does.
> I've tried to load a model and place it instead of the shapes.
> It worked somehow, but I'm not sure if it really works.
> Is there some limitation to the models which can be used for instancing?
When I was writing that code, I was aware that different models
will be used as an input. That's why I implemented model
merging/conversion in a modular way.
All models must be merged into a single osg::Geometry.
This work is performed by AggregateGeometryVisitor which uses
ConvertTrianglesOperator descendant to perform merging/conversion.
In osggpucull I implemented and used class ConvertTrianglesOperatorClassic
which merges vertices, colors, normals and texture coordinates from unit 0.
If your models look wrong, it is probably an error in method setGeometryData()
( it may be some dynamic_cast<> returning NULL, I guess. Cannot tell more
without inspecting the model in the debugger ).
I don't remember any limitations to the input models at the moment.
You may implement any classes derived from ConvertTrianglesOperator as long
as generated geometries have typeID and lodNumber in vertex attributes.
Of course - drawing vertex shader should be modified to use these vertex
attributes.
> Following your second comment on the submission you mentioned binding
> textures via "bindImageToUnit".
> I've struggled with this a bit. It would be nice if you could provide
> some hint where to bind it and how. (I'm not that experienced with the
> OpenGL 4.x features)
Oh sorry. I mistaken the method name from osg::Texture.
Its name is bindToImageUnit(), not bindImageToUnit() :D
Anyway, I'll write some more compehensive explanation for those
who want to know, what the "image unit" is.
Until OpenGL 4.2 shaders could only read data from textures
using GLSL functions like texelFetch(), or texture*().
Revolutionary ARB_shader_image_load_store extension from OpenGL 4.2
introduced possibility to write to textures directly in the shader
( this feature was added specially for compute shaders, but works
with any other types of shader as well : vertex, fragment etc. ).
Such writable textures are named "image units" in that extension
( or just "images", but I will call them "image units" because
"image" may be easily mistaken with osg::Image ).
"Image units" came with its own set of GLSL functions :
- imageLoad() - which works exactly the same as texelFetch()
- imageStore() - which writes to "image unit"
- imageAtomic*() functions that perform atomic operations over the "image unit"
( imageAtomicAdd(), imageAtomicMin(), imageAtomicMax() etc. )
"Image unit" must be declared in the shader similarly the texture is declared.
Let's see how it works in OpenSceneGraph :
Our example vertex shader declares one "image unit" named myImage
with one 32-bit integer channel :
layout(R32I) uniform iimageBuffer myImage;
In C++ code, similarly to textures, we must add an uniform that associates name
"myImage" with "image unit" index :
osg::Uniform* uniform = new osg::Uniform("myImage", 0 );
stateset->addUniform( uniform );
We must also add the texture itself. For example :
stateset->setTextureAttribute( 2, texture.get() );
The last thing to do is to inform the texture which "image unit" index does it
use :
texture->bindToImageUnit(0, osg::Texture::READ_WRITE);
Final result : texture is bound to texture unit = 2 and to image unit=0.
Now we may use imageLoad()/imageStore()/imageAtomic*() operations in the shader.
Problem arises when we reuse "image unit" 0 with different texture in another
shader,
because "image unit" binding ( function glBindImageTexture() ) is called only
on
first osg::Texture::apply() or when dirtyTextureParams() was called.
--
Pawel Ksiezopolski
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=58218#58218
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org