void KeyComputeShader::execute() {
    glUseProgram(this->key_compute_shader);

    // Bind the output texture
    glBindImageTexture(0,                // Binding image unit
                       this->k_texture,  // Texture to be bound
                       0,                // Level
                       GL_FALSE,         // Layered?
                       0,                // specified layer
                       GL_WRITE_ONLY,    // Access method
                       GL_R16UI);        // Format

    // Bind depth texture
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, this->depth_texture);

    /*
    GLfloat z_value[1024 * 4];
    glGetTexImage(GL_TEXTURE_2D,
                  0,
                  GL_DEPTH_COMPONENT,
                  GL_FLOAT,
                  z_value);
                  */

    // Compute results
    glDispatchCompute(this->n_tiles.x, this->n_tiles.y, 1);
    glMemoryBarrier(GL_ALL_BARRIER_BITS);

    // Bind texture
    glBindImageTexture(0,
                       0,
                       0,
                       GL_FALSE,
                       0,
                       GL_READ_WRITE,
                       GL_R16UI);

    // Check if values are correctly written
    /*
    GLushort value[1024];
    glBindTexture(GL_TEXTURE_2D, this->k_texture);
    glGetTexImage(GL_TEXTURE_2D,
                  0,
                  GL_RED_INTEGER,
                  GL_UNSIGNED_SHORT,
                  value);
    glBindTexture(GL_TEXTURE_2D, 0);
    */

    glUseProgram(0);
}
int positiongen_launch(
	float t,
	GLuint vbo,
	int width,
	int height )
{
	debuggl_check( glUseProgram(positiongen.program) );
	debuggl_check( glUniform1f(positiongen.u_time, t) );
	debuggl_check( glBindBufferBase(GL_SHADER_STORAGE_BUFFER, positiongen.w_output, vbo) );
	debuggl_check( glDispatchCompute(width/16, height/16, 1) );
	debuggl_check( glBindBufferBase(GL_SHADER_STORAGE_BUFFER, positiongen.w_output, 0) );
	debuggl_check( glUseProgram(0) );
}
void BackgroundSubtractorLOBSTER_<ParallelUtils::eGLSL>::dispatch(size_t nStage, GLShader& oShader) {
    lvDbgExceptionWatch;
    glAssert(nStage<m_nComputeStages);
    if(nStage==0) {
        if(m_dCurrLearningRate>0)
            oShader.setUniform1ui("nResamplingRate",(GLuint)ceil(m_dCurrLearningRate));
        else
            oShader.setUniform1ui("nResamplingRate",BGSLOBSTER_DEFAULT_LEARNING_RATE);
    }
    else //nStage==1 && BGSLOBSTER_GLSL_USE_POSTPROC
        glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
    glDispatchCompute((GLuint)ceil((float)m_oFrameSize.width/m_vDefaultWorkGroupSize.x),(GLuint)ceil((float)m_oFrameSize.height/m_vDefaultWorkGroupSize.y),1);
}
	void DynamicMarchingTetrahedra::update(GLContext * gl) {

		GLContext::Program * prog = gl->getProgram(m_sceneShader.c_str());
		prog->use();

		Vec3i numBlocks(64);
		Vec3i threadBlockSize(4);
		Vec3i gridSize = (numBlocks + threadBlockSize - 1) / threadBlockSize;

		gl->setUniform(prog->getUniformLoc("cubeInfo"), m_cubeInfo);
		gl->setUniform(prog->getUniformLoc("isPrefixSumPass"), true);

		gl->setUniform(prog->getUniformLoc("numCubes"), numBlocks);

		gl->setUniform(prog->getUniformLoc("sync1"), m_disp1);
		gl->setUniform(prog->getUniformLoc("sync2"), m_disp2);
		gl->setUniform(prog->getUniformLoc("sync3"), m_disp3);
		gl->setUniform(prog->getUniformLoc("sync4"), m_disp4);
		gl->setUniform(prog->getUniformLoc("maxTetrahedras"), 6);

		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffers[DMT_Buffer_Types::INDEX_BUFFER]);
		glDispatchCompute(gridSize.x, gridSize.y, gridSize.z);

		glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

		GPUPrefixScan::scan(gl, m_buffers[DMT_Buffer_Types::INDEX_BUFFER], m_buffers[DMT_Buffer_Types::BLOCK_BUFFER], 100*100*100);

		prog->use();
		gl->setUniform(prog->getUniformLoc("isPrefixSumPass"), false);

		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffers[DMT_Buffer_Types::MESH_BUFFER]);
		
		glDispatchCompute(gridSize.x, gridSize.y, gridSize.z);

		glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

		m_numTriangles = GPUPrefixScan::getSum(gl, m_buffers[DMT_Buffer_Types::BLOCK_BUFFER]);
	}
void ComputeBasicGLSL::runComputeFilter(GLuint inputTex, GLuint outputTex, int width, int height)
{
    glUseProgram( m_computeProg->getProgram() );

    glBindImageTexture(0, inputTex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); 
    glBindImageTexture(1, outputTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);

    glDispatchCompute(width/WORKGROUP_SIZE, height/WORKGROUP_SIZE, 1);

    glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);  

    CHECK_GL_ERROR();

}
示例#6
0
void SSAO::Update(const FrameBuffer *FBO, const Camera *camera) const
{
	ssaoFBO.Bind();
	glDepthMask(GL_FALSE);
	glDisable(GL_DEPTH_TEST);

	Shader *ssao = Manager::Shader->GetShader("ssao");
	ssao->Use();
	ssao->BindTexturesUnits();

	ssaoFBO.SendResolution(ssao);
	camera->BindViewMatrix(ssao->loc_view_matrix);
	camera->BindProjectionMatrix(ssao->loc_projection_matrix);
	camera->BindProjectionDistances(ssao);

	glUniform1f(ssao->loc_u_rad, radius);
	glUniform1i(ssao->loc_kernel_size, kernelSize);
	glUniform3fv(ssao->loc_kernel, kernelSize * 3, glm::value_ptr(kernel[0]));

	FBO->BindTexture(3, GL_TEXTURE0);
	FBO->BindTexture(4, GL_TEXTURE1);
	FBO->BindDepthTexture(GL_TEXTURE2);
	RandomNoise1->BindToTextureUnit(GL_TEXTURE3);
	RandomNoise2->BindToTextureUnit(GL_TEXTURE4);

	ScreenQuad->Render(ssao);

	// Finish TASK
	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);

	FrameBuffer::Unbind();

	// -- COMPUTE SHADER
	int WORK_GROUP_SIZE = 16;
	auto res = ssaoFBO.GetResolution();

	Shader *S = Manager::Shader->GetShader("ssaoBlur");
	S->Use();

	// First Pass
	ssaoFBO.BindTexture(0, GL_TEXTURE0);
	
	glBindImageTexture(1, computeTexture->GetTextureID(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA16F);
	glDispatchCompute(GLuint(UPPER_BOUND(res.x, WORK_GROUP_SIZE)), GLuint(UPPER_BOUND(res.y, WORK_GROUP_SIZE)), 1);
	glMemoryBarrier(GL_ALL_BARRIER_BITS);

}
示例#7
0
GLUSboolean update(GLUSfloat time)
{
	// Switch to the compute shader.
	glUseProgram(g_computeProgram.program);

	// Create threads depending on width, height and block size. In this case we have 1200 threads.
	glDispatchCompute(g_imageWidth / g_localSize, g_imageHeight / g_localSize, 1);

	// Switch back to the render program.
	glUseProgram(g_program.program);

	// Here we full screen the output of the compute shader.
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

	return GLUS_TRUE;
}
	void GraphicsEngine::GridComputePass(const glm::mat4& projMatrix)
	{
		int workGroupsX = (SCREEN_SIZE_X + (SCREEN_SIZE_X % GRID_SIZE)) / GRID_SIZE;
		int workGroupsY = (SCREEN_SIZE_Y + (SCREEN_SIZE_Y % GRID_SIZE)) / GRID_SIZE;

		GraphicsCore::GPUAPI::UseShader(g_GridComputeProgram);

		// Setup inverse projection Matrix.
		glm::mat4 projInv = glm::inverse(projMatrix);
		glUniformMatrix4fv(glGetUniformLocation(g_GridComputeProgram, "inverseProj"), 1, GL_FALSE, glm::value_ptr(projInv));

		glUniform2f(glGetUniformLocation(g_GridComputeProgram, "screenDimensions"), SCREEN_SIZE_X, SCREEN_SIZE_Y);

		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, g_FrustrumSSBO.SSBO);
		glDispatchCompute(workGroupsX, workGroupsY, 1);
	}
