void ComputeBasicGLSL::initRendering(void) 
{
	NV_APP_BASE_SHARED_INIT();

	NvAssetLoaderAddSearchPath("es3aep-kepler/ComputeBasicGLSL");

    if (!requireMinAPIVersion(NvGLAPIVersionES3_1()))
        return;

    {
        NvScopedShaderPrefix switched(
        (getGLContext()->getConfiguration().apiVer.api == NvGLAPI::GL)
        ? "#version 430\n" : "#version 310 es\n");

        //init shaders
        m_blitProg = NvGLSLProgram::createFromFiles("shaders/plain.vert", "shaders/plain.frag");

        m_computeProg = new NvGLSLProgram;
        int32_t len;
        NvGLSLProgram::ShaderSourceItem sources[1];
        sources[0].type = GL_COMPUTE_SHADER;
        sources[0].src = NvAssetLoaderRead("shaders/invert.glsl", len);
        m_computeProg->setSourceFromStrings(sources, 1);
        NvAssetLoaderFree((char*)sources[0].src);
    }

    //load input texture - this is a normal, "mutable" texture
    m_sourceImage = NvImage::CreateFromDDSFile("textures/flower1024.dds");
    GLint w = m_sourceImage->getWidth();
    GLint h = m_sourceImage->getHeight();
    GLint intFormat = m_sourceImage->getInternalFormat();
    GLint format = m_sourceImage->getFormat();
    GLint type = m_sourceImage->getType();

    // Image must be immutable in order to be used with glBindImageTexture
    // So we copy the mutable texture to an immutable texture
    glGenTextures(1, &m_sourceTexture );
    glBindTexture(GL_TEXTURE_2D, m_sourceTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, intFormat, w, h );
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, type, m_sourceImage->getLevel(0));
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);

    //create output texture with same size and format as input 
    // Image must be immutable in order to be used with glBindImageTexture
    glGenTextures(1, &m_resultTexture );
    glBindTexture(GL_TEXTURE_2D, m_resultTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, intFormat, w, h );

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    CHECK_GL_ERROR();

    glBindTexture(GL_TEXTURE_2D, 0);

    }
