Ver Fonte

Interleaved VBOs. Won't compile

Panagiotis Christopoulos Charitos há 13 anos atrás
pai
commit
a2c0d7438a

+ 66 - 0
include/anki/gl/ContextNonSharable.h

@@ -0,0 +1,66 @@
+#ifndef ANKI_GL_CONTEXT_NON_SHARABLE_H
+#define ANKI_GL_CONTEXT_NON_SHARABLE_H
+
+#include "anki/Config.h"
+#include "anki/util/Assert.h"
+#include <thread>
+
+namespace anki {
+
+/// Defines an non sharable GL object. Used to avoid idiotic mistakes and more
+/// specifically using the object from other than contexts
+class ContextNonSharable
+{
+public:
+	ContextNonSharable()
+	{}
+
+	ContextNonSharable(const ContextNonSharable& b)
+#if ANKI_DEBUG
+		: creationThreadId(b.creationThreadId)
+#endif
+	{}
+
+	ContextNonSharable(ContextNonSharable&& b)
+#if ANKI_DEBUG
+		: creationThreadId(b.creationThreadId)
+#endif
+	{}
+
+	~ContextNonSharable()
+	{
+		checkNonSharable();
+	}
+
+	ContextNonSharable& operator=(const ContextNonSharable& b)
+	{
+#if ANKI_DEBUG
+		creationThreadId = b.creationThreadId;
+#endif
+		return *this;
+	}
+
+	void crateNonSharable()
+	{
+#if ANKI_DEBUG
+		creationThreadId = std::this_thread::get_id();
+#endif
+	}
+
+	void checkNonSharable() const
+	{
+#if ANKI_DEBUG
+		ANKI_ASSERT(creationThreadId == std::this_thread::get_id() && 
+				"Object is not context sharable");
+#endif
+	}
+
+private:
+#if ANKI_DEBUG
+	std::thread::id creationThreadId;
+#endif
+};
+
+} // end namespace anki
+
+#endif

+ 16 - 10
include/anki/gl/Vao.h

@@ -3,6 +3,7 @@
 
 
 #include "anki/gl/GlException.h"
 #include "anki/gl/GlException.h"
 #include "anki/gl/Ogl.h"
 #include "anki/gl/Ogl.h"
+#include "anki/gl/ContextNonSharable.h"
 #include "anki/util/Assert.h"
 #include "anki/util/Assert.h"
 #include "anki/util/NonCopyable.h"
 #include "anki/util/NonCopyable.h"
 #include "anki/util/StdTypes.h"
 #include "anki/util/StdTypes.h"
@@ -13,10 +14,8 @@ class ShaderProgramAttributeVariable;
 class Vbo;
 class Vbo;
 
 
 /// Vertex array object. Non-copyable to avoid instantiating it in the stack
 /// Vertex array object. Non-copyable to avoid instantiating it in the stack
-class Vao: public NonCopyable
+class Vao: public NonCopyable, public ContextNonSharable
 {
 {
-	ANKI_GL_NON_SHARABLE
-
 public:
 public:
 	/// @name Constructors/Destructor
 	/// @name Constructors/Destructor
 	/// @{
 	/// @{
@@ -25,6 +24,12 @@ public:
 	Vao()
 	Vao()
 	{}
 	{}
 
 
+	/// Move
+	Vao(Vao&& b)
+		: ContextNonSharable(std::move(b)), glId(b.glId), 
+			attachments(b.attachments)
+	{}
+
 	/// Destroy VAO from the OpenGL context
 	/// Destroy VAO from the OpenGL context
 	~Vao();
 	~Vao();
 	/// @}
 	/// @}
@@ -33,6 +38,7 @@ public:
 	/// @{
 	/// @{
 	GLuint getGlId() const
 	GLuint getGlId() const
 	{
 	{
+		checkNonSharable();
 		ANKI_ASSERT(isCreated());
 		ANKI_ASSERT(isCreated());
 		return glId;
 		return glId;
 	}
 	}
@@ -42,7 +48,7 @@ public:
 	void create()
 	void create()
 	{
 	{
 		ANKI_ASSERT(!isCreated());
 		ANKI_ASSERT(!isCreated());
-		ANKI_GL_NON_SHARABLE_INIT();
+		crateNonSharable();
 		glGenVertexArrays(1, &glId);
 		glGenVertexArrays(1, &glId);
 		ANKI_CHECK_GL_ERROR();
 		ANKI_CHECK_GL_ERROR();
 	}
 	}
@@ -51,7 +57,7 @@ public:
 	void destroy()
 	void destroy()
 	{
 	{
 		ANKI_ASSERT(isCreated());
 		ANKI_ASSERT(isCreated());
-		ANKI_GL_NON_SHARABLE_CHECK();
+		checkNonSharable();
 		unbind();
 		unbind();
 		glDeleteVertexArrays(1, &glId);
 		glDeleteVertexArrays(1, &glId);
 	}
 	}
@@ -102,7 +108,7 @@ public:
 	    GLsizei stride,
 	    GLsizei stride,
 	    const GLvoid* pointer);
 	    const GLvoid* pointer);
 
 
