Hi,
I recently checked out the newest development release of OSG (version 3.1.5).
After playing around with the osgatomiccounter and osgcomputeshader examples I
tried to implement order independent transparency with per pixel linked lists
as mentioned in this presentation: click!
(https://graphics.stanford.edu/wikis/cs448s-10/FrontPage?action=AttachFile&do=get&target=CS448s-10-11-oit.pdf).
I started with creating an atomic counter as "pointer" to the next free heap
block and a shader image(ARB_shader_image_load_store) to save the "pointer" to
the end of the linked lists. So my first version of the programm should only
increment the heap pointer for each fragment that is drawn and then store it in
the image at the fragments screen space position. There is no visualization of
this image on the screen, yet.
But sadly this first simple example isn't working and I don't know where the
problem is. I get this error: "Warning: OpenGL error detected: out of memory at
start of state apply".
Most of the code is copied from osgatomicbuffers(atomic buffer creation,
reading and resetting) and osgcomputershaders(creating the shader image).
I create the image with the following code:
Code:
// create image for the end of the linked list
osg::ref_ptr<osg::Texture2D> endTex2D = new osg::Texture2D;
endTex2D->setTextureSize(800, 600);
endTex2D->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
endTex2D->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
endTex2D->setInternalFormat(GL_R32UI);
endTex2D->setSourceFormat(GL_RED);
endTex2D->setSourceType(GL_UNSIGNED_INT);
endTex2D->bindToImageUnit(1, osg::Texture::READ_WRITE); // So we can use
'image2D' in the fragment shader
ss->setTextureAttribute(1, endTex2D.get(), osg::StateAttribute::ON);
ss->addUniform(new osg::Uniform("endTex", 1));
And here is my fragment shader code:
Code:
#version 430 compatibility
layout(binding = 0) uniform atomic_uint acHeapPointer;
layout(R32UI) uniform uimage2D endTex;
uniform uint maxFragments;
void main(void)
{
// get a position to write in the heap
uint heapPointer = atomicCounterIncrement(acHeapPointer);
ivec2 texCoord = ivec2(gl_FragCoord.xy);
ivec2 imgSize = imageSize(endTex);
// skip fragment if the heap is to small (gets increased in the next frame) or
the coordinate is out of texture bounds
if (heapPointer >= maxFragments || texCoord.x >= imgSize.x ||texCoord.y >=
imgSize.y || texCoord.x < 0 || texCoord.y < 0)
discard;
// exchange old linked list end with new one, and store values on the heaps
uint oldEnd = imageAtomicExchange(endTex, ivec2(gl_FragCoord.xy), heapPointer);
// write something doesnt matter anyway
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
To resize the shader image to with the viewport size I use the following
CullCallback:
Code:
class UpdateTextureResolution : public osg::NodeCallback {
public:
UpdateTextureResolution(osg::ref_ptr<osg::Texture2D> endTex)
{
_endTex = endTex;
_oldViewport = new osg::Viewport();
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
osgUtil::CullVisitor* cullVisitor = static_cast<osgUtil::CullVisitor*>(nv);
osgUtil::RenderStage* renderStage = cullVisitor->getCurrentRenderStage();
const osg::Viewport* viewport = renderStage->getViewport();
if (*_oldViewport != *viewport) {
_oldViewport = new osg::Viewport(*viewport);
_endTex->setTextureSize((int)viewport->width(), (int)viewport->height());
_endTex->dirtyTextureObject();
_endTex->dirtyTextureParameters(); // I don't know if this is necessary, I was
trying to find the problem
}
}
private:
osg::ref_ptr<osg::Texture2D> _endTex;
osg::ref_ptr<osg::Viewport> _oldViewport;
};
I don't know what the problem is. Am I doing something wrong when resizing the
texture?
I would be very grateful if someone could help me with my problem.
Thank you!
Cheers,
Marcel
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=53772#53772
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org