43 #include <ACG/GL/acg_glew.hh>
45 #include "OITLinkedList.hh"
51 #include <ACG/GL/ShaderCache.hh>
52 #include <ACG/GL/ScreenQuad.hh>
54 #include <ACG/GL/GLError.hh>
110 _shader->
addUniform(
"layout(binding = 0, offset = 0) uniform atomic_uint g_FragmentCounter");
111 _shader->
addUniform(
"layout(binding = 0, r32ui) uniform uimageBuffer g_StartOffsetBuffer");
112 _shader->
addUniform(
"layout(binding = 1, rgba32ui) uniform uimageBuffer g_ABuffer");
115 _shader->
addUniform(
"uniform uvec2 g_ScreenSize");
125 _code->push_back(
"uint uiColor = packUnorm4x8(outFragment);");
128 _code->push_back(
"uint uiDepth = floatBitsToUint(gl_FragCoord.z);");
133 _code->push_back(
"uint uiFragCount = atomicCounterIncrement(g_FragmentCounter);");
136 _code->push_back(
"uvec2 absFragCoord = uvec2(gl_FragCoord.xy);");
137 _code->push_back(
"uint uiPixelID = absFragCoord.x + uint(g_ScreenSize.x) * absFragCoord.y;");
142 _code->push_back(
"uint uiNextFragment = imageAtomicExchange(g_StartOffsetBuffer, int(uiPixelID), uiFragCount);");
145 _code->push_back(
"imageStore(g_ABuffer, int(uiFragCount), uvec4(uiColor, uiDepth, uiNextFragment, uint(gl_SampleMaskIn[0])) );");
159 OITLinkedList::OITLinkedList()
164 OITLinkedList::~OITLinkedList()
169 void OITLinkedList::initializePlugin()
190 void OITLinkedList::prepareBuffers(
int w,
int h)
195 const int estAvgLayers = 3;
197 const int numPixels = w * h;
198 const int offsetBufSize = numPixels * 4;
199 const int ABufSize = numPixels * 16 * estAvgLayers;
201 if (startOffsetBuffer_.getBufferSize() < offsetBufSize)
202 startOffsetBuffer_.setBufferData(offsetBufSize, 0, GL_R32UI, GL_DYNAMIC_DRAW);
204 if (ABuffer_.getBufferSize() < ABufSize)
205 ABuffer_.setBufferData(ABufSize, 0, GL_RGBA32UI, GL_DYNAMIC_DRAW);
209 glBindTexture(GL_TEXTURE_BUFFER, 0);
215 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
218 void OITLinkedList::renderOIT(
int w,
int h,
bool multisampled)
222 prepareBuffers(w, h);
227 glColorMask(0, 0, 0, 0);
229 glDisable(GL_DEPTH_TEST);
234 startOffsetBuffer_.bindAsImage(0, GL_WRITE_ONLY);
238 shaderReset->
setUniform(
"g_ScreenSize", screenSize);
247 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT);
258 glDisable(GL_SAMPLE_SHADING);
259 glEnable(GL_MULTISAMPLE);
260 glMinSampleShading(0.0f);
263 int msaaSampleCount = 1;
264 glGetIntegerv(GL_SAMPLES, &msaaSampleCount);
267 startOffsetBuffer_.bindAsImage(0, GL_READ_WRITE);
268 ABuffer_.bindAsImage(1, GL_WRITE_ONLY);
271 fragCounter_.bind(0);
281 shaderRender->
setUniform(
"g_ScreenSize", screenSize);
285 obj->glColorMask(0,0,0,0);
286 obj->depthTest =
false;
287 obj->depthWrite =
false;
288 obj->culling =
false;
293 fragCounter_.unbind();
297 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT);
302 glColorMask(1, 1, 1, 1);
309 glEnable(GL_SAMPLE_SHADING);
310 glEnable(GL_MULTISAMPLE);
311 glMinSampleShading(1.0f);
314 glGetIntegerv(GL_SAMPLES, &msaaSampleCount);
317 glDepthFunc(GL_ALWAYS);
324 QStringList shaderMacros;
326 shaderMacros.push_back(
"#define OITLL_MSAA");
332 shaderResolve->
use();
334 startOffsetBuffer_.bindAsImage(0, GL_READ_ONLY);
335 ABuffer_.bindAsImage(1, GL_READ_ONLY);
337 shaderResolve->
setUniform(
"g_ScreenSize", screenSize);
340 shaderResolve->
setUniform(
"g_SampleCount", GLuint(msaaSampleCount));
351 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
357 glDisable(GL_SAMPLE_SHADING);
358 glMinSampleShading(0.0f);
363 const int numBoundImages = 3;
365 for (
int i = 0; i < numBoundImages; ++i)
366 glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
371 unsigned int actualFragmentCount = 0;
373 fragCounter_.get(&actualFragmentCount);
378 if (
int(actualFragmentCount) * 16 > ABuffer_.getBufferSize())
380 ABuffer_.setBufferData(actualFragmentCount * 18, 0, ABuffer_.getFormat(), ABuffer_.getUsage());
388 QString OITLinkedList::checkOpenGL()
392 return QString(
"Insufficient OpenGL Version! OpenGL 4.2 or higher required");
395 QString glExtensions = QString((
const char*)glGetString(GL_EXTENSIONS));
397 if ( !glExtensions.contains(
"ARB_shader_image_load_store") )
398 missing +=
"ARB_shader_image_load_store extension missing\n";
400 if ( !glExtensions.contains(
"GL_ARB_shader_atomic_counters") )
401 missing +=
"GL_ARB_shader_atomic_counters extension missing\n";
403 if ( !glExtensions.contains(
"GL_ARB_gpu_shader5") )
404 missing +=
"GL_ARB_gpu_shader5 extension missing\n";
412 std::vector<ACG::ShaderModifier*> mods;
413 mods.push_back(&ABufferGenModifier::instance);
417 #if QT_VERSION < 0x050000
int viewport_width() const
get viewport width
QString renderObjectsInfo(bool _outputShaderInfo)
Return a qstring of the current render objects.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
virtual void finishRenderingPipeline(bool _drawOverlay=true)
Draw overlay objects and reset OpenGL state.
void setGLSLVersion(int _version)
Set glsl version.
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
std::vector< ACG::RenderObject * > sortedObjects_
sorted list of renderobjects without overlay objects (sorted in rendering order)
virtual QString dumpCurrentRenderObjectsToString(ACG::RenderObject **_list=0, bool _outputShaders=false, std::vector< ACG::ShaderModifier * > *_modifiers=0)
Outputs the current render objects to the string.
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
static void setShaderDir(QString _dir)
void multisampling(bool _state)
set multisampling on/off
bool openGLVersion(const int _major, const int _minor)
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
ACG::RenderObject * getRenderObject(int i)
Get render objects in the sorted list by index (not including overlay objects)
virtual void renderObject(ACG::RenderObject *_obj, GLSL::Program *_prog=0, bool _constRenderStates=false, const std::vector< unsigned int > *_shaderModifiers=0)
Render one renderobject.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
VectorT< unsigned int, 2 > Vec2ui
int viewport_height() const
get viewport height
int getNumRenderObjects() const
Get the number of collected render objects (not including overlay objects or gl4.2 line objects) ...
virtual void prepareRenderingPipeline(ACG::GLState *_glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode *_scenegraphRoot)
Prepares renderer and OpenGL for any draw-related calls including.
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
Interface class between scenegraph and renderer.
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
void use()
Enables the program object for using.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void modifyFragmentIO(ACG::ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.