Esempio n. 1
0
	//-----------------------------------------------------------------------------
	void GLSLGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params)
	{
		// activate the link program object
		GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();
		// pass on parameters from params to program object uniforms
		linkProgram->updatePassIterationUniforms( params );
		
	}
Esempio n. 2
0
	//-----------------------------------------------------------------------------
	void GLSLGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask)
	{
		// link can throw exceptions, ignore them at this point
		try
		{
			// activate the link program object
			GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();
			// pass on parameters from params to program object uniforms
			linkProgram->updateUniforms(params, mask, mType);
		}
		catch (Exception& e) {}
	
	}
Esempio n. 3
0
	//-----------------------------------------------------------------------------
	bool GLSLGpuProgram::isAttributeValid(VertexElementSemantic semantic, uint index)
	{
		// get link program - only call this in the context of bound program
		GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();

		if (linkProgram->isAttributeValid(semantic, index))
		{
			return true;
		}
		else
		{
			// fall back to default implementation, allow default bindings
			return GLGpuProgram::isAttributeValid(semantic, index);
		}
	}
//-----------------------------------------------------------------------------
	void GL3PlusRenderToVertexBuffer::bindVerticesOutput(Pass* pass)
	{
		VertexDeclaration* declaration = mVertexData->vertexDeclaration;
        size_t elemCount = declaration->getElementCount();

		if (elemCount > 0)
		{
            GLuint linkProgramId = 0;
			// Have GLSL shaders, using varying attributes
            if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS))
            {
                GLSLProgramPipeline* programPipeline =
                    GLSLProgramPipelineManager::getSingleton().getActiveProgramPipeline();
                linkProgramId = programPipeline->getGLProgramPipelineHandle();
            }
            else
            {
                GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();
                linkProgramId = linkProgram->getGLProgramHandle();
            }

            // Note: 64 is the minimum number of interleaved attributes allowed by GL_EXT_transform_feedback
            // So we are using it. Otherwise we could query during rendersystem initialisation and use a dynamic sized array.
            // But that would require C99.
//            const GLchar *names[64];
            const GLchar *names[1] = {"gl_Position"};//, "oUv0", "oUv1", "oUv2" };
//			vector<const GLchar*>::type names;
//			for (unsigned short e = 0; e < elemCount; e++)
//			{
//				const VertexElement* element = declaration->getElement(e);
//				String varyingName = getSemanticVaryingName(element->getSemantic(), element->getIndex());
//                names[e] = varyingName.c_str();
////                names.push_back(varyingName.c_str());
//			}

			OGRE_CHECK_GL_ERROR(glTransformFeedbackVaryings(linkProgramId, elemCount, names, GL_INTERLEAVED_ATTRIBS));
            OGRE_CHECK_GL_ERROR(glLinkProgram(linkProgramId));
            GLint didLink = 0;
            OGRE_CHECK_GL_ERROR(glGetProgramiv( linkProgramId, GL_LINK_STATUS, &didLink ));
            logObjectInfo( String("RVB GLSL link result : "), linkProgramId );
            if(glIsProgram(linkProgramId))
            {
                glValidateProgram(linkProgramId);
            }
            logObjectInfo( String("RVB  GLSL validation result : "), linkProgramId );
		}
	}
Esempio n. 5
0
	//-----------------------------------------------------------------------------
	void GLSLGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params)
	{
        if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS))
        {
            // Activate the program pipeline object
            GLSLProgramPipeline* programPipeline = GLSLProgramPipelineManager::getSingleton().getActiveProgramPipeline();
            // Pass on parameters from params to program object uniforms
            programPipeline->updatePassIterationUniforms( params );
        }
        else
        {
            // Activate the link program object
            GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();
            // Pass on parameters from params to program object uniforms
            linkProgram->updatePassIterationUniforms( params );
		}
	}
Esempio n. 6
0
	//-----------------------------------------------------------------------------
	void GLSLGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask)
	{
		// Link can throw exceptions, ignore them at this point
		try
		{
            if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS))
            {
                // Activate the program pipeline object
                GLSLProgramPipeline* programPipeline = GLSLProgramPipelineManager::getSingleton().getActiveProgramPipeline();
                // Pass on parameters from params to program object uniforms
                programPipeline->updateUniforms(params, mask, mType);
            }
            else
            {
                // Activate the link program object
                GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();
                // Pass on parameters from params to program object uniforms
                linkProgram->updateUniforms(params, mask, mType);
            }
		}
		catch (Exception& e) {}
	}
