Panagiotis Christopoulos Charitos 13 anos atrás
pai
commit
83f0b890d0

+ 8 - 0
include/anki/gl/BufferObject.h

@@ -116,6 +116,14 @@ public:
 		return glId != 0;
 	}
 
+	void setBinding(GLuint binding) const
+	{
+		ANKI_ASSERT(target == GL_TRANSFORM_FEEDBACK_BUFFER ||
+			target == GL_UNIFORM_BUFFER);
+		bind();
+		glBindBufferBase(target, binding, glId);
+	}
+
 private:
 	/// Opt to save a few glBindBuffer calls
 	static const thread_local BufferObject* lastBindedBo; 

+ 51 - 5
include/anki/gl/ShaderProgram.h

@@ -175,14 +175,57 @@ public:
 class ShaderProgramUniformBlock
 {
 public:
-	ShaderProgramUniformBlock(ShaderProgram& sprog);
+	ShaderProgramUniformBlock()
+	{}
+	ShaderProgramUniformBlock(const ShaderProgramUniformBlock& b)
+	{
+		operator=(b);
+	}
+	~ShaderProgramUniformBlock()
+	{}
+
+	/// @name Accessors
+	/// @{
+	GLuint getIndex() const
+	{
+		return index;
+	}
+
+	uint32_t getSize() const
+	{
+		return size;
+	}
+
+	const std::string& getName() const
+	{
+		return name;
+	}
+
+	GLuint getBindingPoint() const
+	{
+		return bindingPoint;
+	}
+	void setBindingPoint(GLuint bp)
+	{
+		if(bindingPoint != bp)
+		{
+			glUniformBlockBinding(progId, index, bp);
+			bindingPoint = bp;
+		}
+	}
+	/// @}
+
+	ShaderProgramUniformBlock& operator=(const ShaderProgramUniformBlock& b);
+
+	void init(ShaderProgram& prog, const char* blockName);
 
 private:
 	std::vector<ShaderProgramUniformVariable*> uniforms;
-	GLuint index;
-	uint32_t size; ///< In bytes
+	GLuint index = GL_INVALID_INDEX;
+	uint32_t size = 0; ///< In bytes
 	std::string name;
 	GLuint bindingPoint = 0; ///< All blocks the default to 0
+	GLuint progId;
 };
 
 /// Shader program object
@@ -195,7 +238,7 @@ public:
 		UniformVariablesContainer;
 	typedef std::vector<ShaderProgramAttributeVariable*>
 		AttributeVariablesContainer;
-	typedef std::vector<std::shared_ptr<ShaderProgramUniformBlock>>
+	typedef std::vector<ShaderProgramUniformBlock>
 		UniformBlocksContainer;
 
 	/// @name Constructors/Destructor
@@ -291,6 +334,9 @@ public:
 		const char* varName) const;
 	const ShaderProgramAttributeVariable* findAttributeVariableByName(
 		const char* varName) const;
+	const ShaderProgramUniformBlock* tryFindUniformBlock(
+		const char* name) const;
+	const ShaderProgramUniformBlock& findUniformBlock(const char* name) const;
 	/// @}
 
 	/// For all uniforms set the SPUVF_DIRTY bit to 0
@@ -380,6 +426,6 @@ private:
 };
 /// @}
 
-} // end namespace
+} // end namespace anki
 
 #endif

+ 3 - 1
include/anki/renderer/Is.h

@@ -37,6 +37,8 @@ public:
 private:
 	Texture fai;
 	Fbo fbo;
+	BufferObject ubo;
+
 	/// Illumination stage ambient pass shader program
 	ShaderProgramResourcePointer ambientPassSProg;
 	/// Illumination stage point light shader program
@@ -56,6 +58,6 @@ private:
 	void spotLightPass(SpotLight& slight);
 };
 
-} // end namespace
+} // end namespace anki
 
 #endif

+ 70 - 1
src/gl/ShaderProgram.cpp

@@ -144,6 +144,47 @@ void ShaderProgramUniformVariable::set(const Texture& tex) const
 	glUniform1i(getLocation(), tex.bind());
 }
 
