ソースを参照

Collision work & some GL work

Panagiotis Christopoulos Charitos 11 年 前
コミット
267bf3506e

+ 7 - 1
include/anki/collision/CollisionShape.h

@@ -7,6 +7,7 @@
 #define ANKI_COLLISION_COLLISION_SHAPE_H
 #define ANKI_COLLISION_COLLISION_SHAPE_H
 
 
 #include "anki/collision/Forward.h"
 #include "anki/collision/Forward.h"
+#include "anki/collision/Common.h"
 #include "anki/Math.h"
 #include "anki/Math.h"
 #include "anki/util/StdTypes.h"
 #include "anki/util/StdTypes.h"
 #include "anki/util/Visitor.h"
 #include "anki/util/Visitor.h"
@@ -31,7 +32,10 @@ public:
 		AABB,
 		AABB,
 		SPHERE,
 		SPHERE,
 		OBB,
 		OBB,
-		COUNT
+		CONVEX_HULL,
+
+		COUNT,
+		LAST_CONVEX = CONVEX_HULL
 	};
 	};
 
 
 	/// Generic mutable visitor
 	/// Generic mutable visitor
@@ -47,6 +51,7 @@ public:
 		virtual void visit(Sphere&) = 0;
 		virtual void visit(Sphere&) = 0;
 		virtual void visit(Aabb&) = 0;
 		virtual void visit(Aabb&) = 0;
 		virtual void visit(CompoundShape&) = 0;
 		virtual void visit(CompoundShape&) = 0;
+		virtual void visit(ConvexHullShape&) = 0;
 	};
 	};
 
 
 	/// Generic const visitor
 	/// Generic const visitor
@@ -62,6 +67,7 @@ public:
 		virtual void visit(const Sphere&) = 0;
 		virtual void visit(const Sphere&) = 0;
 		virtual void visit(const Aabb&) = 0;
 		virtual void visit(const Aabb&) = 0;
 		virtual void visit(const CompoundShape&) = 0;
 		virtual void visit(const CompoundShape&) = 0;
+		virtual void visit(const ConvexHullShape&) = 0;
 	};
 	};
 
 
 	CollisionShape(Type cid)
 	CollisionShape(Type cid)

+ 3 - 0
include/anki/collision/Common.h

@@ -18,6 +18,9 @@ namespace anki {
 template<typename T>
 template<typename T>
 using CollisionTempAllocator = StackAllocator<T>;
 using CollisionTempAllocator = StackAllocator<T>;
 
 
+template<typename T>
+using CollisionAllocator = ChainAllocator<T>;
+
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 20 - 9
include/anki/collision/ConvexHullShape.h

@@ -32,7 +32,7 @@ public:
 	ConvexHullShape(ConvexHullShape&& b)
 	ConvexHullShape(ConvexHullShape&& b)
 	:	Base(Type::CONVEX_HULL)
 	:	Base(Type::CONVEX_HULL)
 	{
 	{
-		*this = std::move(b);
+		move(b);
 	}
 	}
 
 
 	ConvexHullShape(const ConvexHullShape& b) = delete;
 	ConvexHullShape(const ConvexHullShape& b) = delete;
@@ -41,7 +41,11 @@ public:
 
 
 	ConvexHullShape& operator=(const ConvexHullShape& b) = delete;
 	ConvexHullShape& operator=(const ConvexHullShape& b) = delete;
 
 
-	ConvexHullShape& operator=(ConvexHullShape&& b);
+	ConvexHullShape& operator=(ConvexHullShape&& b)
+	{
+		move(b);
+		return *this;
+	}
 
 
 	/// Calculate from a set of points. You have to call initStorage before
 	/// Calculate from a set of points. You have to call initStorage before
 	/// calling this method.
 	/// calling this method.
@@ -52,7 +56,8 @@ public:
 	/// method allocates a storage and the owner is the convex hull. 
 	/// method allocates a storage and the owner is the convex hull. 
 	/// @param alloc The allocator to use for the point cloud
 	/// @param alloc The allocator to use for the point cloud
 	/// @param pointCount The number of points
 	/// @param pointCount The number of points
-	void initStorage(CollisionAllocator<U8>& alloc, U pointCount);
+	ANKI_USE_RESULT Error initStorage(
+		CollisionAllocator<U8>& alloc, U pointCount);
 
 
 	/// This function initializes the storage that holds the point cloud using
 	/// This function initializes the storage that holds the point cloud using
 	/// a predefined buffer. The convex hull is not the owner of the storage.
 	/// a predefined buffer. The convex hull is not the owner of the storage.
@@ -62,30 +67,36 @@ public:
 	void initStorage(void* buffer, U pointCount);
 	void initStorage(void* buffer, U pointCount);
 
 
 	/// Implements CollisionShape::accept
 	/// Implements CollisionShape::accept
-	void accept(MutableVisitor& v)
+	void accept(MutableVisitor& v) override
 	{
 	{
 		v.visit(*this);
 		v.visit(*this);
 	}
 	}
 	/// Implements CollisionShape::accept
 	/// Implements CollisionShape::accept
-	void accept(ConstVisitor& v) const
+	void accept(ConstVisitor& v) const override
 	{
 	{
 		v.visit(*this);
 		v.visit(*this);
 	}
 	}
 
 
 	/// Implements CollisionShape::testPlane
 	/// Implements CollisionShape::testPlane
-	F32 testPlane(const Transform& trf, const Plane& p) const;
+	F32 testPlane(const Plane& p) const override;
+
+	/// Implements CollisionShape::transform.
+	void transform(const Transform& trf) override;
 
 
 	/// Implements CollisionShape::computeAabb
 	/// Implements CollisionShape::computeAabb
-	void computeAabb(const Transform& trf, Aabb& aabb) const;
+	void computeAabb(Aabb& aabb) const override;
 
 
 	/// Implements ConvexShape::computeSupport
 	/// Implements ConvexShape::computeSupport
-	Vec4 computeSupport(const Vec4& dir) const;
+	Vec4 computeSupport(const Vec4& dir) const override;
 
 
 private:
 private:
+	Transform m_trf = Transform::getIdentity();
 	Vec4* m_points = nullptr;
 	Vec4* m_points = nullptr;
 	U32 m_pointsCount = 0;
 	U32 m_pointsCount = 0;
-	CollisionAllocator<U8> m_alloc;
+	CollisionAllocator<Vec4> m_alloc;
 	Bool8 m_ownsTheStorage = false;
 	Bool8 m_ownsTheStorage = false;
+
+	void move(ConvexHullShape& b);
 };
 };
 /// @}
 /// @}
 
 

+ 1 - 1
include/anki/collision/ConvexShape.h

@@ -41,7 +41,7 @@ public:
 
 
 	static Bool classof(const CollisionShape& c)
 	static Bool classof(const CollisionShape& c)
 	{
 	{
-		return c.getType() >= Type::AABB && c.getType() <= Type::OBB;
+		return c.getType() >= Type::AABB && c.getType() <= Type::LAST_CONVEX;
 	}
 	}
 };
 };
 /// @}
 /// @}

+ 1 - 0
include/anki/collision/Forward.h

@@ -17,6 +17,7 @@ class Plane;
 class Sphere;
 class Sphere;
 class Aabb;
 class Aabb;
 class CompoundShape;
 class CompoundShape;
+class ConvexHullShape;
 
 
 class ContactPoint;
 class ContactPoint;
 
 

+ 6 - 0
include/anki/gl/GlCommandBufferHandle.h

@@ -14,6 +14,7 @@ namespace anki {
 // Forward
 // Forward
 class GlDevice;
 class GlDevice;
 class GlTextureHandle;
 class GlTextureHandle;
+class GlBufferHandle;
 class GlOcclusionQueryHandle;
 class GlOcclusionQueryHandle;
 
 
 /// @addtogroup opengl_other
 /// @addtogroup opengl_other
@@ -160,6 +161,11 @@ public:
 		U32 first = 0, U32 baseInstance = 0);
 		U32 first = 0, U32 baseInstance = 0);
 	/// @}
 	/// @}
 
 
+	/// @name Other operations
+	/// @{
+	void copyTextureToBuffer(GlTextureHandle& from, GlBufferHandle& To);
+	/// @}
+
 	/// @privatesection
 	/// @privatesection
 	/// @{
 	/// @{
 	GlCommandBufferAllocator<U8> _getAllocator() const
 	GlCommandBufferAllocator<U8> _getAllocator() const

+ 2 - 2
include/anki/gl/GlCommon.h

@@ -47,7 +47,7 @@ using GlAllocator = HeapAllocator<T>;
 /// @addtogroup opengl_containers
 /// @addtogroup opengl_containers
 /// @{
 /// @{
 
 
-/// Attachment load.
+/// Attachment load operation.
 enum class GlAttachmentLoadOperation: U8
 enum class GlAttachmentLoadOperation: U8
 {
 {
 	LOAD,
 	LOAD,
@@ -55,7 +55,7 @@ enum class GlAttachmentLoadOperation: U8
 	DONT_CARE
 	DONT_CARE
 };
 };
 
 
-/// Attachment store.
+/// Attachment store operation.
 enum class GlAttachmentStoreOperation: U8
 enum class GlAttachmentStoreOperation: U8
 {
 {
 	STORE,
 	STORE,

+ 7 - 0
include/anki/gl/GlQueue.h

@@ -61,6 +61,11 @@ public:
 		return m_state;
 		return m_state;
 	}
 	}
 
 
+	GLuint getCopyFbo() const
+	{
+		return m_copyFbo;
+	}
+
 	/// Start the working thread
 	/// Start the working thread
 	/// @note Don't free the context before calling #stop
 	/// @note Don't free the context before calling #stop
 	ANKI_USE_RESULT Error start(
 	ANKI_USE_RESULT Error start(
@@ -123,6 +128,8 @@ private:
 	GlCommandBufferHandle m_syncCommands;
 	GlCommandBufferHandle m_syncCommands;
 	GlClientSyncHandle m_sync;
 	GlClientSyncHandle m_sync;
 
 
+	GLuint m_copyFbo = MAX_U32; ///< FBO for copying from tex to buffer.
+
 	/// The function that the thread runs
 	/// The function that the thread runs
 	static ANKI_USE_RESULT Error threadCallback(Thread::Info&);
 	static ANKI_USE_RESULT Error threadCallback(Thread::Info&);
 	void threadLoop();
 	void threadLoop();

+ 2 - 1
include/anki/renderer/Tiler.h

@@ -50,7 +50,8 @@ public:
 	Error init();
 	Error init();
 
 
 	/// Issue the GPU job
 	/// Issue the GPU job
-	void runMinMax(const GlTextureHandle& depthMap);
+	void runMinMax(GlTextureHandle& depthMap,
+		GlCommandBufferHandle& cmd);
 
 
 	/// Update the tiles before doing visibility tests
 	/// Update the tiles before doing visibility tests
 	void updateTiles(Camera& cam);
 	void updateTiles(Camera& cam);

+ 81 - 0
src/collision/ConvexHullShape.cpp

@@ -0,0 +1,81 @@
+// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "anki/collision/ConvexHullShape.h"
+
+namespace anki {
+
+//==============================================================================
+ConvexHullShape::~ConvexHullShape()
+{
+	if(m_ownsTheStorage)
+	{
+		ANKI_ASSERT(m_pointsCount > 0);
+		ANKI_ASSERT(m_points != nullptr);
+		m_alloc.deallocate(static_cast<void*>(m_points), m_pointsCount);
+	}
+
+	m_points = nullptr;
+	m_pointsCount = 0;
+	m_alloc = CollisionAllocator<U8>();
+	m_ownsTheStorage = false;
+}
+
+//==============================================================================
+void ConvexHullShape::move(ConvexHullShape& b)
+{
+	this->~ConvexHullShape();
+	Base::operator=(b);
+
+	m_trf = b.m_trf;
+	b.m_trf = Transform::getIdentity();
+	
+	m_points = b.m_points;
+	b.m_points = nullptr;
+
+	m_pointsCount = b.m_pointsCount;
+	b.m_pointsCount = 0;
+
+	m_alloc = b.m_alloc;
+	b.m_alloc = CollisionAllocator<U8>();
+
+	m_ownsTheStorage = b.m_ownsTheStorage;
+	b.m_ownsTheStorage = false;
+}
+
+//==============================================================================
+Error ConvexHullShape::initStorage(CollisionAllocator<U8>& alloc, U pointCount)
+{
+	this->~ConvexHullShape();
+
+	m_points = 
+		reinterpret_cast<Vec4*>(alloc.allocate(pointCount * sizeof(Vec4)));
+	if(m_points)
+	{
+		m_alloc = alloc;
+		m_ownsTheStorage = true;
+		m_pointsCount = pointCount;
+	}
+	else
+	{
+		return ErrorCode::OUT_OF_MEMORY;
+	}
+
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+void ConvexHullShape::initStorage(void* buffer, U pointCount)
+{
+	ANKI_ASSERT(buffer);
+	ANKI_ASSERT(pointCount > 0);
+	
+	this->~ConvexHullShape();
+	m_points = static_cast<Vec4*>(buffer);
+	m_pointsCount = pointCount;
+	ANKI_ASSERT(m_ownsTheStorage == false);
+}
+
+} // end namespace anki

+ 64 - 0
src/gl/GlCommandBufferHandle.cpp

@@ -9,6 +9,8 @@
 #include "anki/gl/GlFramebuffer.h"
 #include "anki/gl/GlFramebuffer.h"
 #include "anki/gl/GlTextureHandle.h"
 #include "anki/gl/GlTextureHandle.h"
 #include "anki/gl/GlTexture.h"
 #include "anki/gl/GlTexture.h"
+#include "anki/gl/GlBufferHandle.h"
+#include "anki/gl/GlBuffer.h"
 #include "anki/gl/GlOcclusionQueryHandle.h"
 #include "anki/gl/GlOcclusionQueryHandle.h"
 #include "anki/gl/GlOcclusionQuery.h"
 #include "anki/gl/GlOcclusionQuery.h"
 #include "anki/core/Counters.h"
 #include "anki/core/Counters.h"
@@ -603,4 +605,66 @@ void GlCommandBufferHandle::drawArraysConditional(
 	_pushBackNewCommand<DrawArraysCondCommand>(mode, info, query);
 	_pushBackNewCommand<DrawArraysCondCommand>(mode, info, query);
 }
 }
 
 
+//==============================================================================
+class CopyBuffTex: public GlCommand
+{
+public:
+	GlTextureHandle m_tex;
+	GlBufferHandle m_buff;
+
+	CopyBuffTex(GlTextureHandle& from, GlBufferHandle& to)
+	:	m_tex(from),
+		m_buff(to)
+	{}
+
+	Error operator()(GlCommandBuffer* cmd)
+	{
+		GlTexture& tex = m_tex._get();
+		GlBuffer& buff = m_buff._get();
+
+		// Bind
+		GLuint copyFbo = cmd->getQueue().getCopyFbo();
+		glBindFramebuffer(GL_FRAMEBUFFER, copyFbo);
+
+		// Attach texture
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+			tex.getTarget(), tex.getGlName(), 0);
+
+		// Set draw buffers
+		GLuint drawBuff = GL_COLOR_ATTACHMENT0;
+		glDrawBuffers(1, &drawBuff);
+
+		// Bind buffer
+		ANKI_ASSERT(m_buff.getTarget() == GL_PIXEL_PACK_BUFFER);
+		buff.bind();
+
+		// Read pixels
+		GLuint format, type;
+		if(tex.getInternalFormat() == GL_RG32UI)
+		{
+			format = GL_RG_INTEGER;
+			type = GL_UNSIGNED_INT;
+		}
+		else
+		{
+			ANKI_ASSERT(0 && "Not implemented");
+		}
+
+		glReadPixels(0, 0, tex.getWidth(), tex.getHeight(), 
+			format, type, nullptr);
+
+		// End
+		buff.unbind();
+		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+		return ErrorCode::NONE;
+	}
+};
+
+void GlCommandBufferHandle::copyTextureToBuffer(
+	GlTextureHandle& from, GlBufferHandle& to)
+{
+	_pushBackNewCommand<CopyBuffTex>(from, to);
+}
+
 } // end namespace anki
 } // end namespace anki