//-----------------------------------------------------------------------------
	void GLRenderToVertexBuffer::bindVerticesOutput(Pass* pass)
	{
		VertexDeclaration* declaration = mVertexData->vertexDeclaration;
		bool useVaryingAttributes = false;
		
		//Check if we are FixedFunc/ASM shaders (Static attributes) or GLSL (Varying attributes)
		//We assume that there isn't a mix of GLSL and ASM as this is illegal
		GpuProgram* sampleProgram = 0;
		if (pass->hasVertexProgram())
		{
			sampleProgram = pass->getVertexProgram().getPointer();
		}
		else if (pass->hasGeometryProgram())
		{
			sampleProgram = pass->getGeometryProgram().getPointer();
		}
		if ((sampleProgram != 0) && (sampleProgram->getLanguage() == "glsl"))
		{
			useVaryingAttributes = true;
		}

		if (useVaryingAttributes)
		{
			//Have GLSL shaders, using varying attributes
			GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();
			GLhandleARB linkProgramId = linkProgram->getGLHandle();
			
			vector<GLint>::type locations;
			for (unsigned short e=0; e < declaration->getElementCount(); e++)
			{
				const VertexElement* element =declaration->getElement(e);
				String varyingName = getSemanticVaryingName(element->getSemantic(), element->getIndex());
				GLint location = glGetVaryingLocationNV(linkProgramId, varyingName.c_str());
				if (location < 0)
				{
					OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
						"GLSL link program does not output " + varyingName + 
						" so it cannot fill the requested vertex buffer", 
						"OgreGLRenderToVertexBuffer::bindVerticesOutput");
				}
				locations.push_back(location);
			}
			glTransformFeedbackVaryingsNV(
				linkProgramId, static_cast<GLsizei>(locations.size()), 
				&locations[0], GL_INTERLEAVED_ATTRIBS_NV);
		}
		else
		{
			//Either fixed function or assembly (CG = assembly) shaders
			vector<GLint>::type attribs;
			for (unsigned short e=0; e < declaration->getElementCount(); e++)
			{
				const VertexElement* element = declaration->getElement(e);
				//Type
				attribs.push_back(getGLSemanticType(element->getSemantic()));
				//Number of components
				attribs.push_back(VertexElement::getTypeCount(element->getType()));
				//Index
				attribs.push_back(element->getIndex());
			}
			
			glTransformFeedbackAttribsNV(
				static_cast<GLuint>(declaration->getElementCount()), 
				&attribs[0], GL_INTERLEAVED_ATTRIBS_NV);
		}

		checkGLError(true, true, "GLRenderToVertexBuffer::bindVerticesOutput");
	}
//-----------------------------------------------------------------------------
	void GL3PlusRenderToVertexBuffer::update(SceneManager* sceneMgr)
	{
		size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount;
		if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize)
		{
			// Buffers don't match. Need to reallocate.
			mResetRequested = true;
		}
		
		// Single pass only for now
		Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0);
		// Set pass before binding buffers to activate the GPU programs
		sceneMgr->_setPass(r2vbPass);
		
		bindVerticesOutput(r2vbPass);

		RenderOperation renderOp;
		size_t targetBufferIndex;
		if (mResetRequested || mResetsEveryUpdate)
		{
			// Use source data to render to first buffer
			mSourceRenderable->getRenderOperation(renderOp);
			targetBufferIndex = 0;
		}
		else
		{
			// Use current front buffer to render to back buffer
			this->getRenderOperation(renderOp);
			targetBufferIndex = 1 - mFrontBufferIndex;
		}

		if (mVertexBuffers[targetBufferIndex].isNull() || 
			mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize)
		{
			reallocateBuffer(targetBufferIndex);
		}

        // Disable rasterization
        OGRE_CHECK_GL_ERROR(glEnable(GL_RASTERIZER_DISCARD));

		GL3PlusHardwareVertexBuffer* vertexBuffer = static_cast<GL3PlusHardwareVertexBuffer*>(mVertexBuffers[targetBufferIndex].getPointer());
		// Bind the target buffer
		OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffer->getGLBufferId()));

        if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS))
        {
            GLSLProgramPipeline* programPipeline =
                GLSLProgramPipelineManager::getSingleton().getActiveProgramPipeline();
            programPipeline->getVertexArrayObject()->bind();
        }
        else
        {
            GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram();
            linkProgram->getVertexArrayObject()->bind();
        }

		// Bind the target buffer
		OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffer->getGLBufferId()));

        // Disable rasterization
        OGRE_CHECK_GL_ERROR(glEnable(GL_RASTERIZER_DISCARD));

		RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem();
		// Draw the object
		targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY);
		targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY);
		targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY);
		if (r2vbPass->hasVertexProgram())
		{
			targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, 
                                                         r2vbPass->getVertexProgramParameters(), GPV_ALL);
		}
		if (r2vbPass->hasFragmentProgram())
		{
			targetRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM,
                                                         r2vbPass->getFragmentProgramParameters(), GPV_ALL);
		}
		if (r2vbPass->hasGeometryProgram())
		{
			targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM,
                                                         r2vbPass->getGeometryProgramParameters(), GPV_ALL);
		}
        OGRE_CHECK_GL_ERROR(glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mPrimitivesDrawnQuery));

		OGRE_CHECK_GL_ERROR(glBeginTransformFeedback(getR2VBPrimitiveType(mOperationType)));

		targetRenderSystem->_render(renderOp);
		
		OGRE_CHECK_GL_ERROR(glEndTransformFeedback());

		// Finish the query
		OGRE_CHECK_GL_ERROR(glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN));

		OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD));

		// Read back query results
		GLuint primitivesWritten;
		OGRE_CHECK_GL_ERROR(glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten));
		mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType);

		// Switch the vertex binding if necessary
		if (targetBufferIndex != mFrontBufferIndex)
		{
			mVertexData->vertexBufferBinding->unsetAllBindings();
			mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]);
			mFrontBufferIndex = targetBufferIndex;
		}

        // Enable rasterization
		OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD));

		// Clear the reset flag
		mResetRequested = false;
	}