void GL3ProgramObjectProvider::set_storage_buffer_index(int buffer_index, int bind_unit_index)
{
	throw_if_disposed();
	if (buffer_index == -1 )
		return;
	glShaderStorageBlockBinding(handle, buffer_index, bind_unit_index);
}
Exemple #2
0
// Simple function for getting some uniform / shader storage attached to a shader. Should ideally be split up for more
// flexibility.
uint UniformBufferObject(Shader *sh, const float *data, size_t len, const char *uniformblockname, bool ssbo)
{
    GLuint bo = 0;
    #if !defined(PLATFORM_ES2) && !defined(__APPLE__)
        if (sh && glGetProgramResourceIndex && glShaderStorageBlockBinding && glBindBufferBase &&
                  glUniformBlockBinding && glGetUniformBlockIndex)
        {
            sh->Activate();
            auto idx = ssbo ? glGetProgramResourceIndex(sh->program, GL_SHADER_STORAGE_BLOCK, uniformblockname)
                            : glGetUniformBlockIndex(sh->program, uniformblockname);
            if (idx != GL_INVALID_INDEX)
            {
                auto type = ssbo ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER;
                glGenBuffers(1, &bo);
                glBindBuffer(type, bo);
                glBufferData(type, sizeof(float) * len, data, GL_STATIC_DRAW);
                glBindBuffer(type, 0);
                static GLuint bo_binding_point_index = 0;
                bo_binding_point_index++;  // FIXME: how do we allocate these properly?
                glBindBufferBase(type, bo_binding_point_index, bo);
                if (ssbo) glShaderStorageBlockBinding(sh->program, idx, bo_binding_point_index);
                else      glUniformBlockBinding      (sh->program, idx, bo_binding_point_index);
            }
        }
    #else
        // UBO's are in ES 3.0, not sure why OS X doesn't have them
    #endif
    return bo;
}
static int lite3d_shader_program_ssbo_set(
    lite3d_shader_program *program, lite3d_shader_parameter_container *p)
{
    SDL_assert(program);
    SDL_assert(program->success == LITE3D_TRUE);
    SDL_assert(p->parameter->parameter.vbo);

    /* -1  mean what location unknown yet */
    if (p->location == -1)
    {
        p->location = glGetProgramResourceIndex(program->programID, 
            GL_SHADER_STORAGE_BLOCK, p->parameter->name);
        if (p->location < 0)
        {
            p->location = -2;
            SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
                "%s: resource block '%s' not found in program %p",
                LITE3D_CURRENT_FUNCTION, p->parameter->name, (void *)program);
            return LITE3D_FALSE;
        }
    }
    else if (p->location == -2)
        return LITE3D_FALSE;
    
    if (p->binding < 0)
    {
        p->binding = p->bindContext->blockBindingsCount++;
        glShaderStorageBlockBinding(program->programID, p->location, p->binding);
    }
    
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, p->binding, p->parameter->parameter.vbo->vboID);
    return LITE3D_TRUE;
}
Exemple #4
0
void Program::setShaderStorageBlockBinding(const GLuint storageBlockIndex, const GLuint storageBlockBinding) const
{
	checkDirty();
    if (!m_linked)
        return;

    glShaderStorageBlockBinding(id(), storageBlockIndex, storageBlockBinding);
}
Exemple #5
0
void RendererServiceAddVoxel::glResourcesCreated(const GLResourceConfiguration& glResources)
{
	glUseProgram(m_program);

	m_uniformSelectedVoxelSSBOStorageBlock = glGetProgramResourceIndex(m_program, GL_SHADER_STORAGE_BLOCK, "SelectVoxelData");
	glShaderStorageBlockBinding(m_program, m_uniformSelectedVoxelSSBOStorageBlock, GLResourceConfiguration::m_selectedVoxelSSBOBindingPointIndex);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, GLResourceConfiguration::m_selectedVoxelSSBOBindingPointIndex, glResources.m_selectedVoxelSSBO);

	glUseProgram(0);
}
Exemple #6
0
static void
setup_ubos(void)
{
	static const char *names[NUM_SSBOS] = {
		"ssbo_pos_size",
		"ssbo_color",
		"ssbo_rot"
	};
	static GLubyte zeros[1000] = {0};
	int i;

	glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &alignment);
	printf("GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = %d\n", alignment);

	if (test_buffer_offset) {
		printf("Testing buffer offset %d\n", alignment);
	}
	else {
		/* we use alignment as the offset */
		alignment = 0;
	}

	glGenBuffers(NUM_SSBOS, buffers);

	for (i = 0; i < NUM_SSBOS; i++) {
		GLint index, size;

		/* query SSBO index */
		index = glGetProgramResourceIndex(prog,
						  GL_SHADER_STORAGE_BLOCK,
						  names[i]);

		GLenum prop = GL_BUFFER_DATA_SIZE;
		/* query SSBO size */
		glGetProgramResourceiv(prog, GL_SHADER_STORAGE_BLOCK, index,
				       1, &prop, 1, NULL, &size);

		printf("SSBO %s: index = %d, size = %d\n",
		       names[i], index, size);

		/* Allocate SSBO */
		glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[i]);
		glBufferData(GL_SHADER_STORAGE_BUFFER, size + alignment,
                             zeros, GL_DYNAMIC_DRAW);

		/* Attach SSBO */
		glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, buffers[i],
				  alignment,  /* offset */
				  size);
		glShaderStorageBlockBinding(prog, index, i);

		if (!piglit_check_gl_error(GL_NO_ERROR))
			piglit_report_result(PIGLIT_FAIL);
	}
}
Exemple #7
0
    ComputeSHShader()
    {
        std::ifstream fsin("../examples/shaders/computesh.comp", std::ios::in);
        const std::string &fs = std::string((std::istreambuf_iterator<char>(fsin)), std::istreambuf_iterator<char>());
        Program = ProgramShaderLoading::LoadProgram(
                      GL_COMPUTE_SHADER, fs.c_str());

        AssignSamplerNames(Program, "DATA", "probe");
        GLuint SHblock = glGetProgramResourceIndex(Program, GL_SHADER_STORAGE_BLOCK, "SH");
        glShaderStorageBlockBinding(Program, SHblock, 0);
    }