Exemplo n.º 2
0
void Mercury::initRendering(void) {

	// OpenGL 4.3 is the minimum for compute shaders
	if (!requireMinAPIVersion(NvGLAPIVersionES3_1()))
		return;

	// Set Clear Color
	glClearColor(0.25f, 0.25f, 0.25f, 1.0f);

	CHECK_GL_ERROR();
	NvAssetLoaderAddSearchPath("es3aep-kepler/Mercury");

	const char* shaderPrefix =
		(getGLContext()->getConfiguration().apiVer.api == NvGLAPI::GL)
		? "#version 430\n" : "#version 310 es\n";

	CHECK_GL_ERROR();
	{
		int32_t len;
		// Initialize Particles Render Program
		NvScopedShaderPrefix switched(shaderPrefix);

		std::string renderPartVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartVS.glsl");
		std::string renderPartGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderPartGS.glsl");
		mParticlesRenderProg = new NvGLSLProgram;


		NvGLSLProgram::ShaderSourceItem sourcesP[2];
		sourcesP[0].type = GL_VERTEX_SHADER;
		sourcesP[0].src = renderPartVS.c_str();
		sourcesP[1].type = GL_FRAGMENT_SHADER;
		sourcesP[1].src = NvAssetLoaderRead("shaders/renderPartFS.glsl", len);
		mParticlesRenderProg->setSourceFromStrings(sourcesP, 2);
		NvAssetLoaderFree((char*)sourcesP[1].src);

		// Initialize Surface Render Program
		std::string renderSurfVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfVS.glsl");
		std::string renderSurfGS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfGS.glsl");
		std::string renderSurfFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderSurfFS.glsl");
		mSurfaceRenderProg = new NvGLSLProgram;

		NvGLSLProgram::ShaderSourceItem sourcesS[3];
		sourcesS[0].type = GL_VERTEX_SHADER;
		sourcesS[0].src = renderSurfVS.c_str();
		sourcesS[1].type = GL_GEOMETRY_SHADER_EXT;
		sourcesS[1].src = renderSurfGS.c_str();
		sourcesS[2].type = GL_FRAGMENT_SHADER;
		sourcesS[2].src = renderSurfFS.c_str();
		mSurfaceRenderProg->setSourceFromStrings(sourcesS, 3);

		std::string quadVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadVS.glsl");
		std::string quadFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/renderQuadFS.glsl");
		mQuadProg = new NvGLSLProgram;

		NvGLSLProgram::ShaderSourceItem sourcesQ[2];
		sourcesQ[0].type = GL_VERTEX_SHADER;
		sourcesQ[0].src = quadVS.c_str();
		sourcesQ[1].type = GL_FRAGMENT_SHADER;
		sourcesQ[1].src = quadFS.c_str();
		mQuadProg->setSourceFromStrings(sourcesQ, 2);
		
		std::string blurVS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurVS.glsl");
		std::string blurFS = loadShaderSourceWithUniformTag("shaders/uniforms.h", "shaders/blurFS.glsl");
		mBlurProg = new NvGLSLProgram;

		NvGLSLProgram::ShaderSourceItem sourcesB[2];
		sourcesB[0].type = GL_VERTEX_SHADER;
		sourcesB[0].src = blurVS.c_str();
		sourcesB[1].type = GL_FRAGMENT_SHADER;
		sourcesB[1].src = blurFS.c_str();
		mBlurProg->setSourceFromStrings(sourcesB, 2);

	}
	CHECK_GL_ERROR();

	// Set up cubemap for skybox 
	mSkyBoxTexID = NvImageGL::UploadTextureFromDDSFile("textures/sky_cube.dds");
	glBindTexture(GL_TEXTURE_CUBE_MAP, mSkyBoxTexID);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
	CHECK_GL_ERROR();

	// Initialize skybox for screen quad
	mScreenQuadPos = new ShaderBuffer<nv::vec4f>(4);
	vec4f* pos = mScreenQuadPos->map();
	pos[0] = vec4f(-1.0f, -1.0f, -1.0f, 1.0f);
    pos[1] = vec4f( 1.0f, -1.0f, -1.0f, 1.0f);
    pos[2] = vec4f(-1.0f, 1.0f, -1.0f, 1.0f);
    pos[3] = vec4f( 1.0f, 1.0f, -1.0f, 1.0f);
	mScreenQuadPos->unmap();	


    //create ubo and initialize it with the structure data
    glGenBuffers( 1, &mUBO);
    glBindBuffer( GL_UNIFORM_BUFFER, mUBO);
    glBufferData( GL_UNIFORM_BUFFER, sizeof(ShaderParams), &mShaderParams, GL_STREAM_DRAW);
    CHECK_GL_ERROR();

    //create simple single-vertex VBO
    float vtx_data[] = { 0.0f, 0.0f, 0.0f, 1.0f};
    glGenBuffers( 1, &mVBO);
    glBindBuffer( GL_ARRAY_BUFFER, mVBO);
    glBufferData( GL_ARRAY_BUFFER, sizeof(vtx_data), vtx_data, GL_STATIC_DRAW);
    CHECK_GL_ERROR();

    // For now, scale back the particle count on mobile.
	//int32_t particleCount = isMobilePlatform() ? (mNumParticles >> 2) : mNumParticles;
	int32_t particleCount = mNumParticles;

    mParticles = new ParticleSystem(particleCount, shaderPrefix);
    CHECK_GL_ERROR();

    int cx, cy, cz;
    glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &cx );
    glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &cy );
    glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &cz );
    LOGI("Max compute work group count = %d, %d, %d\n", cx, cy, cz );

    int sx, sy, sz;
    glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &sx );
    glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &sy );
    glGetIntegeri_v( GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &sz );
    LOGI("Max compute work group size  = %d, %d, %d\n", sx, sy, sz );

    CHECK_GL_ERROR();

	//Set clockwise winding
	glFrontFace(GL_CW);

	// Texture
	const int screen_width = getAppContext()->width();
	const int screen_height = getAppContext()->height();
	
	// Frame buffer for final scene
	glGenTextures(gbuffer_size, gbuffer_tex);
	glGenFramebuffers(1, &fbo);
	glBindFramebuffer(GL_FRAMEBUFFER, fbo);

	for (int i = 0; i < gbuffer_size; i++) {
		glActiveTexture(GL_TEXTURE0 + 3 + i);
		glBindTexture(GL_TEXTURE_2D, gbuffer_tex[i]);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, screen_width, screen_height, 0, GL_RGBA, GL_FLOAT, NULL);
		glBindTexture(GL_TEXTURE_2D, 0);
		
		glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, gbuffer_tex[i], 0);
	}

	// Depth buffer 
	glGenRenderbuffers(1, &rbo_depth);
	glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height);
	glBindRenderbuffer(GL_RENDERBUFFER, 0);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth);


	GLuint attachments[gbuffer_size];
	for (int i = 0; i < gbuffer_size; i++) {
		attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	}

	glDrawBuffers(gbuffer_size, attachments);

	GLenum status;
	if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
		LOGE("glCheckFramebufferStatus: error %p", status);
		exit(0);
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	
}
void ComputeBasicGLSL::configurationCallback(NvGLConfiguration& config)
{ 
    config.depthBits = 24; 
    config.stencilBits = 0; 
    config.apiVer = NvGLAPIVersionES3_1();
}