void HeightMapCS::GenerateHeightMap()
{
	mShader.Use();

	glUniform1f(mShader.GetUniform(u_Time), Engine::GetInstance()->GetTime()); GL_CHECK_ERRORS;

	glBindImageTexture((GLuint)EHMapCSBindings::u_ImageOut, mHeightMapTextureId, 0, GL_FALSE, 0, GL_WRITE_ONLY, mPrecomputeNormals ? GL_RGBA16F : GL_R16F);
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, (GLuint)EHMapCSBindings::u_WaveParamsBlock, mBufferIds[WavePropsBufferIndex]); GL_CHECK_ERRORS;

	//glDispatchCompute(mTextureSize.x / 32, mTextureSize.y / 32, 1);
	glDispatchCompute(mTextureSize.x, mTextureSize.y, 1);

	glBindTexture(GL_TEXTURE_2D, 0);

	mShader.UnUse();
}
void SimpleComputeShaderExample::Display(bool auto_redraw)
{
    // Activate the compute program and bind the output texture image
    glUseProgram(compute_prog);
    glBindImageTexture(0, output_image, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
    glDispatchCompute(8, 16, 1);

    // Now bind the texture for rendering _from_
    glBindTexture(GL_TEXTURE_2D, output_image);

    // Clear, select the rendering program and draw a full screen quad
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(render_prog);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    base::Display();
}
// This runs once a frame, before renderScene
void update()
{
	// If we're reversing the circle that means we are shrinking it.
	// This part of the code should be straightforward: frameNum will increase until 250, then decrease down to 1, then repeat
	if (reverse)
	{
		frameNum--; 

		if (frameNum < 1)
		{
			reverse = false;
		}
	}
	else
	{
		frameNum++;
		if (frameNum > 250)
		{
			reverse = true;
		}
	}

	// Rotate the transformation matrix about the Z axis by 1 degree per function call.
	// glm::rotate returns a 4x4 matrix of the resulting transform, given an input matrix, an angle to rotate by (in radians), and a vector3 determining which axis to rotate about
	// glm::radians converts the value in paranthesis from degrees to radians
	// The axis parameter should be treated like a vector, so it doesn't just have to have a 1.0f in a single axis, but instead you're defining a vector that we are rotating around
	trans = glm::rotate(trans, glm::radians(1.0f), glm::vec3(0.0f, 0.0f, 1.0f)); // All this is doing is rotating the circle.

	// This takes the value of our transformation, view, and projection matrices and multiplies them together to create the MVP matrix.
	// Then it sets our uniform MVP matrix within our shader to this value.
	// Parameters are: Location within the shader, size (in case we're passing in multiple matrices via a single pointer), whether or not to transpose the matrix, and a pointer 
	// to the matrix value we're passing in.
	MVP = proj * view * trans;

	// Tells the code to use the compute shader program.
	glUseProgram(compute_program);

	// Sets the uniform radius to frameNum / 500.
	glUniform1f(iLocRadius, ((float)frameNum / 500.0f));
	
	// Submit job for the compute shader execution.
	// GROUP_SIZE_HEIGHT = GROUP_SIZE_WIDTH = 8
	// NUM_VERTS_H = NUM_VERTS_V = 16
	// As the result the function is called with the following parameters:
	glDispatchCompute(2, 2, 1); // 2 x 2 = 4, and within the compute shader we've locally defined sizes x and y to be 8, so 8 x 8 = 64 and 64 x 4 = 256
}
void ScanSystem::combineWithOffsets(GLuint elements, const Buffer& output, const Buffer& offsets )
{
  //assert((elements % 4) == 0);
  assert(elements * sizeof(GLuint) <= output.size);

  glUseProgram(programs.combine);
  glUniform1ui(0,elements);

  offsets.BindBufferRange(GL_SHADER_STORAGE_BUFFER, 1);
  output.BindBufferRange(GL_SHADER_STORAGE_BUFFER, 0);

  glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

  GLuint groups = snapdiv(elements,GROUPSIZE);
  assert(groups < maxGrpsCombine);
  glDispatchCompute(groups,1,1);
}
示例#13
0
bool
GLComputeEvaluator::EvalPatches(
    GLuint srcBuffer, BufferDescriptor const &srcDesc,
    GLuint dstBuffer, BufferDescriptor const &dstDesc,
    GLuint duBuffer,  BufferDescriptor const &duDesc,
    GLuint dvBuffer,  BufferDescriptor const &dvDesc,
    int numPatchCoords,
    GLuint patchCoordsBuffer,
    const PatchArrayVector &patchArrays,
    GLuint patchIndexBuffer,
    GLuint patchParamsBuffer) const {

    if (!_patchKernel.program) return false;

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, srcBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, dstBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, duBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, dvBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, patchCoordsBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, patchIndexBuffer);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, patchParamsBuffer);

    glUseProgram(_patchKernel.program);

    glUniform1i(_patchKernel.uniformSrcOffset, srcDesc.offset);
    glUniform1i(_patchKernel.uniformDstOffset, dstDesc.offset);
    glUniform4iv(_patchKernel.uniformPatchArray, (int)patchArrays.size(),
                 (const GLint*)&patchArrays[0]);
    glUniform3i(_patchKernel.uniformDuDesc, duDesc.offset, duDesc.length, duDesc.stride);
    glUniform3i(_patchKernel.uniformDvDesc, dvDesc.offset, dvDesc.length, dvDesc.stride);

    glDispatchCompute((numPatchCoords + _workGroupSize - 1) / _workGroupSize, 1, 1);

    glUseProgram(0);

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, 0);

    return true;
}
void CParticlePropNode::bindAndDraw()
{
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_vboId);

	m_updateShader->bind();

    glDispatchCompute(512/16, 1, 1);

	glPointSize(3.0f);

	m_drawShader->bind();
	CShaderResource::glslSendInt("max_particles", 512);
	glBindBufferBase(GL_UNIFORM_BUFFER, OPENGL_UBOBP_PROP, m_uboId);
	CVaoBinder::bind(m_vaoId);
	glDrawArrays(GL_POINTS, 0, 512);

	glPointSize(1.0f);
}
/*!****************************************************************************
 @Function		Update
 @Input			dt	Elapsed time from last iteration (frame)
 @Description	Advances the simulation by dt. Invalidates the following OpenGL
				state:Current program, GL_UNIFORM_BUFFER binding
******************************************************************************/
void ParticleSystemGPU::Update(float dt)
{
	if (dt == 0) { return; }
	dt *= 0.001f;
	GLuint numGroups = m_ui32NumParticles / m_ui32WorkgroupSize;

	m_ParticleConfigData.fDt = dt;
	m_ParticleConfigData.fTotalTime += dt;

	glBindBuffer(GL_UNIFORM_BUFFER, m_ParticleConfigUbo);
	glBufferData(GL_UNIFORM_BUFFER, sizeof(m_ParticleConfigData), &m_ParticleConfigData, GL_STREAM_DRAW);

	glUseProgram(m_glProgram);

	glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
	glDispatchCompute(numGroups, 1, 1);
	glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
}
示例#16
0
文件: main.c 项目: DreamerKing/OpenGL
GLUSboolean update(GLUSfloat time)
{
    glClear(GL_COLOR_BUFFER_BIT);

    // Switch to the compute shader.
    glUseProgram(g_computeProgram.program);

    // Create threads depending on width, height and block size. In this case we have 1200 threads.
    glDispatchCompute(g_imageWidth / g_localSize, g_imageHeight / g_localSize, 1);

    // Switch back to the render program.
    glUseProgram(g_program.program);

    // Here we draw the plane / rectangle using the indices, stored in the VBO.
    glDrawElements(GL_TRIANGLES, g_numberIndicesPlane, GL_UNSIGNED_INT, 0);

    return GLUS_TRUE;
}
示例#17
0
    void v_Render()
    {
        float t = (float)glfwGetTime();
        static const float black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
        static const float one = 1.0f;

        glUseProgram(flock_update_program);

        vmath::vec3 goal = vmath::vec3(sinf(t * 0.34f),
                                       cosf(t * 0.29f),
                                       sinf(t * 0.12f) * cosf(t * 0.5f));

        goal = goal * vmath::vec3(35.0f, 25.0f, 60.0f);

        glUniform3fv(uniforms.update.goal, 1, goal);

        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, flock_buffer[frame_index]);
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, flock_buffer[frame_index ^ 1]);

        glDispatchCompute(NUM_WORKGROUPS, 1, 1);

        glViewport(0, 0, GetScreenWidth(), GetScreenHeight());
        glClearBufferfv(GL_COLOR, 0, black);
        glClearBufferfv(GL_DEPTH, 0, &one);

        glUseProgram(flock_render_program);

        vmath::mat4 mv_matrix = vmath::lookat(vmath::vec3(0.0f, 0.0f, -400.0f),
                                              vmath::vec3(0.0f, 0.0f, 0.0f),
                                              vmath::vec3(0.0f, 1.0f, 0.0f));
        vmath::mat4 proj_matrix = vmath::perspective(60.0f,
                                                     getAspect(),
                                                     0.1f,
                                                     3000.0f);
        vmath::mat4 mvp = proj_matrix * mv_matrix;

        glUniformMatrix4fv(uniforms.render.mvp, 1, GL_FALSE, mvp);

        glBindVertexArray(flock_render_vao[frame_index]);

        glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 8, FLOCK_SIZE);

        frame_index ^= 1;
    }
示例#18
0
void display()
{
    // Update of the uniform buffer
    {
        glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
        glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(
                                 GL_UNIFORM_BUFFER, 0,	sizeof(glm::mat4),
                                 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

        glm::mat4 Projection = glm::perspectiveFov(45.f, 640.f, 480.f, 0.1f, 100.0f);
        //glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
        glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y));
        glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f));
        glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f));
        glm::mat4 Model = glm::mat4(1.0f);

        *Pointer = Projection * View * Model;

        // Make sure the uniform buffer is uploaded
        glUnmapBuffer(GL_UNIFORM_BUFFER);
    }

    glBindProgramPipeline(PipelineName[program::COMPUTE]);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, semantics::INPUT, BufferName[buffer::INPUT]);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, semantics::OUTPUT, BufferName[buffer::OUTPUT]);
    glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
    glDispatchCompute(GLuint(VertexCount), 1, 1);

    glViewportIndexedf(0, 0, 0, GLfloat(Window.Size.x), GLfloat(Window.Size.y));
    glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f)[0]);

    glBindProgramPipeline(PipelineName[program::GRAPHICS]);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, TextureName);
    glBindVertexArray(VertexArrayName);
    glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, semantics::INPUT, BufferName[buffer::OUTPUT]);

    glDrawElementsInstancedBaseVertexBaseInstance(
        GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, GLF_BUFFER_OFFSET(0), 1, 0, 0);

    glf::swapBuffers();
}
示例#19
0
	void Game::UpdateFrame( const double deltaTimeSec)
	{
		if(GLEW_ARB_compute_shader)
		{
			m_cameraDataUBO->Bind( m_computeShaderProgram->GetUniformBlockIndex("CameraInfo"));

			glBindImageTexture( 0, m_texture->GetTextureID(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);  

			m_computeShaderProgram->Bind();

			glDispatchCompute( 1280 / 8, 720 / 8, 1);
			
			m_computeShaderProgram->UnBind();
			
			glBindImageTexture( 0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8);

			m_cameraDataUBO->UnBind();
		}
	}
void TiledLightRenderer::draw(const vector<Light>& lights, Texture* processedSkybox)
{
    createLigthBuffer(lights);
    _lightBuffer.bind(0);

    _computeShader->bind();
    _computeShader->setUniform(static_cast<int>(lights.size()), _nbLightUniformId);

    openGL.bindImageTexture(_buffer.buffer(0)->id(), 0, GL_WRITE_ONLY, Texture::toGLFormat(_buffer.buffer(0)->format()));

    for(int i=0 ; i<4 ; ++i)
    {
        openGL.bindTextureSampler(textureSampler[TextureMode::NoFilter], i);
        _deferred.buffer(i)->bind(i);
    }

    if(_processedBrdf)
    {
        _processedBrdf->bind(4);
        openGL.bindTextureSampler(textureSampler[TextureMode::FilteredNoRepeat], 4);
    } else openGL.bindTexture(0, GL_TEXTURE_2D, 4);

    if(processedSkybox)
    {
        processedSkybox->bind(5);
        openGL.bindTextureSampler(textureSampler[TextureMode::FilteredNoRepeat], 5);
    } else openGL.bindTexture(0, GL_TEXTURE_CUBE_MAP, 5);

    uint texIndex=6;
    for(const Light& l : lights)
    {
        if(l.type == Light::SPECULAR_PROB && l.tex != nullptr)
        {
            openGL.bindTextureSampler(textureSampler[TextureMode::FilteredNoRepeat], texIndex);
            l.tex->bind(texIndex++);
        }
    }

    _frameState.bind(0);
    glDispatchCompute(_tileCount.x(),_tileCount.y(),1);

    glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}
    void convertToSphericalMaps(
            const GLCubeMapContainer<ChannelCount, HasDepthBuffer>& container,
            const GLTexture2DArray* sphereMapArrays) {
        m_ConvertPass.m_Program.use();

        Vec3u groupSize(16, 16, 4);

        for(auto i = 0u; i < ChannelCount; ++i) {
            sphereMapArrays[i].bindImage(0u, 0, GL_WRITE_ONLY, GL_RGBA32F);

            m_ConvertPass.uSphereMap.set(0u);
            m_ConvertPass.uCubeMapContainer.set(i, 0u, container);

            glDispatchCompute(1 + sphereMapArrays[i].getWidth() / groupSize.x,
                              1 + sphereMapArrays[i].getHeight() / groupSize.y,
                              1 + container.size() / groupSize.z);
        }

        glMemoryBarrier(GL_ALL_BARRIER_BITS);
    }
    void convertToDualParaboloidMaps(
            const GLCubeMapContainer<ChannelCount, HasDepthBuffer>& container,
            const GLBufferStorage<Vec4f>* dualParaboloidMapBuffers,
            uint32_t paraboloidMapWidth, uint32_t paraboloidMapHeight) {
        m_DualParaboloidConversionPass.m_Program.use();

        Vec3u groupSize(16, 16, 4);

        for(auto i = 0u; i < ChannelCount; ++i) {
            dualParaboloidMapBuffers[i].bindBase(GL_SHADER_STORAGE_BUFFER, 0);
            m_DualParaboloidConversionPass.uCubeMapContainer.set(i, 0u, container);
            m_DualParaboloidConversionPass.uParaboloidMapWidth.set(paraboloidMapWidth);
            m_DualParaboloidConversionPass.uParaboloidMapHeight.set(paraboloidMapHeight);
            m_DualParaboloidConversionPass.uDualParaboloidMapCount.set(container.size());

            glDispatchCompute(1 + 2 * paraboloidMapWidth / groupSize.x,
                              1 + paraboloidMapHeight / groupSize.y,
                              1 + container.size() / groupSize.z);
        }

        glMemoryBarrier(GL_ALL_BARRIER_BITS);
    }
    void convertToSphericalMaps(
            const GLCubeMapContainer<ChannelCount, HasDepthBuffer>& container,
            const GLBufferStorage<Vec4f>* sphereMapBuffers,
            uint32_t sphereMapWidth, uint32_t sphereMapHeight) {
        m_ConvertPass2.m_Program.use();

        Vec3u groupSize(16, 16, 4);

        for(auto i = 0u; i < ChannelCount; ++i) {
            sphereMapBuffers[i].bindBase(GL_SHADER_STORAGE_BUFFER, 0);
            m_ConvertPass2.uCubeMapContainer.set(i, 0u, container);
            m_ConvertPass2.uSphereMapWidth.set(sphereMapWidth);
            m_ConvertPass2.uSphereMapHeight.set(sphereMapHeight);
            m_ConvertPass2.uSphereMapCount.set(container.size());

            glDispatchCompute(1 + sphereMapWidth / groupSize.x,
                              1 + sphereMapHeight / groupSize.y,
                              1 + container.size() / groupSize.z);
        }

        glMemoryBarrier(GL_ALL_BARRIER_BITS);
    }
示例#24
0
void ParticleSystem::update()
{
    // Invoke the compute shader to integrate the particles
    glBindProgramPipeline(m_programPipeline);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_3D, m_noiseTex);

    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 1,  m_pos->getBuffer() );
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 2,  m_vel->getBuffer() );

    glDispatchCompute(GLuint (m_size / WORK_GROUP_SIZE), 1,  1 );

    // We need to block here on compute completion to ensure that the
    // computation is done before we render
    glMemoryBarrier( GL_SHADER_STORAGE_BARRIER_BIT );

    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 2,  0 );
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 1,  0 );

    glBindProgramPipeline(0);
}
	bool render()
	{
		glm::vec2 WindowSize(this->getWindowSize());

		{
			glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]);
			glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0,	sizeof(glm::mat4),
				GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);

			glm::mat4 Projection = glm::perspectiveFov(glm::pi<float>() * 0.25f, WindowSize.x, WindowSize.y, 0.1f, 100.0f);
			glm::mat4 Model = glm::mat4(1.0f);
			*Pointer = Projection * this->view() * Model;

			// Make sure the uniform buffer is uploaded
			glUnmapBuffer(GL_UNIFORM_BUFFER);
		}

		glBindProgramPipeline(PipelineName[program::COMPUTE]);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, semantics::INPUT, BufferName[buffer::INPUT]);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, semantics::OUTPUT, BufferName[buffer::OUTPUT]);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glDispatchCompute(GLuint(VertexCount), 1, 1);

		glViewportIndexedf(0, 0, 0, WindowSize.x, WindowSize.y);
		glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f)[0]);

		glBindProgramPipeline(PipelineName[program::GRAPHICS]);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, TextureName);
		glBindVertexArray(VertexArrayName);
		glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]);
		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, semantics::INPUT, BufferName[buffer::OUTPUT]);

		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0), 1, 0, 0);

		return true;
	}
示例#26
0
void ParticleSystem::update(float timeDelta)
{	
    static bool updated = false;
    if (!updated)
    {
        LOGI("ParticleSystem: First Update Time: %f", timeDelta);
        updated = true;
    }
    m_mcpolygonizer->generateMesh(m_pos, m_vel, timeDelta);

    // Invoke the compute shader to integrate the particles
    glBindProgramPipeline(m_programPipeline);

    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 1,  m_pos->getBuffer() );
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 2,  m_vel->getBuffer() );

    // Update the timestep in the shaders
    GLuint loc = glGetUniformLocation(m_updateProg, "timeStep");
    glProgramUniform1f(m_updateProg, loc, timeDelta);

    uint xGroups = (m_size + (WORK_GROUP_SIZE - 1)) / WORK_GROUP_SIZE;
    glDispatchCompute(xGroups, 1, 1);
    
    // We need to block here on compute completion to ensure that the
    // computation is done before we render
    glMemoryBarrier( GL_SHADER_STORAGE_BARRIER_BIT );

    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 2,  0 );
    glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 1,  0 );

	// Update the timestep in the shaders
	//GLuint loc = glGetUniformLocation(m_updateProg, "timeStep");
	//glProgramUniform1f(m_updateProg, loc, timeDelta);

    glBindProgramPipeline(0);
}
示例#27
0
//--------------------------------------------------------------
void ofShader::dispatchCompute(GLuint x, GLuint y, GLuint z) const{
    glDispatchCompute(x,y,z);
}
示例#28
0
int main(int argc, char* argv[])
{
	GLUSchar*	output;
	GLUSchar* extension;
	GLUSchar fileType[MAX_FILETYPE_LENGTH];
	GLUSchar buffer[MAX_FILENAME_LENGTH];

	GLUSint		roughnessSamples;
	GLUSuint		exponent;
	GLUSuint		samples;

	GLUSint i, k, m, o, p, q, ouputLength;
	GLUSuint x = 0;
	GLUSuint y = 0;

	GLUSboolean isHDR = GLUS_FALSE;

	GLUStgaimage tgaOutput[2];
	GLUShdrimage hdrOutput[2];

	GLUSboolean	mipMap;

	GLUSint	length;
	GLUSint	lengthExponent;
	GLUSint	stride;

	GLUSfloat offset, step, roughness;

	GLUSfloat startVector[3] = { 1.0f, -1.0f, -1.0f };
	GLUSfloat offsetVector[3];
	GLUSfloat normalVector[3];
	GLUSfloat* scanVectors;
	GLUSfloat* colorBufferLambert;
	GLUSfloat* colorBufferCookTorrance;

	GLUSfloat matrix[9];

	GLUStextfile computeSource;
	GLUSprogram computeProgram;

	GLUSuint localSize = 16;

	GLUSuint textureLambert;
	GLUSuint textureCookTorrance[MAX_ROUGHNESS];

	GLUSuint scanVectorsSSBO;

	GLUSint mLocation;
	GLUSint samplesLocation;
	GLUSint binaryFractionFactorLocation;
	GLUSint roughnessLocation;

	EGLint eglConfigAttributes[] = {
	        EGL_RED_SIZE, 8,
	        EGL_GREEN_SIZE, 8,
	        EGL_BLUE_SIZE, 8,
	        EGL_DEPTH_SIZE, 0,
	        EGL_STENCIL_SIZE, 0,
	        EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
	        EGL_NONE
	};

    EGLint eglContextAttributes[] = {
    		EGL_CONTEXT_MAJOR_VERSION, 4,
    		EGL_CONTEXT_MINOR_VERSION, 3,
    		EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE, EGL_TRUE,
    		EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
    		EGL_NONE
    };

	if (argc != 12)
	{
		printf("Usage: PreFilterCubeMap.exe [Pos X] [Neg X] [Pos Y] [Neg Y] [Pos Z] [Neg Z] [Output] [Roughness] [Samples 2^m] [Length 2^n] [As MipMap]\n");

		return -1;
	}

	//

	output = argv[7];

	ouputLength = strlen(output);

	if (ouputLength >= MAX_FILENAME_LENGTH - (MAX_FILETYPE_LENGTH - 1) - SIDE_NAMING_LENGTH - ROUGHNESS_NAMING_LENGTH - TYPE_NAMING_LENGTH)
	{
		printf("Error: Output filename too long.\n");

		return -1;
	}

	roughnessSamples = atoi(argv[8]);

	if (roughnessSamples < 2 || roughnessSamples >= MAX_ROUGHNESS)
	{
		printf("Error: Invalid roughness value.\n");

		return -1;
	}

	exponent = (GLUSuint)atoi(argv[9]);

	if (exponent > 16)
	{
		printf("Error: Invalid samples value.\n");

		return -1;
	}

	samples = 1 << exponent;

	lengthExponent = (GLUSuint)atoi(argv[10]);

	if (lengthExponent > 16)
	{
		printf("Error: Invalid length value.\n");

		return -1;
	}

	length = 1 << lengthExponent;

	mipMap = (GLUSuint)atoi(argv[11]) != 0;

	if (mipMap && roughnessSamples - 1 > lengthExponent)
	{
		printf("Error: Can not do mip mapping with given roughness and length.\n");

		return -1;
	}

	//

	extension = strrchr(argv[1], '.');

	if (extension == 0)
	{
		printf("Error: No file type found.\n");

		return -1;
	}

	if (strlen(extension) != MAX_FILETYPE_LENGTH - 1)
	{
		printf("Error: Invalid file type.\n");

		return -1;
	}

	// Copy includes NULL terminating character.
	for (i = 0; i < MAX_FILETYPE_LENGTH ; i++)
	{
		fileType[i] = tolower(extension[i]);
	}

	stride = 1;

	printf("Loading texture cube maps ... ");
	if (strcmp(fileType, ".tga") == 0)
	{
		//

		for (i = 0; i < 6; i++)
		{
			if (!glusImageLoadTga(argv[1 + i], &g_tgaimage[i]))
			{
				printf("failed! TGA image could not be loaded.\n");

				freeTgaImages(i);

				return -1;
			}

			if (i > 0)
			{
				if (g_tgaimage[0].width != g_tgaimage[i].width || g_tgaimage[0].height != g_tgaimage[i].height)
				{
					printf("failed! TGA images do have different dimension.\n");

					freeTgaImages(i + 1);

					return -1;
				}
			}
			else
			{
				if (g_tgaimage[0].width != g_tgaimage[i].height)
				{
					printf("failed! TGA images do have different dimension.\n");

					freeTgaImages(1);

					return -1;
				}
			}
		}

		if (g_tgaimage[0].format == GLUS_RGB)
		{
			stride = 3;
		}
		else if (g_tgaimage[0].format == GLUS_RGBA)
		{
			stride = 4;
		}

		//

		tgaOutput[0] = g_tgaimage[0];

		tgaOutput[0].width = length;
		tgaOutput[0].height = length;

		tgaOutput[0].data = (GLUSubyte*)malloc(length * length * stride * sizeof(GLUSubyte));

		if (!tgaOutput[0].data)
		{
			printf("failed! TGA output image could not be created.\n");

			freeTgaImages(6);

			return -1;
		}

		tgaOutput[1] = g_tgaimage[0];

		tgaOutput[1].width = length;
		tgaOutput[1].height = length;

		tgaOutput[1].data = (GLUSubyte*)malloc(length * length * stride * sizeof(GLUSubyte));

		if (!tgaOutput[1].data)
		{
			printf("failed! TGA output image could not be created.\n");

			freeTgaImages(6);

			glusImageDestroyTga(&tgaOutput[0]);

			return -1;
		}
	}
	else if (strcmp(fileType, ".hdr") == 0)
	{
		isHDR = GLUS_TRUE;

		for (i = 0; i < 6; i++)
		{
			if (!glusImageLoadHdr(argv[1 + i], &g_hdrimage[i]))
			{
				printf("failed! HDR image could not be loaded.\n");

				freeHdrImages(i);

				return -1;
			}

			if (i > 0)
			{
				if (g_hdrimage[0].width != g_hdrimage[i].width || g_hdrimage[0].height != g_hdrimage[i].height)
				{
					printf("failed! HDR images do have different dimension.\n");

					freeHdrImages(i + 1);

					return -1;
				}
			}
			else
			{
				if (g_hdrimage[0].width != g_hdrimage[i].height)
				{
					printf("failed! HDR images do have different dimension.\n");

					freeHdrImages(1);

					return -1;
				}
			}
		}

		stride = 3;

		//

		hdrOutput[0] = g_hdrimage[0];

		hdrOutput[0].width = length;
		hdrOutput[0].height = length;

		hdrOutput[0].data = (GLUSfloat*)malloc(length * length * stride * sizeof(GLUSfloat));

		if (!hdrOutput[0].data)
		{
			printf("failed! HDR output image could not be created.\n");

			freeHdrImages(6);

			return -1;
		}

		hdrOutput[1] = g_hdrimage[0];

		hdrOutput[1].width = length;
		hdrOutput[1].height = length;

		hdrOutput[1].data = (GLUSfloat*)malloc(length * length * stride * sizeof(GLUSfloat));

		if (!hdrOutput[1].data)
		{
			printf("failed! HDR output image could not be created.\n");

			freeHdrImages(6);

			glusImageDestroyHdr(&hdrOutput[1]);

			return -1;
		}
	}
	else
	{
		printf("failed. Unknown file type.\n");

		return -1;
	}
	printf("completed!\n");

	// Contains the vectors to scan and generate one side of the pre-filtered cube map.
	scanVectors = (GLUSfloat*)malloc(length * length * (3 + 1) * sizeof(GLUSfloat));

	if (!scanVectors)
	{
		printf("Error: Scan scanVectors could not be created.\n");

		freeHdrImages(6);

		return -1;
	}

	// Color buffer needed to gather the pixels from the texture.
	colorBufferLambert = (GLUSfloat*)malloc(length * length * 4 * sizeof(GLUSfloat));

	if (!colorBufferLambert)
	{
		printf("Error: Color buffer could not be created.\n");

		freeHdrImages(6);

		free(scanVectors);

		return -1;
	}

	// Color buffer needed to gather the pixels from the texture.
	colorBufferCookTorrance = (GLUSfloat*)malloc(length * length * 4 * sizeof(GLUSfloat));

	if (!colorBufferCookTorrance)
	{
		printf("Error: Color buffer could not be created.\n");

		freeHdrImages(6);

		free(scanVectors);

		free(colorBufferLambert);

		return -1;
	}

	//
	// Initialize OpenGL, as it is needed for the compute shader.
	//

	if (!glusWindowCreate("GLUS Example Window", 512, 512, GLUS_FALSE, GLUS_FALSE, eglConfigAttributes, eglContextAttributes))
	{
		printf("Could not create window!\n");
		return -1;
	}

	if (!glusWindowStartup())
	{
		return -1;
	}

	//
	// Compute shader for pre-filtering.
	//

	glusFileLoadText("../PreFilterCubeMap/shader/prefilter.comp.glsl", &computeSource);

	glusProgramBuildComputeFromSource(&computeProgram, (const GLchar**)&computeSource.text);

	glusFileDestroyText(&computeSource);

	//

	mLocation = glGetUniformLocation(computeProgram.program, "u_m");
	samplesLocation = glGetUniformLocation(computeProgram.program, "u_samples");
	binaryFractionFactorLocation = glGetUniformLocation(computeProgram.program, "u_binaryFractionFactor");
	roughnessLocation = glGetUniformLocation(computeProgram.program, "u_roughness");

	//

	glUseProgram(computeProgram.program);

	//
	//
	//

	// Create cube maps
	if (isHDR)
	{
		createHdrCubeMap();

		freeHdrImages(6);
	}
	else
	{
		createTgaCubeMap();

		freeTgaImages(6);
	}

	// Prepare texture, where the pre-filtered image is stored: Lambert
    glGenTextures(1, &textureLambert);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textureLambert);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, length, length, 0, GL_RGBA, GL_FLOAT, 0);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // see binding = 1 in the shader
    glBindImageTexture(1, textureLambert, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	//

	if (mipMap)
	{
		// Prepare texture, where the pre-filtered image is stored: Cook-Torrance
		glGenTextures(roughnessSamples, textureCookTorrance);

		for (i = 0; i < roughnessSamples; i++)
		{
			glActiveTexture(GL_TEXTURE2);
			glBindTexture(GL_TEXTURE_2D, textureCookTorrance[i]);

			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, length, length, 0, GL_RGBA, GL_FLOAT, 0);

			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

			length /= 2;
		}

		length = 1 << lengthExponent;
	}
	else
	{
		// Prepare texture, where the pre-filtered image is stored: Cook-Torrance
		glGenTextures(1, textureCookTorrance);
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, textureCookTorrance[0]);

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, length, length, 0, GL_RGBA, GL_FLOAT, 0);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		// see binding = 2 in the shader
		glBindImageTexture(2, textureCookTorrance[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

		glPixelStorei(GL_PACK_ALIGNMENT, 1);
	}

	//
	//
	//

	step = 2.0f / (GLUSfloat)length;
	offset = step * 0.5f;

	// Prepare save name.

	strcpy(buffer, output);
	buffer[ouputLength + 0] = '_';
	buffer[ouputLength + 4] = '_';

	buffer[ouputLength + 6] = '_';

	buffer[ouputLength + 9] = '_';

	for (i = ouputLength + SIDE_NAMING_LENGTH + ROUGHNESS_NAMING_LENGTH + TYPE_NAMING_LENGTH; i < ouputLength + SIDE_NAMING_LENGTH + ROUGHNESS_NAMING_LENGTH + TYPE_NAMING_LENGTH + MAX_FILETYPE_LENGTH; i++)
	{
		buffer[i] = fileType[i - (ouputLength + SIDE_NAMING_LENGTH + ROUGHNESS_NAMING_LENGTH + TYPE_NAMING_LENGTH)];
	}

	//

	// Setup scan vectors buffer for compute shader.
	glGenBuffers(1, &scanVectorsSSBO);

	glBindBuffer(GL_SHADER_STORAGE_BUFFER, scanVectorsSSBO);
	glBufferData(GL_SHADER_STORAGE_BUFFER, length * length * (3 + 1) * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
	// see binding = 3 in the shader
	glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, scanVectorsSSBO);

	// Setup m and samples for compute shader.
	glUniform1ui(mLocation, exponent);
	glUniform1ui(samplesLocation, samples);
	// Results are in range [0.0 1.0] and not [0.0, 1.0[.
	glUniform1f(binaryFractionFactorLocation, 1.0f / (powf(2.0f, (GLfloat)exponent) - 1.0f));

	printf("Generating pre filtered cube maps ...\n");
	for (i = 0; i < 6; i++)
	{
		printf("Side: %d\n", i);

		switch (i)
		{
			case 0:
				// Positive X

				glusMatrix3x3Identityf(matrix);

				buffer[ouputLength + 1] = 'P';
				buffer[ouputLength + 2] = 'O';
				buffer[ouputLength + 3] = 'S';

				buffer[ouputLength + 5] = 'X';

			break;
			case 1:
				// Negative X

				glusMatrix3x3Identityf(matrix);
				glusMatrix3x3RotateRyf(matrix, 180.0f);

				buffer[ouputLength + 1] = 'N';
				buffer[ouputLength + 2] = 'E';
				buffer[ouputLength + 3] = 'G';

				buffer[ouputLength + 5] = 'X';

			break;
			case 2:
				// Positive Y

				glusMatrix3x3Identityf(matrix);
				glusMatrix3x3RotateRxf(matrix, 90.0f);
				glusMatrix3x3RotateRyf(matrix, 90.0f);

				buffer[ouputLength + 1] = 'P';
				buffer[ouputLength + 2] = 'O';
				buffer[ouputLength + 3] = 'S';

				buffer[ouputLength + 5] = 'Y';

			break;
			case 3:
				// Negative Y

				glusMatrix3x3Identityf(matrix);
				glusMatrix3x3RotateRxf(matrix, -90.0f);
				glusMatrix3x3RotateRyf(matrix, 90.0f);

				buffer[ouputLength + 1] = 'N';
				buffer[ouputLength + 2] = 'E';
				buffer[ouputLength + 3] = 'G';

				buffer[ouputLength + 5] = 'Y';

			break;
			case 4:
				// Positive Z

				glusMatrix3x3Identityf(matrix);
				glusMatrix3x3RotateRyf(matrix, -90.0f);

				buffer[ouputLength + 1] = 'P';
				buffer[ouputLength + 2] = 'O';
				buffer[ouputLength + 3] = 'S';

				buffer[ouputLength + 5] = 'Z';

			break;
			case 5:
				// Negative Z

				glusMatrix3x3Identityf(matrix);
				glusMatrix3x3RotateRyf(matrix, 90.0f);

				buffer[ouputLength + 1] = 'N';
				buffer[ouputLength + 2] = 'E';
				buffer[ouputLength + 3] = 'G';

				buffer[ouputLength + 5] = 'Z';

			break;
		}

		if (!mipMap)
		{
			// Generate scan vectors
			for (k = 0; k < length; k++)
			{
				for (m = 0; m < length; m++)
				{
					offsetVector[0] = 0.0f;
					offsetVector[1] = offset + step * (GLUSfloat)k;
					offsetVector[2] = offset + step * (GLUSfloat)m;

					glusVector3AddVector3f(normalVector, startVector, offsetVector);
					glusVector3Normalizef(normalVector);

					glusMatrix3x3MultiplyVector3f(&scanVectors[k * length * (3 + 1) + m * (3 + 1)], matrix, normalVector);
				}
			}

			// Upload scan vectors for each side.
			glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, length * length * (3 + 1) * sizeof(GLfloat), scanVectors);
		}

		// For all roughness levels
		for (k = 0; k < roughnessSamples; k++)
		{
			if (mipMap)
			{
				if (isHDR)
				{
					hdrOutput[1].width = length;
					hdrOutput[1].height = length;
				}
				else
				{
					tgaOutput[1].width = length;
					tgaOutput[1].height = length;
				}

				step = 2.0f / (GLUSfloat)length;
				offset = step * 0.5f;

				// Generate scan vectors
				for (m = 0; m < length; m++)
				{
					for (o = 0; o < length; o++)
					{
						offsetVector[0] = 0.0f;
						offsetVector[1] = offset + step * (GLUSfloat)m;
						offsetVector[2] = offset + step * (GLUSfloat)o;

						glusVector3AddVector3f(normalVector, startVector, offsetVector);
						glusVector3Normalizef(normalVector);

						glusMatrix3x3MultiplyVector3f(&scanVectors[m * length * (3 + 1) + o * (3 + 1)], matrix, normalVector);
					}
				}

				// Upload scan vectors for each side.
				glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, length * length * (3 + 1) * sizeof(GLfloat), scanVectors);
			}

			// Calculate roughness ...
			roughness = (GLUSfloat)k * 1.0f / (GLUSfloat)(roughnessSamples - 1);

			printf("Roughness: %f\n", roughness);

			// ... and set it up for compute shader.
			glUniform1f(roughnessLocation, roughness);

		    if (mipMap)
		    {
		    	// see binding = 2 in the shader
		    	glBindImageTexture(2, textureCookTorrance[k], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

		    	glPixelStorei(GL_PACK_ALIGNMENT, 1);
		    }

			// Run the compute shader, which is doing the pre-filtering.
			glDispatchCompute(length / localSize, length / localSize, 1);

		    glActiveTexture(GL_TEXTURE1);
		    glBindTexture(GL_TEXTURE_2D, textureLambert);

		    if (roughness == 0.0f)
		    {
		    	// Compute shader stores result in given texture.
		    	glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, colorBufferLambert);
		    }

		    glActiveTexture(GL_TEXTURE2);
		    if (mipMap)
		    {
		    	glBindTexture(GL_TEXTURE_2D, textureCookTorrance[k]);
		    }
		    else
		    {
		    	glBindTexture(GL_TEXTURE_2D, textureCookTorrance[0]);
		    }

			// Compute shader stores result in given texture.
			glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, colorBufferCookTorrance);

			// Resolve
			for (p = 0; p < length; p++)
			{
				for (q = 0; q < length; q++)
				{
					// Some of the textures need to be stored flipped and mirrored down.
					switch (i)
					{
						case 0:
						case 1:
						case 4:
						case 5:
							// Positive X
							// Negative X
							// Positive Z
							// Negative Z

							x = length - 1 - q;
							y = length - 1 - p;

						break;
						case 2:
						case 3:
							// Positive Y
							// Negative Y

							x = q;
							y = p;

						break;
					}

					for (o = 0; o < stride; o++)
					{
						if (isHDR)
						{
							if (roughness == 0.0f)
							{
								hdrOutput[0].data[p * length * stride + q * stride + o] = colorBufferLambert[y * length * 4 + x * 4 + o];
							}
							hdrOutput[1].data[p * length * stride + q * stride + o] = colorBufferCookTorrance[y * length * 4 + x * 4 + o];
						}
						else
						{
							if (roughness == 0.0f)
							{
								tgaOutput[0].data[p * length * stride + q * stride + o] = (GLUSubyte)glusMathClampf(colorBufferLambert[y * length * 4 + x * 4 + o] * 255.0f, 0.0f, 255.0f);
							}
							tgaOutput[1].data[p * length * stride + q * stride + o] = (GLUSubyte)glusMathClampf(colorBufferCookTorrance[y * length * 4 + x * 4 + o] * 255.0f, 0.0f, 255.0f);
						}
					}
				}
			}

			// Construct save name depending on roughness level.
			buffer[ouputLength + 7] = '0' + (k / 10);
			buffer[ouputLength + 8] = '0' + (k % 10);

			if (isHDR)
			{
				if (roughness == 0.0f)
				{
					buffer[ouputLength + 10] = 'd';
					glusImageSaveHdr(buffer, &hdrOutput[0]);
				}
				buffer[ouputLength + 10] = 's';
				glusImageSaveHdr(buffer, &hdrOutput[1]);
			}
			else
			{
				if (roughness == 0.0f)
				{
					buffer[ouputLength + 10] = 'd';
					glusImageSaveTga(buffer, &tgaOutput[0]);
				}
				buffer[ouputLength + 10] = 's';
				glusImageSaveTga(buffer, &tgaOutput[1]);
			}

			if (mipMap)
			{
				length /= 2;
			}
		}

		if (mipMap)
		{
			length = 1 << lengthExponent;
		}
	}
	printf("completed!\n");

	//
	// Freeing resources
	//

	free(scanVectors);

	free(colorBufferLambert);

	free(colorBufferCookTorrance);

	glusProgramDestroy(&computeProgram);

    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

    if (g_cubemap)
    {
        glDeleteTextures(1, &g_cubemap);

        g_cubemap = 0;
    }

    glBindTexture(GL_TEXTURE_2D, 0);

    if (textureLambert)
    {
        glDeleteTextures(1, &textureLambert);

        textureLambert = 0;
    }

    if (!mipMap)
    {
		if (textureCookTorrance[0])
		{
			glDeleteTextures(1, textureCookTorrance);

			textureCookTorrance[0] = 0;
		}
    }
    else
    {
		glDeleteTextures(roughnessSamples, textureCookTorrance);
    }

    if (isHDR)
    {
    	glusImageDestroyHdr(&hdrOutput[0]);
    	glusImageDestroyHdr(&hdrOutput[1]);
    }
    else
    {
    	glusImageDestroyTga(&tgaOutput[0]);
    	glusImageDestroyTga(&tgaOutput[1]);
    }

	glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

	if (scanVectorsSSBO)
	{
		glDeleteBuffers(1, &scanVectorsSSBO);

		scanVectorsSSBO = 0;
	}

	//
	// Shutdown OpenGL.
	//

	glusWindowShutdown();

	return 0;
}
示例#29
0
文件: main.c 项目: AJ92/OpenGL
GLUSboolean update(GLUSfloat time)
{
	static GLfloat totalTime = 0.0f;

	static GLint previousInput = 0;
	static GLint currentInput = 1;
	static GLint currentOutput = 2;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_CULL_FACE);

    if (!updateSphere(time))
    {
    	return GLUS_FALSE;
    }

    glDisable(GL_CULL_FACE);

    //
    // Simulation part.
    //

    glUseProgram(g_computeProgram.program);

    glUniform1f(g_deltaTimeLocation, time);

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_VERTICES_IN_PREVIOUS, g_verticesBuffer[previousInput]);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_VERTICES_IN_CURRENT, g_verticesBuffer[currentInput]);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_VERTICES_OUT, g_verticesBuffer[currentOutput]);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_NORMALS_OUT, g_normalsBuffer);

    // Process all vertices.
    glDispatchCompute(1, 1, 1);

    // Make sure, all vertices and normals are written.
    glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);

    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_VERTICES_IN_PREVIOUS, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_VERTICES_IN_CURRENT, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_VERTICES_OUT, 0);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_COMP_NORMALS_OUT, 0);

    //
    // Drawing part.
    //

    glUseProgram(g_program.program);

    glBindVertexArray(g_vao);

	glBindBuffer(GL_ARRAY_BUFFER, g_verticesBuffer[currentOutput]);
	glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);

    glDrawElements(GL_TRIANGLES, g_numberIndicesPlane, GL_UNSIGNED_INT, 0);

    glBindVertexArray(0);

    // Output is next time input etc.

    previousInput = (previousInput + 1) % 3;
    currentInput = (currentInput + 1) % 3;
    currentOutput = (currentOutput + 1) % 3;

    // Update the total passed time.

    totalTime += time;

    // Reset after 10 seconds.
    if (totalTime >= 10.0f)
    {
        previousInput = 0;
        currentInput = 1;
        currentOutput = 2;

    	glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_verticesBuffer[previousInput]);
    	glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, g_gridPlane.numberVertices * 4 * sizeof(GLfloat), g_gridPlane.vertices);

    	glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_verticesBuffer[currentInput]);
    	glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, g_gridPlane.numberVertices * 4 * sizeof(GLfloat), g_gridPlane.vertices);

    	glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

    	totalTime = 0.0f;
    }

    return GLUS_TRUE;
}
void FilterComputeShader::DispatchCompute(int width, int height, int depth)
{
	glDispatchCompute(width, height, depth);
}