Exemple #8
0
void        
program::set_shaderstoragebuffer(char const* varname, shaderstoragebuffer& ssbo, unsigned binding_point) const
{
  GLuint location = glGetProgramResourceIndex(id_, GL_SHADER_STORAGE_BLOCK, varname);

  if (location == GL_INVALID_INDEX) {
    BOOST_LOG_TRIVIAL(warning) << "program::set_shaderstoragebuffer(): " << varname << "not found in program.\n" << std::endl;
  }
  else {
    ssbo.bind_base(binding_point);
    glShaderStorageBlockBinding(id_, location, binding_point);
  }
}
void CDecalsDrawerGL4::CreateStructureVBOs()
{
	{
		// Decal Groups UBO
		GLsizei uniformBlockSize = 0;
		GLuint uniformBlockIndex = glGetUniformBlockIndex(decalShader->GetObjID(), "decalGroupsUBO");
		glGetActiveUniformBlockiv(decalShader->GetObjID(), uniformBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlockSize);

		uboDecalGroups.Bind(GL_UNIFORM_BUFFER);
		uboDecalGroups.New(uniformBlockSize, GL_DYNAMIC_DRAW);
		uboDecalGroups.Unbind();

		glUniformBlockBinding(decalShader->GetObjID(), uniformBlockIndex, 4);
		glBindBufferBase(GL_UNIFORM_BUFFER, 4, uboDecalGroups.GetId());
	}

	{
		// Decals UBO
		GLint uniformBlockSize = 0;
		GLuint uniformBlockIndex = 0;
		if (useSSBO) {
			uniformBlockIndex = glGetProgramResourceIndex(decalShader->GetObjID(), GL_SHADER_STORAGE_BLOCK, "decalsUBO");
			constexpr GLenum props[] = {GL_BUFFER_DATA_SIZE};
			glGetProgramResourceiv(decalShader->GetObjID(),
				GL_SHADER_STORAGE_BLOCK, uniformBlockIndex,
				1, props,
				1, nullptr, &uniformBlockSize);
		} else {
			uniformBlockIndex = glGetUniformBlockIndex(decalShader->GetObjID(), "decalsUBO");
			glGetActiveUniformBlockiv(decalShader->GetObjID(), uniformBlockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlockSize);
		}

		uboDecalsStructures.Bind(GL_UNIFORM_BUFFER);
		uboDecalsStructures.New(uniformBlockSize, GL_DYNAMIC_DRAW);
		uboDecalsStructures.Unbind();

		if (useSSBO) {
			glShaderStorageBlockBinding(decalShader->GetObjID(), uniformBlockIndex, 3);
			glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, uboDecalsStructures.GetId());
		} else {
			glUniformBlockBinding(decalShader->GetObjID(), uniformBlockIndex, 3);
			glBindBufferBase(GL_UNIFORM_BUFFER, 3, uboDecalsStructures.GetId());
		}
	}
}
Exemple #10
0
static bool
pass_link_test(int y_index,
	       const char *vs_prefix, int vs_blocks,
	       const char *fs_prefix, int fs_blocks)
{
	bool pass = true;
	GLuint prog;
	GLuint *bos = (GLuint *) calloc(vs_blocks + fs_blocks, sizeof(GLuint));
	GLint active_blocks;
	int i;

	prog = build_shaders(vs_prefix, vs_blocks,
			     fs_prefix, fs_blocks);

	if (!prog) {
		printf("shader with (%d, %d) blocks failed to link\n",
		       vs_blocks, fs_blocks);
		free(bos);
		return false;
	}

	glUseProgram(prog);
	glGetProgramInterfaceiv(prog, GL_SHADER_STORAGE_BLOCK,
				GL_ACTIVE_RESOURCES, &active_blocks);
	glGenBuffers(active_blocks, bos);
	for (i = 0; i < active_blocks; i++) {
		glShaderStorageBlockBinding(prog, i, i);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, bos[i]);
	}

	for (i = 0; i < active_blocks; i++) {
		if (!test_draw(y_index, prog, bos, i, active_blocks)) {
			pass = false;
		}
	}

	glDeleteBuffers(active_blocks, bos);
	glDeleteProgram(prog);

	free(bos);

	return pass;
}
Exemple #11
0
enum piglit_result
piglit_display(void)
{
	const char *vs_ssbo_template =
		"#version 130\n"
		"#extension GL_ARB_shader_storage_buffer_object : enable\n"
		"#extension GL_ARB_uniform_buffer_object : enable\n"
		"\n"
		"varying vec4 vary;"
		"in vec4 piglit_vertex;\n"
		"\n"
		"layout(std140) buffer ssbo {\n"
		"	vec4 v[%d];\n"
		"};\n"
		"uniform int i;\n"
		"\n"
		"void main() {\n"
		"	gl_Position = piglit_vertex;\n"
		"	vary = v[i];\n"
		"}\n";

	const char *fs_template =
		"#version 130\n"
		"#extension GL_ARB_shader_storage_buffer_object : enable\n"
		"\n"
		"varying vec4 vary;"
		"\n"
		"void main() {\n"
		"	gl_FragColor = vary;\n"
		"}\n";

	const char *vs_template =
		"#version 130\n"
		"#extension GL_ARB_shader_storage_buffer_object : enable\n"
		"in vec4 piglit_vertex;\n"
		"\n"
		"void main() {\n"
		"	gl_Position = piglit_vertex;\n"
		"}\n";

	const char *fs_ssbo_template =
		"#version 130\n"
		"#extension GL_ARB_shader_storage_buffer_object : enable\n"
		"#extension GL_ARB_uniform_buffer_object : enable\n"
		"\n"
		"layout(std140) buffer ssbo {\n"
		"	vec4 v[%d];\n"
		"};\n"
		"uniform int i;\n"
		"\n"
		"void main() {\n"
		"	gl_FragColor = v[i];\n"
		"}\n";

	char *vs_source, *fs_source;
	GLint max_size, vec4s, i_location;
	GLuint vs, fs, prog, bo;
	GLenum target;
	float *data;
	size_t size;
	bool pass = true;
	bool link_should_fail;
	const float green[4] = { 0, 1, 0, 0 };
	int test_index;

	piglit_require_extension("GL_ARB_shader_storage_buffer_object");
	piglit_require_extension("GL_ARB_uniform_buffer_object");

	glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_size);
	printf("Max shader storage block size: %d\n", max_size);
	vec4s = max_size / 4 / 4;

	switch (mode) {
	case VS:
		target = GL_VERTEX_SHADER;
		link_should_fail = false;
		test_index = vec4s - 1;
		break;
	case VS_EXCEED:
		target = GL_VERTEX_SHADER;
		link_should_fail = true;
		vec4s++;
		test_index = vec4s - 2;
		break;
	case FS:
		target = GL_FRAGMENT_SHADER;
		link_should_fail = false;
		test_index = vec4s - 1;
		break;
	case FS_EXCEED:
		target = GL_FRAGMENT_SHADER;
		link_should_fail = true;
		vec4s++;
		test_index = vec4s - 2;
		break;
	default:
		assert(false);
		target = GL_NONE;
		link_should_fail = false;
	}

	switch (target) {
	case GL_VERTEX_SHADER:
		(void)!asprintf(&vs_source, vs_ssbo_template, vec4s);
		(void)!asprintf(&fs_source, "%s", fs_template);
		printf("Testing VS with shader storage block vec4 v[%d]\n", vec4s);
		break;
	case GL_FRAGMENT_SHADER:
		(void)!asprintf(&vs_source, "%s", vs_template);
		(void)!asprintf(&fs_source, fs_ssbo_template, vec4s);
		printf("Testing FS with shader storage block vec4 v[%d]\n", vec4s);
		break;
	default:
		piglit_report_result(PIGLIT_FAIL);
	}

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);

	prog = glCreateProgram();
	glAttachShader(prog, vs);
	glAttachShader(prog, fs);
	glLinkProgram(prog);

	if (link_should_fail) {
		if (!piglit_link_check_status_quiet(prog)) {
			printf("Failed to link with shader storage block vec4 "
			       "v[%d]\n", vec4s);
			piglit_report_result(PIGLIT_PASS);
		}
	} else {
		if (!piglit_link_check_status_quiet(prog)) {
			fprintf(stderr,
				"Failed to link with shader storage block vec4 "
				"v[%d]\n", vec4s);
			return PIGLIT_FAIL;
		}
	}

	size = vec4s * 4 * sizeof(float);
	glGenBuffers(1, &bo);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, bo);
	glBufferData(GL_SHADER_STORAGE_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
	data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_WRITE);
	memset(data, 0, size);

	/* The whole shader storage buffer will be zeros, except for the
	 * entry at v[test_index] which will be green.
	 */
	data[test_index * 4 + 0] = green[0];
	data[test_index * 4 + 1] = green[1];
	data[test_index * 4 + 2] = green[2];
	data[test_index * 4 + 3] = green[3];
	glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

	glUseProgram(prog);
	i_location = glGetUniformLocation(prog, "i");
	glUniform1i(i_location, test_index);

	glShaderStorageBlockBinding(prog, 0, 0);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bo);
	piglit_draw_rect(-1, -1, 2, 2);

	pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green);

	glDeleteProgram(prog);

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
Exemple #12
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint buffer[2];
	unsigned int i;
	float ssbo_values[SSBO_SIZE] = {0};
	float *map;
	int index;

	piglit_require_extension("GL_ARB_shader_storage_buffer_object");
	piglit_require_extension("GL_ARB_program_interface_query");

	prog = piglit_build_simple_program(vs_pass_thru_text, fs_source);

	glUseProgram(prog);

	glClearColor(0, 0, 0, 0);

	glGenBuffers(2, buffer);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, buffer[0]);
	glBufferData(GL_SHADER_STORAGE_BUFFER, SSBO_SIZE*sizeof(GLfloat),
				&ssbo_values[0], GL_DYNAMIC_DRAW);
	/* Change binding point */
	index = glGetProgramResourceIndex(prog,
					  GL_SHADER_STORAGE_BLOCK, "ssbo[0]");
	glShaderStorageBlockBinding(prog, index, 4);

	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, buffer[1]);
	glBufferData(GL_SHADER_STORAGE_BUFFER, SSBO_SIZE*sizeof(GLfloat),
				&ssbo_values[0], GL_DYNAMIC_DRAW);

	glViewport(0, 0, piglit_width, piglit_height);

	piglit_draw_rect(-1, -1, 2, 2);

	glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer[0]);
	map = (float *) glMapBuffer(GL_SHADER_STORAGE_BUFFER,  GL_READ_ONLY);

	/* Former bound buffer should not be modified */
	for (i = 0; i < SSBO_SIZE; i++) {
		if (map[i] != 0) {
			printf("Wrong %d value in buffer[0]: %.2f\n",
			       i, map[i]);
			pass = false;
		}
	}
	glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

	glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer[1]);
	map = (float *) glMapBuffer(GL_SHADER_STORAGE_BUFFER,  GL_READ_ONLY);

	for (i = 0; i < SSBO_SIZE; i++) {
                /* Values should be below ten but different than zero */
		if (map[i] == 0 || map[i] > 10) {
			printf("Wrong %d value in buffer[1]: %.2f\n",
			       i, map[i]);
			pass = false;
		}
	}

	glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

	if (!piglit_check_gl_error(GL_NO_ERROR))
	   pass = false;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
void VisibilityExtractionDemo::init()
{
    window = generateWindow();

    // load a file
    std::vector<std::string> paths;
    //paths.push_back("/home/nlichtenberg/1crn.pdb");
    paths.push_back("/home/nlichtenberg/1vis.pdb");
    //paths.push_back("/home/nlichtenberg/Develop/Mol_Sandbox/resources/TrajectoryFiles/1aon.pdb");
    MdTrajWrapper mdwrap;
    std::auto_ptr<Protein> prot = mdwrap.load(paths);

    impSph = new ImpostorSpheres(!useAtomicCounters, false);
    impSph->setProteinData(prot.get());
    impSph->init();
    num_balls = impSph->num_balls;

    if(perspectiveProj)
        projection = perspective(45.0f, getRatio(window), 0.1f, 100.0f);
    else
        projection = ortho(-30.0f, 30.0f, -30.0f, 30.0f, 0.0f, 100.0f);

    if (useAtomicCounters)
    {
        spRenderImpostor = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_InstancedUA.vert",
                                         "/VisibleAtomsDetection/Detection/solidColorInstanceCount.frag");
        spRenderDiscs = ShaderProgram("/VisibleAtomsDetection//Impostor/impostorSpheres_InstancedUA.vert",
                                      "/VisibleAtomsDetection//Impostor/impostorSpheres_discardFragments_Instanced.frag");
        if(perspectiveProj)
            spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Base/modelViewProjectionInstancedUA.vert",
                                          "/VisibleAtomsDetection/Impostor/Impostor3DSphere.frag");
        else
            spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Base/modelViewProjectionInstancedUA.vert",
                                          "/VisibleAtomsDetection/Impostor/Impostor3DSphere_Ortho.frag");
    }
    else
    {
        spRenderImpostor = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert",
                                         "/VisibleAtomsDetection/Detection/solidColorInstanceCount.frag");
        spRenderDiscs = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert",
                                      "/VisibleAtomsDetection/Impostor/impostorSpheres_discardFragments_Instanced.frag");
        spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert",
                                      "/VisibleAtomsDetection/Impostor/Impostor3DSphere.frag");
    }

    /// Renderpass to render impostors/fake geometry
    renderBalls = new RenderPass(
                impSph,
                &spRenderBalls,
                getWidth(window),
                getHeight(window));

    renderBalls->update("projection", projection);

    // define projection matrix for other shader programs
    renderBalls->setShaderProgram(&spRenderDiscs);
    renderBalls->update("projection", projection);
    renderBalls->setShaderProgram(&spRenderImpostor);
    renderBalls->update("projection", projection);

    /// Renderpass to detect the visible instances
    collectSurfaceIDs = new RenderPass(
                new Quad(),
                new ShaderProgram("/VisibleAtomsDetection/Base/fullscreen.vert",
                                  "/VisibleAtomsDetection/Detection/DetectVisibleInstanceIDs.frag"),
                getWidth(window),
                getHeight(window));

    // prepare 1D buffer for entries
    tex_collectedIDsBuffer = new Texture(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
    tex_collectedIDsBuffer->genUimageBuffer(num_balls);
    collectSurfaceIDs->texture("collectedIDsBuffer", tex_collectedIDsBuffer);
    collectSurfaceIDs->texture("tex", renderBalls->get("InstanceID"));

    /// renderpass to display result frame
    result = new RenderPass(
                new Quad(),
                new ShaderProgram("/VisibleAtomsDetection/Base/fullscreen.vert",
                                  "/VisibleAtomsDetection/Detection/toneMapperLinearInstanceCount.frag"));
    result->texture("tex", renderBalls->get("fragColor"));

    /// compute shader to process a list of visible IDs (with the actual instanceID of the first general draw)
    computeSortedIDs = new ComputeProgram(new ShaderProgram("/VisibleAtomsDetection/Detection/CreateVisibleIDList.comp"));

    // 1D buffer for visible IDs
    tex_sortedVisibleIDsBuffer = new Texture(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT);
    tex_sortedVisibleIDsBuffer->genUimageBuffer(num_balls);

    computeSortedIDs->texture("collectedIDsBuffer", tex_collectedIDsBuffer);
    computeSortedIDs->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer);

    // atomic counter buffer for consecutive index access in compute shader
    glGenBuffers(1, &atomBuff);
    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomBuff);
    glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 3, atomBuff);
    glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);

    positions_size = sizeof(glm::vec4) * impSph->instance_positions_s.instance_positions.size();
    colors_size = sizeof(glm::vec4) * impSph->instance_colors_s.instance_colors.size();

    // SSBO setup
    glGenBuffers(2, SSBO);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]);
    glBufferData(GL_SHADER_STORAGE_BUFFER, positions_size, &impSph->instance_positions_s.instance_positions[0], GL_DYNAMIC_COPY);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, SSBO[0], 0, positions_size);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]);
    glBufferData(GL_SHADER_STORAGE_BUFFER, colors_size, &impSph->instance_colors_s.instance_colors[0], GL_DYNAMIC_COPY);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, SSBO[1], 0, colors_size);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

    // SSBO copy data
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]);
    GLvoid* p_ = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
    memcpy(p_, &impSph->instance_positions_s.instance_positions[0], positions_size);
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]);
    p_ = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
    memcpy(p_, &impSph->instance_colors_s.instance_colors[0], colors_size);
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

    // SSBO bind to shaders
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]);
    GLuint block_index = 0;
    block_index = glGetProgramResourceIndex(spRenderBalls.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t");
    glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]);
    block_index = glGetProgramResourceIndex(spRenderBalls.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t");
    glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]);
    block_index = glGetProgramResourceIndex(spRenderDiscs.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t");
    glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]);
    block_index = glGetProgramResourceIndex(spRenderDiscs.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t");
    glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]);
    block_index = glGetProgramResourceIndex(spRenderImpostor.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t");
    glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]);
    block_index = glGetProgramResourceIndex(spRenderImpostor.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t");
    glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1);


    // prepare data to reset the buffer that holds the visible instance IDs
    int byteCount = sizeof(unsigned int)* num_balls;
    zeros = new unsigned char[byteCount];
    unsigned int f = 0;
    unsigned char const * p = reinterpret_cast<unsigned char const *>(&f);

    for (int i = 0; i < byteCount; i+=4)
    {
        zeros[i] = p[0];
        zeros[i+1] = p[1];
        zeros[i+2] = p[2];
        zeros[i+3] = p[3];
    }

    // prepare buffer with index = value
    // used to draw all istances

    identityInstancesMap.clear();
    for (GLuint i = 0; i < num_balls; i++)
        identityInstancesMap.push_back(i);

    glBindTexture(GL_TEXTURE_1D, tex_sortedVisibleIDsBuffer->getHandle());
    glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &identityInstancesMap[0]);

    // map to set all instances visible
    mapAllVisible.resize(num_balls);
    std::fill(mapAllVisible.begin(), mapAllVisible.end(), 1);

    // time query
    GLuint timeQuery;
    glGenQueries(1, &timeQuery);

    glEnable(GL_DEPTH_TEST);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglShaderStorageBlockBinding(JNIEnv *__env, jclass clazz, jint program, jint storageBlockIndex, jint storageBlockBinding, jlong __functionAddress) {
	glShaderStorageBlockBindingPROC glShaderStorageBlockBinding = (glShaderStorageBlockBindingPROC)(intptr_t)__functionAddress;
	UNUSED_PARAMS(__env, clazz)
	glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_glShaderStorageBlockBinding(JNIEnv *__env, jclass clazz, jint program, jint storageBlockIndex, jint storageBlockBinding) {
    glShaderStorageBlockBindingPROC glShaderStorageBlockBinding = (glShaderStorageBlockBindingPROC)tlsGetFunction(902);
    UNUSED_PARAM(clazz)
    glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL43_nglShaderStorageBlockBinding(JNIEnv *env, jclass clazz, jint program, jint storageBlockIndex, jint storageBlockBinding, jlong function_pointer) {
	glShaderStorageBlockBindingPROC glShaderStorageBlockBinding = (glShaderStorageBlockBindingPROC)((intptr_t)function_pointer);
	glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
}