+//==============================================================================
+// ShaderProgramUniformBlock                                                   =
+//==============================================================================
+
+//==============================================================================
+ShaderProgramUniformBlock& ShaderProgramUniformBlock::operator=(
+	const ShaderProgramUniformBlock& b)
+{
+	uniforms = b.uniforms;
+	index = b.index;
+	size = b.size;
+	name = b.name;
+	bindingPoint = b.bindingPoint;
+	progId = b.progId;
+	return *this;
+}
+
+//==============================================================================
+void ShaderProgramUniformBlock::init(ShaderProgram& prog, 
+	const char* blockName)
+{
+	GLint gli;
+	name = blockName;
+	progId = prog.getGlId();
+
+	index = glGetUniformBlockIndex(progId, blockName);
+	if(index == GL_INVALID_INDEX)
+	{
+		throw ANKI_EXCEPTION("glGetUniformBlockIndex() returned "
+			"GL_INVALID_INDEX");
+	}
+
+	glGetActiveUniformBlockiv(progId, index, GL_UNIFORM_BLOCK_DATA_SIZE, &gli);
+	size = gli;
+
+	glGetActiveUniformBlockiv(progId, index, GL_UNIFORM_BLOCK_BINDING, &gli);
+	bindingPoint = gli;
+
+	// XXX Init uniforms
+}
+
 //==============================================================================
 // ShaderProgram                                                               =
 //==============================================================================
@@ -438,9 +479,17 @@ void ShaderProgram::initUniformBlocks()
 	GLint blocksCount;
 	glGetProgramiv(glId, GL_ACTIVE_UNIFORM_BLOCKS, &blocksCount);
 
+	blocks.resize(blocksCount);
+	blocks.shrink_to_fit();
+
 	for(GLint i = 0; i < blocksCount; i++)
 	{
+		char name[256];
+		GLsizei len;
+		glGetActiveUniformBlockName(glId, i, sizeof(name), &len, name);
 
+		blocks[i].init(*this, name);
+		nameToBlock[blocks[i].getName().c_str()] = &blocks[i];
 	}
 }
 
@@ -480,6 +529,26 @@ const ShaderProgramUniformVariable* ShaderProgram::findUniformVariableByName(
 	return it->second;
 }
 
+//==============================================================================
+const ShaderProgramUniformBlock* ShaderProgram::tryFindUniformBlock(
+	const char* name) const
+{
+	NameToUniformBlockHashMap::const_iterator it = nameToBlock.find(name);
+	return (it == nameToBlock.end()) ? nullptr : it->second;
+}
+
+//==============================================================================
+const ShaderProgramUniformBlock& ShaderProgram::findUniformBlock(
+	const char* name) const
+{
+	const ShaderProgramUniformBlock* block = tryFindUniformBlock(name);
+	if(block == nullptr)
+	{
+		throw ANKI_EXCEPTION("Block not found: " + name);
+	}
+	return *block;
+}
+
 //==============================================================================
 void ShaderProgram::cleanAllUniformsDirtyFlags()
 {
@@ -503,4 +572,4 @@ std::ostream& operator<<(std::ostream& s, const ShaderProgram& x)
 	return s;
 }
 
-} // end namespace
+} // end namespace anki

+ 100 - 19
src/renderer/Is.cpp

@@ -5,6 +5,21 @@
 
 namespace anki {
 
+/// Representation of the program's block
+struct UniformBlockData
+{
+	vec2 planes;
+	vec2 limitsOfNearPlane;
+	vec2 limitsOfNearPlane2;
+	float zNear; float padding0;
+	float lightRadius; float padding1;
+	float shadowMapSize; float padding2;
+	vec3 lightPos; float padding3;
+	vec3 lightDiffuseCol; float padding4;
+	vec3 lightSpecularCol; float padding5;
+	mat4 texProjectionMat;
+};
+
 //==============================================================================
 Is::Is(Renderer* r_)
 	: RenderingPass(r_)
@@ -17,32 +32,98 @@ Is::~Is()
 //==============================================================================
 void Is::init(const RendererInitializer& /*initializer*/)
 {
-	// Load the passes
-	//
-	// XXX
+	try
+	{
+		// Load the passes
+		//
+		// XXX
+
+		// Load the programs
+		//
+
+		// Ambient pass
+		ambientPassSProg.load("shaders/IsAp.glsl");
 
-	// Load the programs
-	//
+		// point light
+		pointLightSProg.load(ShaderProgramResource::createSrcCodeToCache(
+			"shaders/IsLpGeneric.glsl", "#define POINT_LIGHT 1\n").c_str());
 
-	// Ambient pass
-	ambientPassSProg.load("shaders/IsAp.glsl");
+		// spot light no shadow
+		spotLightNoShadowSProg.load(
+			ShaderProgramResource::createSrcCodeToCache(
+			"shaders/IsLpGeneric.glsl", "#define SPOT_LIGHT 1\n").c_str());
 
-	// point light
-	pointLightSProg.load(ShaderProgramResource::createSrcCodeToCache(
-		"shaders/IsLpGeneric.glsl", "#define POINT_LIGHT 1\n").c_str());
+		// spot light w/t shadow
+		std::string pps = std::string("#define SPOT_LIGHT 1\n"
+			"#define SHADOW 1\n");
+		if(/*sm.isPcfEnabled()*/ 1) // XXX
+		{
+			pps += "#define PCF 1\n";
+		}
+		spotLightShadowSProg.load(ShaderProgramResource::createSrcCodeToCache(
+			"shaders/IsLpGeneric.glsl", pps.c_str()).c_str());
 
-	// spot light no shadow
-	spotLightNoShadowSProg.load(ShaderProgramResource::createSrcCodeToCache(
-		"shaders/IsLpGeneric.glsl", "#define SPOT_LIGHT 1\n").c_str());
+		// Create FBO
+		//
+		fbo.create();
+		fbo.setColorAttachments({fai});
 
-	// spot light w/t shadow
-	std::string pps = std::string("#define SPOT_LIGHT 1\n#define SHADOW 1\n");
-	if(/*sm.isPcfEnabled()*/ 1) // XXX
+		if(!fbo.isComplete())
+		{
+			throw ANKI_EXCEPTION("Fbo not complete");
+		}
+		
+		// Create UBO
+		//
+		const ShaderProgramUniformBlock& block = 
+			pointLightSProg->findUniformBlock("uniforms");
+
+		if(block.getSize() != sizeof(UniformBlockData))
+		{
+			throw ANKI_EXCEPTION("Uniform block size is not the expected");
+		}
+
+		ubo.create(GL_UNIFORM_BUFFER, blockSize, nullptr, GL_STATIC_DRAW);
+
+		ubo.setBinding(0);
+	}
+	catch(const std::exception& e)
 	{
-		pps += "#define PCF 1\n";
+		throw ANKI_EXCEPTION("Failed to create IS stage") << e;
 	}
-	spotLightShadowSProg.load(ShaderProgramResource::createSrcCodeToCache(
-		"shaders/IsLpGeneric.glsl", pps.c_str()).c_str());
+}
+
+//==============================================================================
+void Is::pointLightPass(PointLight& light)
+{
+	const Camera& cam = r.getCamera();
+
+	// XXX SMO
+	GlStateSingleton::get().enable(GL_DEPTH_TEST, false);
+
+	// shader prog
+	const ShaderProgram& shader = *pointLightSProg; // ensure the const-ness
+	shader.bind();
+
+	shader.findUniformVariableByName("msFai0")->set(r->getMs().getFai0());
+	shader.findUniformVariableByName("msDepthFai")->set(
+		r->getMs().getDepthFai());
+
+	UniformBlockData data;
+	data.planes = r->getPlanes();
+	data.limitsOfNearPlane = r->.getLimitsOfNearPlane();
+	data.limitsOfNearPlane2 = r->getLimitsOfNearPlane();
+	data.zNear = cam.getZNear();
+	Vec3 lightPosEyeSpace = origin.getTransformed(cam.getViewMatrix());
+	data.lightPos = lightPosEyeSpace;
+	data.lightRadius = light.getRadius();
+	data.lightDiffuseCol = light.getDiffuseColor();
+	data.lightSpecularCol = light.getSpecularColor();
+
+	ubo.write(&data, 0, sizeof(UniformBlockData));
+
+	// render quad
+	r->drawQuad();
 }
 
 //==============================================================================