-	int getAttachmentsCount() const
+	U32 getAttachmentsCount() const
 	{
 	{
 		return attachments;
 		return attachments;
 	}
 	}
@@ -114,7 +120,7 @@ public:
 	void bind() const
 	void bind() const
 	{
 	{
 		ANKI_ASSERT(isCreated());
 		ANKI_ASSERT(isCreated());
-		ANKI_GL_NON_SHARABLE_CHECK();
+		checkNonSharable();
 		if(current != this)
 		if(current != this)
 		{
 		{
 			glBindVertexArray(glId);
 			glBindVertexArray(glId);
@@ -127,7 +133,7 @@ public:
 	void unbind() const
 	void unbind() const
 	{
 	{
 		ANKI_ASSERT(isCreated());
 		ANKI_ASSERT(isCreated());
-		ANKI_GL_NON_SHARABLE_CHECK();
+		checkNonSharable();
 		if(current == this)
 		if(current == this)
 		{
 		{
 			glBindVertexArray(0);
 			glBindVertexArray(0);
@@ -140,7 +146,7 @@ private:
 	GLuint glId = 0; ///< The OpenGL id
 	GLuint glId = 0; ///< The OpenGL id
 	U32 attachments = 0;
 	U32 attachments = 0;
 
 
-	bool isCreated() const
+	Bool isCreated() const
 	{
 	{
 		return glId != 0;
 		return glId != 0;
 	}
 	}
@@ -153,6 +159,6 @@ private:
 	}
 	}
 };
 };
 
 
-} // end namespace
+} // end namespace anki
 
 
 #endif
 #endif

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

@@ -14,7 +14,7 @@ public:
 	{}
 	{}
 
 
 	/// Adds an extra check in target_ @see BufferObject::BufferObject
 	/// Adds an extra check in target_ @see BufferObject::BufferObject
-	Vbo(GLenum target_, uint32_t sizeInBytes_, const void* dataPtr_,
+	Vbo(GLenum target_, PtrSize sizeInBytes_, const void* dataPtr_,
 		GLenum usage_)
 		GLenum usage_)
 	{
 	{
 		create(target_, sizeInBytes_, dataPtr_, usage_);
 		create(target_, sizeInBytes_, dataPtr_, usage_);
@@ -31,7 +31,7 @@ public:
 	/// The same as BufferObject::create but it only accepts
 	/// The same as BufferObject::create but it only accepts
 	/// GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER in target
 	/// GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER in target
 	/// @see BufferObject::create
 	/// @see BufferObject::create
-	void create(GLenum target, uint32_t sizeInBytes, const void* dataPtr,
+	void create(GLenum target, PtrSize sizeInBytes, const void* dataPtr,
 		GLenum usage)
 		GLenum usage)
 	{
 	{
 		// unacceptable target_
 		// unacceptable target_

+ 9 - 2
include/anki/resource/Mesh.h

@@ -4,6 +4,7 @@
 #include "anki/math/Math.h"
 #include "anki/math/Math.h"
 #include "anki/gl/Vbo.h"
 #include "anki/gl/Vbo.h"
 #include "anki/collision/Obb.h"
 #include "anki/collision/Obb.h"
+#include "anki/util/Vector.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -19,9 +20,11 @@ public:
 		VA_POSITIONS,
 		VA_POSITIONS,
 		VA_NORMALS,
 		VA_NORMALS,
 		VA_TANGENTS,
 		VA_TANGENTS,
-		VA_TEX_COORDS,
+		VA_TEXTURE_COORDS,
+		VA_WEIGHTS_BONE_COUNT,
+		VA_WEIGHTS_BONE_IDS,
+		VA_WEIGHTS_BONE_WEIGHTS,
 		VA_INDICES, 
 		VA_INDICES, 
-		VA_WEIGHTS, 
 		VA_COUNT
 		VA_COUNT
 	};
 	};
 
 
@@ -42,6 +45,8 @@ public:
 	virtual Bool hasWeights() const = 0;
 	virtual Bool hasWeights() const = 0;
 
 
 	virtual U32 getLodsCount() const = 0;
 	virtual U32 getLodsCount() const = 0;
+
+	virtual const Obb& getBoundingShape() const = 0;
 };
 };
 
 
 /// Mesh Resource. It contains the geometry packed in VBOs
 /// Mesh Resource. It contains the geometry packed in VBOs
@@ -127,6 +132,8 @@ private:
 
 
 	/// Create the VBOs using the mesh data
 	/// Create the VBOs using the mesh data
 	void createVbos(const MeshLoader& meshData);
 	void createVbos(const MeshLoader& meshData);
+
+	U32 calcVertexSize() const;
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

+ 13 - 8
include/anki/resource/MeshLoader.h

@@ -72,36 +72,41 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	const Vector<Vec3>& getVertCoords() const
+	U getLodsCount() const
+	{
+		return 1;
+	}
+
+	const Vector<Vec3>& getPositions() const
 	{
 	{
 		return vertCoords;
 		return vertCoords;
 	}
 	}
 
 
-	const Vector<Vec3>& getVertNormals() const
+	const Vector<Vec3>& getNormals() const
 	{
 	{
 		return vertNormals;
 		return vertNormals;
 	}
 	}
 
 
-	const Vector<Vec4>& getVertTangents() const
+	const Vector<Vec4>& getTangents() const
 	{
 	{
 		return vertTangents;
 		return vertTangents;
 	}
 	}
 
 
-	const Vector<Vec2>& getTexCoords(const U32 channel = 0) const
+	const Vector<Vec2>& getTexureCoordinates(const U32 channel) const
 	{
 	{
 		return texCoords;
 		return texCoords;
 	}
 	}
-	U32 getTexCoordChannels() const
+	U getTextureChannelsCount() const
 	{
 	{
-		return 0;
+		return 1;
 	}
 	}
 
 
-	const Vector<VertexWeight>& getVertWeights() const
+	const Vector<VertexWeight>& getWeights() const
 	{
 	{
 		return vertWeights;
 		return vertWeights;
 	}
 	}
 
 
-	const Vector<ushort>& getVertIndeces() const
+	const Vector<ushort>& getIndices(const U lod) const
 	{
 	{
 		return vertIndeces;
 		return vertIndeces;
 	}
 	}

+ 2 - 2
include/anki/resource/Model.h

@@ -31,9 +31,9 @@ public:
 		return *vaosMap.at(key);
 		return *vaosMap.at(key);
 	}
 	}
 
 
