Skip to content

Instantly share code, notes, and snippets.

@Kaminate
Last active March 25, 2016 22:48
Show Gist options
  • Save Kaminate/9363745 to your computer and use it in GitHub Desktop.
Save Kaminate/9363745 to your computer and use it in GitHub Desktop.
Shader storage buffer
void GraphicsSystem::VoxelizeScene() const
{
auto compSet = GetComponentSet(Comp::eCompModel);
if (compSet.empty())
return;
if (!mCurrentCamera)
return;
// voxelize scene
const Window & wind = GetCore()->GetWindow();
glViewport(0, 0, wind.GetWidth(), wind.GetHeight());
mShaderVoxelFrags.Activate();
glDrawBuffer(GL_NONE);
GLuint zero = 0;
glBufferSubData(
GL_ATOMIC_COUNTER_BUFFER,
0,
sizeof(GLuint),
&zero);
glUniform1ui(mShaderVoxelFrags.mMaxFrags, mMaxNumFragments);
Matrix4 view = mCurrentCamera->mCamera.GetViewMatrix();
Matrix4 proj = mCurrentCamera->mCamera.GetPerspectiveProjMatrix();
glUniformMatrix4fv(mShaderVoxelFrags.mView, 1, GL_TRUE, view.v);
glUniformMatrix4fv(mShaderVoxelFrags.mProj, 1, GL_TRUE, proj.v);
for (SPComp comp: compSet)
{
ModelComponent * iModel = (ModelComponent*) comp.get();
Matrix4 world;
TransformComp * iTransform
= (TransformComp*) comp->GetSibling(Comp::Type::eCompTransform);
if (iTransform)
world = iTransform->mFakeTransform;
glUniformMatrix4fv(mShaderVoxelFrags.mWorl, 1, GL_TRUE, world.v);
// color
const Vector4 & c = iModel->mColor;
glUniform4f(mShaderVoxelFrags.mCol, c.x, c.y, c.z, c.w);
if(Geometry * geom = iModel->GetGeometry())
{
geom->SendAttribute(Geometry::Position, mShaderVoxelFrags.mPos);
geom->Draw();
}
} // draw each model
mShaderVoxelFrags.Deactivate();
glDrawBuffer(GL_BACK);
glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
void * ptr = glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
GLuint numIncrements = *reinterpret_cast<GLuint*>(ptr);
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
unsigned numPixelsToDraw = std::min(numIncrements, mMaxNumFragments);
mShaderPixels.Activate();
// You could also use the storage buffer contents for vertex pulling.
// The glMemoryBarrier() command ensures that the data writes to the
// storage buffer complete prior to vertex pulling.
glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, mFragmentBuffer);
glVertexAttribPointer(
mShaderPixels.mPos,
3,
GL_FLOAT,
GL_FALSE,
sizeof(Frag),
(void*)offsetof(Frag, Frag::fragPos));
glVertexAttribPointer(
mShaderPixels.mCol,
4, // 4 components in vec4
GL_FLOAT,
GL_FALSE,
sizeof(Frag),
(void*)offsetof(Frag, Frag::fragCol));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUniformMatrix4fv(mShaderPixels.mView, 1, GL_TRUE, view.v);
glUniformMatrix4fv(mShaderPixels.mProj, 1, GL_TRUE, proj.v);
// create a tweak bar for the pointsize
static float pointSize = 4.0f;
static bool once = true;
if (once)
{
once = false;
static SPTweakBar bar = GetCore()->GetTweak().Create();
bar->Init("Pixel");
bar->AddVar(
"glPointSize",
"label='glPointSize' "
"precision=1 "
"step=.5 ",
TW_TYPE_FLOAT,
&pointSize);
}
glPointSize(pointSize);
glDrawArrays(GL_POINTS, 0, numPixelsToDraw);
mShaderPixels.Deactivate();
CheckOpenGLErrors();
}
#version 430
in vec4 vColor;
out vec4 outColor;
void main()
{
outColor = vColor;
}
#version 430
struct FragmentData
{
vec3 fragPos; // worldspace
uint padding;
vec4 fragColor; // must be aligned on
};
layout(std140, binding = 0) buffer Fragments
{
FragmentData fragments[];
// i would like to put the fragmentCounter in here too
// but i cant fiugre out how
};
// what is offset?
layout(binding = 1, offset = 0) uniform atomic_uint fragmentCounter;
layout(location = 6) uniform vec4 color;
layout(location = 7) uniform uint maxFrags;
in VoxelData {
vec3 wsPos;
} In;
void main()
{
uint priorFragmentNumber = atomicCounterIncrement(fragmentCounter);
if (priorFragmentNumber < maxFrags)
{
fragments[priorFragmentNumber].fragPos = In.wsPos;
fragments[priorFragmentNumber].fragColor = color;
fragments[priorFragmentNumber].padding = 0; // temp
}
}
#version 430
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in VertexData
{
vec3 wsPos;
} Input[3];
out VoxelData
{
vec3 wsPos;
} Output;
layout(location = 4) uniform mat4 view;
layout(location = 5) uniform mat4 proj;
void main()
{
for (uint i = 0; i < gl_in.length(); ++i)
{
gl_Position = proj * view * vec4(Input[i].wsPos, 1.0);
Output.wsPos = Input[i].wsPos;
EmitVertex();
}
EndPrimitive();
}
#version 430
layout(location = 0) in vec3 position;
layout(location = 2) uniform mat4 world;
out VertexData {
vec3 wsPos; // worldspace
} Output;
void main(void)
{
Output.wsPos = (world * vec4(position, 1)).xyz;
// note: gl_Position handled by geometry shader
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment