Browse Source

Fixing lens flare bugs. Adding lens flare functionality to the exporters

Panagiotis Christopoulos Charitos 11 years ago
parent
commit
d798e7208e

+ 24 - 20
include/anki/gl/GlCommandBuffer.h

@@ -47,7 +47,7 @@ public:
 		ANKI_ASSERT(m_ptr);
 	}
 
-	Error operator()(GlCommandBuffer*)
+	Error operator()(GlCommandBuffer*) override
 	{
 		m_alloc.deleteInstance(m_ptr);
 		return ErrorCode::NONE;
@@ -110,25 +110,7 @@ public:
 
 	/// Create a new command and add it to the chain
 	template<typename TCommand, typename... TArgs>
-	void pushBackNewCommand(TArgs&&... args)
-	{
-		ANKI_ASSERT(m_immutable == false);
-		TCommand* newCommand = 
-			m_alloc.template newInstance<TCommand>(std::forward<TArgs>(args)...);
-
-		if(m_firstCommand != nullptr)
-		{
-			ANKI_ASSERT(m_lastCommand != nullptr);
-			ANKI_ASSERT(m_lastCommand->m_nextCommand == nullptr);
-			m_lastCommand->m_nextCommand = newCommand;
-			m_lastCommand = newCommand;
-		}
-		else
-		{
-			m_firstCommand = newCommand;
-			m_lastCommand = newCommand;
-		}
-	}
+	void pushBackNewCommand(TArgs&&... args);
 
 	/// Execute all commands
 	ANKI_USE_RESULT Error executeAllCommands();
@@ -161,6 +143,28 @@ private:
 	void destroy();
 };
 
+//==============================================================================
+template<typename TCommand, typename... TArgs>
+void GlCommandBuffer::pushBackNewCommand(TArgs&&... args)
+{
+	ANKI_ASSERT(m_immutable == false);
+	TCommand* newCommand = m_alloc.template newInstance<TCommand>(
+		std::forward<TArgs>(args)...);
+
+	if(m_firstCommand != nullptr)
+	{
+		ANKI_ASSERT(m_lastCommand != nullptr);
+		ANKI_ASSERT(m_lastCommand->m_nextCommand == nullptr);
+		m_lastCommand->m_nextCommand = newCommand;
+		m_lastCommand = newCommand;
+	}
+	else
+	{
+		ANKI_ASSERT(m_lastCommand == nullptr);
+		m_firstCommand = newCommand;
+		m_lastCommand = newCommand;
+	}
+}
 /// @}
 
 } // end namespace anki

+ 3 - 1
include/anki/scene/Visibility.h

@@ -89,7 +89,9 @@ public:
 
 	void prepareMerge()
 	{
-		ANKI_ASSERT(m_renderablesCount == 0 && m_lightsCount == 0);
+		ANKI_ASSERT(m_renderablesCount == 0 
+			&& m_lightsCount == 0 
+			&& m_flaresCount == 0);
 		m_renderablesCount = m_renderables.getSize();
 		m_lightsCount = m_lights.getSize();
 		m_flaresCount = m_flares.getSize();

+ 1 - 1
src/core/Config.cpp

@@ -55,7 +55,7 @@ Config::Config()
 
 	newOption("pps.lf.enabled", true);
 	newOption("pps.lf.maxSpritesPerFlare", 8);
-	newOption("pps.lf.maxFlares", 4);
+	newOption("pps.lf.maxFlares", 16);
 
 	newOption("pps.enabled", true);
 	newOption("pps.sharpen", true);

+ 4 - 0
src/gl/GlDevice.cpp

@@ -25,6 +25,10 @@ Error GlDevice::create(
 	m_queue = m_alloc.newInstance<GlQueue>(
 		this, alloc, allocUserData);
 
+#if ANKI_QUEUE_DISABLE_ASYNC
+	ANKI_LOGW("GL queue works in synchronous mode");
+#endif
+
 	return ErrorCode::NONE;
 }
 

+ 5 - 1
src/gl/GlQueue.cpp

@@ -57,7 +57,11 @@ void GlQueue::flushCommandBuffer(GlCommandBufferHandle& commands)
 
 	m_condVar.notifyOne(); // Wake the thread
 #else
-	commands._executeAllCommands();
+	Error err = commands._executeAllCommands();
+	if(err)
+	{
+		ANKI_LOGE("Error in command buffer");
+	}
 #endif
 }
 

+ 24 - 8
src/renderer/Lf.cpp

@@ -57,6 +57,12 @@ Error Lf::initPseudo(const ConfigSet& config,
 	m_maxSpritesPerFlare = config.get("pps.lf.maxSpritesPerFlare");
 	m_maxFlares = config.get("pps.lf.maxFlares");
 
+	if(m_maxSpritesPerFlare < 1 || m_maxFlares < 1)
+	{
+		ANKI_LOGE("Incorrect m_maxSpritesPerFlare or m_maxFlares");
+		return ErrorCode::USER_DATA;
+	}
+
 	// Load program 1
 	String pps;
 	String::ScopeDestroyer ppsd(&pps, getAllocator());
@@ -217,6 +223,11 @@ Error Lf::runOcclusionTests(GlCommandBufferHandle& cmdb)
 	U totalCount = min<U>(vi.getLensFlaresCount(), m_maxFlares);
 	if(totalCount > 0)
 	{
+		if(vi.getLensFlaresCount() > m_maxFlares)
+		{
+			ANKI_LOGW("Visible flares exceed the limit");
+		}
+
 		// Setup state
 		cmdb.setColorWriteMask(false, false, false, false);
 		cmdb.setDepthWriteMask(false);
@@ -246,7 +257,7 @@ Error Lf::runOcclusionTests(GlCommandBufferHandle& cmdb)
 
 		// Iterate lens flare
 		auto it = vi.getLensFlaresBegin();
-		auto end = vi.getLensFlaresEnd();
+		auto end = vi.getLensFlaresBegin() + totalCount;
 		for(; it != end; ++it)
 		{
 			LensFlareComponent& lf = 
@@ -265,6 +276,8 @@ Error Lf::runOcclusionTests(GlCommandBufferHandle& cmdb)
 			++positions;
 		}
 
+		ANKI_ASSERT(positions == initialPositions + totalCount);
+
 		// Restore state
 		cmdb.setColorWriteMask(true, true, true, true);
 		cmdb.setDepthWriteMask(true);
@@ -312,9 +325,9 @@ Error Lf::run(GlCommandBufferHandle& cmdBuff)
 	if(totalCount > 0)
 	{
 		// Allocate client buffer
-		U uboAlignment = 
+		const U uboAlignment = 
 			m_r->_getGlDevice().getBufferOffsetAlignment(GL_UNIFORM_BUFFER);
-		U bufferSize = m_flareSize * totalCount;
+		const U bufferSize = m_flareSize * totalCount;
 
 		GlClientBufferHandle flaresCBuff;
 		err = flaresCBuff.create(cmdBuff, bufferSize, nullptr);
@@ -329,13 +342,11 @@ Error Lf::run(GlCommandBufferHandle& cmdBuff)
 		cmdBuff.setBlendFunctions(GL_ONE, GL_ONE);
 
 		// Send the command to write the buffer now
-		m_flareDataBuff.write(
-			cmdBuff, flaresCBuff, 0, 0, 
-			bufferSize);
+		m_flareDataBuff.write(cmdBuff, flaresCBuff, 0, 0, bufferSize);
 
 		// Iterate lens flare
 		auto it = vi.getLensFlaresBegin();
-		auto end = vi.getLensFlaresEnd();
+		auto end = vi.getLensFlaresBegin() + totalCount;
 		for(; it != end; ++it)
 		{			
 			LensFlareComponent& lf = 
@@ -389,13 +400,18 @@ Error Lf::run(GlCommandBufferHandle& cmdBuff)
 				// view we don't want to draw it.
 			}
 
+			ANKI_ASSERT(count <= m_maxSpritesPerFlare);
+
 			// Advance
 			U advancementSize = 
 				getAlignedRoundUp(uboAlignment, sizeof(Sprite) * count);
-
 			sprites = reinterpret_cast<Sprite*>(
 				reinterpret_cast<U8*>(sprites) + advancementSize);
+			
 		}
+
+		ANKI_ASSERT(
+			reinterpret_cast<U8*>(sprites) <= spritesInitialPtr + bufferSize);
 	}
 	else
 	{

+ 1 - 2
src/renderer/Ssao.cpp

@@ -290,8 +290,7 @@ Error Ssao::run(GlCommandBufferHandle& cmdb)
 		|| m_commonUboUpdateTimestamp == 1)
 	{
 		GlClientBufferHandle tmpBuff;
-		err = tmpBuff.create(cmdb, sizeof(ShaderCommonUniforms),
-			nullptr);
+		err = tmpBuff.create(cmdb, sizeof(ShaderCommonUniforms), nullptr);
 		if(err) return err;
 
 		ShaderCommonUniforms& blk = 

+ 47 - 1
src/script/Scene.cpp

@@ -32,7 +32,7 @@ static T* newSceneNode(SceneGraph* scene, CString name, TArgs... args)
 //==============================================================================
 static SceneGraph* getSceneGraph(lua_State* l)
 {
-	LuaBinder* binder = reinterpret_cast<LuaBinder*>(lua_getuserdata(l));
+	LuaBinder* binder = static_cast<LuaBinder*>(lua_getuserdata(l));
 
 	ScriptManager* scriptManager = 
 		reinterpret_cast<ScriptManager*>(binder->getParent());
@@ -1247,12 +1247,58 @@ static int wrapPointLightgetSceneNodeBase(lua_State* l)
 	return 0;
 }
 
+//==============================================================================
+/// Pre-wrap method PointLight::loadLensFlare.
+static inline int pwrapPointLightloadLensFlare(lua_State* l)
+{
+	UserData* ud;
+	(void)ud;
+	void* voidp;
+	(void)voidp;
+	
+	LuaBinder::checkArgsCount(l, 2);
+	
+	// Get "this" as "self"
+	if(LuaBinder::checkUserData(l, 1, classnamePointLight, 3561037663389896020, ud)) return -1;
+	PointLight* self = static_cast<PointLight*>(ud->m_data);
+	ANKI_ASSERT(self != nullptr);
+	
+	// Pop arguments
+	const char* arg0;
+	if(LuaBinder::checkString(l, 2, arg0)) return -1;
+	
+	// Call the method
+	Error ret = self->loadLensFlare(arg0);
+	
+	// Push return value
+	if(ANKI_UNLIKELY(ret))
+	{
+		lua_pushstring(l, "Glue code returned an error");
+		return -1;
+	}
+	
+	lua_pushnumber(l, ret);
+	
+	return 1;
+}
+
+//==============================================================================
+/// Wrap method PointLight::loadLensFlare.
+static int wrapPointLightloadLensFlare(lua_State* l)
+{
+	int res = pwrapPointLightloadLensFlare(l);
+	if(res >= 0) return res;
+	lua_error(l);
+	return 0;
+}
+
 //==============================================================================
 /// Wrap class PointLight.
 static inline void wrapPointLight(lua_State* l)
 {
 	LuaBinder::createClass(l, classnamePointLight);
 	LuaBinder::pushLuaCFuncMethod(l, "getSceneNodeBase", wrapPointLightgetSceneNodeBase);
+	LuaBinder::pushLuaCFuncMethod(l, "loadLensFlare", wrapPointLightloadLensFlare);
 	lua_settop(l, 0);
 }
 

+ 6 - 0
src/script/Scene.xml

@@ -171,6 +171,12 @@ static SceneGraph* getSceneGraph(lua_State* l)
 					<overrideCall>SceneNode&amp; ret = *self;</overrideCall>
 					<return>SceneNode&amp;</return>
 				</method>
+				<method name="loadLensFlare">
+					<args>
+						<arg>const CString&amp;</arg>
+					</args>
+					<return>Error</return>
+				</method>
 			</methods>
 		</class>
 		<class name="SpotLight">

+ 1 - 1
testapp/Main.cpp

@@ -557,7 +557,7 @@ Error initSubsystems(int argc, char* argv[])
 	//config.set("maxTextureSize", 256);
 
 	config.set("fullscreenDesktopResolution", true);
-	config.set("debugContext", false);
+	config.set("debugContext", true);
 
 	app = new App;
 	err = app->create(config, allocAligned, nullptr);

+ 1 - 1
thirdparty

@@ -1 +1 @@
-Subproject commit f1d4d1f40103028baa4556126ac16e773a6443d6
+Subproject commit f29f77fc44ed665e968c6db25c83c9e4ff21184d

+ 5 - 0
tools/scene/Exporter.cpp

@@ -842,6 +842,11 @@ void Exporter::exportLight(const aiLight& light)
 	{
 		file << "lcomp:setShadowEnabled(1)\n";
 	}
+
+	if(light.mLensFlare)
+	{
+		file << "node:loadLensFlare(\"" << light.mLensFlare << "\")\n";
+	}
 }
 
 //==============================================================================