+ 3 - 0
src/gl/GlQueue.cpp

@@ -180,6 +180,9 @@ void GlQueue::prepare()
 	// Create default VAO
 	// Create default VAO
 	glGenVertexArrays(1, &m_defaultVao);
 	glGenVertexArrays(1, &m_defaultVao);
 	glBindVertexArray(m_defaultVao);
 	glBindVertexArray(m_defaultVao);
+
+	// Create copy FBO
+	glGenFramebuffers(1, &m_copyFbo);
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 3 - 3
src/renderer/Renderer.cpp

@@ -170,9 +170,11 @@ Error Renderer::render(SceneGraph& scene,
 	err = m_ms.run(cmdBuff[0]);
 	err = m_ms.run(cmdBuff[0]);
 	if(err) return err;
 	if(err) return err;
 	ANKI_ASSERT(cmdBuff[0].getReferenceCount() == 1);
 	ANKI_ASSERT(cmdBuff[0].getReferenceCount() == 1);
-	cmdBuff[0].flush();
 	ANKI_COUNTER_STOP_TIMER_INC(RENDERER_MS_TIME);
 	ANKI_COUNTER_STOP_TIMER_INC(RENDERER_MS_TIME);
 
 
+	m_tiler.runMinMax(m_ms._getDepthRt(), cmdBuff[0]);
+	cmdBuff[0].flush();
+
 	if(m_pps.getEnabled() && m_pps.getLf().getEnabled())
 	if(m_pps.getEnabled() && m_pps.getLf().getEnabled())
 	{
 	{
 		err = m_pps.getLf().runOcclusionTests(cmdBuff[1]);
 		err = m_pps.getLf().runOcclusionTests(cmdBuff[1]);
@@ -182,8 +184,6 @@ Error Renderer::render(SceneGraph& scene,
 	err = m_dp.run(cmdBuff[1]);
 	err = m_dp.run(cmdBuff[1]);
 	if(err) return err;
 	if(err) return err;
 
 
-	m_tiler.runMinMax(m_ms._getDepthRt());
-
 	ANKI_COUNTER_START_TIMER(RENDERER_IS_TIME);
 	ANKI_COUNTER_START_TIMER(RENDERER_IS_TIME);
 	err = m_is.run(cmdBuff[1]);
 	err = m_is.run(cmdBuff[1]);
 	if(err) return err;
 	if(err) return err;

+ 7 - 15
src/renderer/Tiler.cpp

@@ -143,27 +143,19 @@ Error Tiler::initInternal()
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Tiler::runMinMax(const GlTextureHandle& depthMap)
+void Tiler::runMinMax(GlTextureHandle& depthMap,
+	GlCommandBufferHandle& cmd)
 {
 {
 #if ANKI_TILER_ENABLE_GPU
 #if ANKI_TILER_ENABLE_GPU
-	ANKI_ASSERT(depthMap.getFiltering() == Texture::TFrustumType::NEAREST);
-
 	// Issue the min/max job
 	// Issue the min/max job
-	fbo.bind();
-	GlStateSingleton::get().setViewport(
-		0, 0, r->getTilesCount().x(), r->getTilesCount().y());
-	r->clearAfterBindingFbo(GL_COLOR_BUFFER_BIT);
-	prog->bind();
-	ANKI_ASSERT(depthMapUniform);
-	depthMapUniform->set(depthMap);
+	m_fb.bind(cmd, true);
+	m_ppline.bind(cmd);
+	depthMap.bind(cmd, 0);
 
 
-	r->drawQuad();
+	m_r->drawQuad(cmd);
 
 
 	// Issue the async pixel read
 	// Issue the async pixel read
-	pbo.bind();
-	glReadPixels(0, 0, r->getTilesCount().x(), r->getTilesCount().y(), 
-		GL_RG_INTEGER, GL_UNSIGNED_INT, nullptr);
-	pbo.unbind();
+	cmd.copyTextureToBuffer(m_rt, m_pixelBuff);
 #endif
 #endif
 }
 }