-	uint getIndecesNumber(uint lod) const
+	U32 getIndecesNumber(const U32 lod) const
 	{
 	{
-		return getMeshBase().getIndicesNumber(lod);
+		return getMeshBase().getIndicesCount(lod);
 	}
 	}
 
 
 protected:
 protected:

+ 2 - 0
src/gl/Vao.cpp

@@ -27,6 +27,7 @@ void Vao::attachArrayBufferVbo(const Vbo& vbo, GLuint attribVarLocation,
 	ANKI_ASSERT(vbo.getBufferTarget() == GL_ARRAY_BUFFER
 	ANKI_ASSERT(vbo.getBufferTarget() == GL_ARRAY_BUFFER
 		&& "Only GL_ARRAY_BUFFER is accepted");
 		&& "Only GL_ARRAY_BUFFER is accepted");
 	ANKI_ASSERT(vbo.isCreated());
 	ANKI_ASSERT(vbo.isCreated());
+	checkNonSharable();
 
 
 	bind();
 	bind();
 	vbo.bind();
 	vbo.bind();
@@ -58,6 +59,7 @@ void Vao::attachElementArrayBufferVbo(const Vbo& vbo)
 	ANKI_ASSERT(vbo.getBufferTarget() == GL_ELEMENT_ARRAY_BUFFER
 	ANKI_ASSERT(vbo.getBufferTarget() == GL_ELEMENT_ARRAY_BUFFER
 		&& "Only GL_ELEMENT_ARRAY_BUFFER is accepted");
 		&& "Only GL_ELEMENT_ARRAY_BUFFER is accepted");
 	ANKI_ASSERT(vbo.isCreated());
 	ANKI_ASSERT(vbo.isCreated());
+	checkNonSharable();
 
 
 	bind();
 	bind();
 	vbo.bind();
 	vbo.bind();

+ 111 - 29
src/resource/Mesh.cpp

@@ -12,25 +12,26 @@ void Mesh::load(const char* filename)
 {
 {
 	MeshLoader meshData(filename);
 	MeshLoader meshData(filename);
 
 
-	vertsCount = meshData.getVertCoords().size();
-	indicesCount.push_back(meshData.getVertIndeces().size());
-	weights = meshData.getVertWeights().size() > 1;
-	texChannelsCount = 1;
+	// Set the non-VBO members
+	vertsCount = meshData.getPositions().size();
+	ANKI_ASSERT(vertsCount > 0);
 
 
-	try
+	indicesCount.push_back(meshData.getLodsCount());
+	for(U lod = 0; lod < indicesCount.size(); lod++)
 	{
 	{
-		// Sanity checks
-		//
-		if(meshData.getVertIndeces().size() < 1
-			|| meshData.getVertCoords().size() < 1
-			|| meshData.getVertNormals().size() < 1)
-		{
-			throw ANKI_EXCEPTION("Empty one of the required vectors");
-		}
+		indicesCount[lod] = meshData.getIndices(lod).size();
+		ANKI_ASSERT(indicesCount[lod] > 0);
+		ANKI_ASSERT(indicesCount[lod] % 3 == 0 && "Expecting triangles");
+	}
 
 
+	weights = meshData.getWeights().size() > 1;
+	texChannelsCount = meshData.getTextureChannelsCount();
+
+	try
+	{
 		createVbos(meshData);
 		createVbos(meshData);
 
 
-		visibilityShape.set(meshData.getVertCoords());
+		visibilityShape.set(meshData.getPositions());
 	}
 	}
 	catch(std::exception& e)
 	catch(std::exception& e)
 	{
 	{
@@ -39,17 +40,22 @@ void Mesh::load(const char* filename)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Mesh::createVbos(const MeshLoader& meshData)
+U32 Mesh::calcVertexSize() const
 {
 {
-	// Calculate VBO size
-	U32 vbosize = (3 + 3 + 4 + texChannelsCount * 2) * sizeof(F32);
-
+	U32 a = (3 + 3 + 4 + texChannelsCount * 2) * sizeof(F32);
 	if(weights)
 	if(weights)
 	{
 	{
-		vbosize += sizeof(MeshLoader::VertexWeight);
+		a += sizeof(MeshLoader::VertexWeight);
 	}
 	}
+	return a;
+}
 
 
-	vbosize *= vertsCount;
+//==============================================================================
+void Mesh::createVbos(const MeshLoader& meshData)
+{
+	// Calculate VBO size
+	U32 vertexsize = calcVertexSize();
+	U32 vbosize = vertexsize * vertsCount;
 
 
 	// Create a temp buffer and populate it
 	// Create a temp buffer and populate it
 	Vector<U8> buff;
 	Vector<U8> buff;
@@ -58,36 +64,112 @@ void Mesh::createVbos(const MeshLoader& meshData)
 	U8* ptr = &buff[0];
 	U8* ptr = &buff[0];
 	for(U i = 0; i < vertsCount; i++)
 	for(U i = 0; i < vertsCount; i++)
 	{
 	{
-		*(Vec3*)ptr = meshData.getVertCoords()[i];
+		ANKI_ASSERT(ptr + vertexsize <= &buff[0] + vbosize);
+
+		*(Vec3*)ptr = meshData.getPositions()[i];
 		ptr += sizeof(Vec3);
 		ptr += sizeof(Vec3);
 
 
-		*(Vec3*)ptr = meshData.getVertNormalsCoords()[i];
+		*(Vec3*)ptr = meshData.getNormals()[i];
 		ptr += sizeof(Vec3);
 		ptr += sizeof(Vec3);
 
 
-		*(Vec4*)ptr = meshData.getVertTangentsCoords()[i];
+		*(Vec4*)ptr = meshData.getTangents()[i];
 		ptr += sizeof(Vec4);
 		ptr += sizeof(Vec4);
 
 
-		for(U j = 0; j < texChannelsCound; j++)
+		for(U j = 0; j < texChannelsCount; j++)
 		{
 		{
-			*(Vec2*)ptr = meshData.getTexCoords(j)[i];
+			*(Vec2*)ptr = meshData.getTexureCoordinates(j)[i];
 			ptr += sizeof(Vec2);
 			ptr += sizeof(Vec2);
 		}
 		}
 
 
 		if(weights)
 		if(weights)
 		{
 		{
-			*(MeshLoader::VertexWeight*)ptr = meshData.getVertWeights()[i];
+			*(MeshLoader::VertexWeight*)ptr = meshData.getWeights()[i];
 			ptr += sizeof(MeshLoader::VertexWeight);
 			ptr += sizeof(MeshLoader::VertexWeight);
 		}
 		}
 	}
 	}
 
 
 	// Create VBO
 	// Create VBO
 	vbo.create(
 	vbo.create(
-		GL_ELEMENT_ARRAY_BUFFER,
+		GL_ARRAY_BUFFER,
 		vbosize,
 		vbosize,
 		&buff[0],
 		&buff[0],
 		GL_STATIC_DRAW);
 		GL_STATIC_DRAW);
 
 
-	/// XXX
+	/// Create the indices VBOs
+	indicesVbos.resize(meshData.getLodsCount());
+	U lod = 0;
+	for(Vbo& v : indicesVbos)
+	{
+		v.create(
+			GL_ELEMENT_ARRAY_BUFFER,
+			getVectorSizeInBytes(meshData.getIndices(lod)),
+			&meshData.getIndices(lod)[0],
+			GL_STATIC_DRAW);
+
+		++lod;
+	}
+}
+
+//==============================================================================
+void Mesh::getVboInfo(
+	const VertexAttribute attrib, const U32 lod, const U32 texChannel,
+	Vbo* v, U32& size, GLenum& type, U32& stride, U32& offset)
+{
+	stride = calcVertexSize();
+
+	switch(attrib)
+	{
+	case VA_POSITIONS:
+		v = &vbo;
+		size = 3;
+		type = GL_FLOAT;
+		offset = 0;
+		break;
+	case VA_NORMALS:
+		v = &vbo;
+		size = 3;
+		type = GL_FLOAT;
+		offset = sizeof(Vec3);
+		break;
+	case VA_TANGENTS:
+		v = &vbo;
+		size = 4;
+		type = GL_FLOAT;
+		offset = sizeof(Vec3) * 2;
+		break;
+	case VA_TEXTURE_COORDS:
+		v = &vbo;
+		size = 2;
+		type = GL_FLOAT;
+		offset = sizeof(Vec3) * 2 + sizeof(Vec4) + texChannel * sizeof(Vec2);
+		break;
+	case VA_WEIGHTS_BONE_COUNT:
+		v = &vbo;
+		size = 1;
+		type = GL_UNSIGNED_INT;
+		offset = sizeof(Vec3) * 2 + sizeof(Vec4) 
+			+ texChannelsCount * sizeof(Vec2);
+		break;
+	case VA_WEIGHTS_BONE_IDS:
+		v = &vbo;
+		size = 4;
+		type = GL_UNSIGNED_INT;
+		offset = sizeof(Vec3) * 2 + sizeof(Vec4) 
+			+ texChannelsCount * sizeof(Vec2) + sizeof(U32);
+		break;
+	case VA_WEIGHTS_BONE_WEIGHTS:
+		v = &vbo;
+		size = 4;
+		type = GL_FLOAT;
+		offset = sizeof(Vec3) * 2 + sizeof(Vec4) 
+			+ texChannelsCount * sizeof(Vec2) + sizeof(U32) + sizeof(U32) * 4;
+	case VA_INDICES:
+		v = &indicesVbos[lod];
+		break;
+	default:
+		ANKI_ASSERT(0);
+		break;
+	}
 }
 }
 
 
-} // end namespace
+} // end namespace anki