vbo_base.h 7.2 KB
Newer Older
Thery Sylvain's avatar
Thery Sylvain committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library is distributed in the hope that it will be useful, but WITHOUT  *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
* Web site: http://cgogn.unistra.fr/                                           *
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#ifndef __CGoGN_GLSL_VBO__
#define __CGoGN_GLSL_VBO__


#include <vector>
#include "Utils/gl_def.h"
#include "Container/convert.h"
32
#include "Topology/generic/attributeHandler.h"
Thery Sylvain's avatar
Thery Sylvain committed
33 34 35 36 37 38 39 40 41 42 43 44

namespace CGoGN
{

namespace Utils
{

class GLSLShader;

/**
 * Encapsulation of OpenGL Vertex Buffer Object
 * Manage
45
 * - alloc / release of GL buffer
Thery Sylvain's avatar
Thery Sylvain committed
46 47 48 49 50 51 52 53
 * - ref by Shaders
 * - size of data (invidual cells)
 */
class VBO
{
protected:
	// VBO id
	CGoGNGLuint m_id;
54

Thery Sylvain's avatar
Thery Sylvain committed
55 56
	// size of data (in floats)
	unsigned int m_data_size;
57

Thery Sylvain's avatar
Thery Sylvain committed
58 59
	// shaders that ref this vbo
	std::vector<GLSLShader*> m_refs;
60

Thery Sylvain's avatar
Thery Sylvain committed
61 62 63
	unsigned int m_nbElts;
	mutable bool m_lock;

64
	/// name of the last attribute used to fill the VBO
65 66
	std::string m_name;

67
	/// type name of the last attribute used to fill the VBO
68 69
	std::string m_typeName;

Thery Sylvain's avatar
Thery Sylvain committed
70 71 72 73
public:
	/**
	 * constructor: allocate the OGL VBO
	 */
74
	VBO(const std::string& name = "");
Thery Sylvain's avatar
Thery Sylvain committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

	/**
	 * copy constructor, new VBO copy content
	 */
	VBO(const VBO& vbo);

	/**
	 * destructor: release the OGL VBO and clean references between VBO/Shaders
	 */
	~VBO();

	/**
	 * get id of vbo
	 */
	GLuint id() const { return *m_id; }

	/**
	 * get dataSize
	 */
	unsigned int dataSize() const { return m_data_size; }

96 97 98 99 100
	/**
	 * get name
	 */
	const std::string& name() const { return m_name; }

101
	/**
102
	 * get type name
103 104 105
	 */
	const std::string& typeName() const { return m_typeName; }

Thery Sylvain's avatar
Thery Sylvain committed
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
	/**
	 * set the data size (in number of float)
	 */
	void setDataSize(unsigned int ds) { m_data_size = ds; }

	/**
	 * get nb element in vbo (vertices, colors ...)
	 */
	unsigned int nbElts() { return m_nbElts; }

	/**
	 * bind array vbo
	 */
	void bind() const  { glBindBuffer(GL_ARRAY_BUFFER, *m_id); }

	/**
	 * alloc buffer of same size than parameter
	 */
	void sameAllocSameBufferSize(const VBO& vbo);

126 127 128 129 130
	/**
	 * update data from attribute multivector to the vbo (automatic conversion if necessary and possible)
	 */
	void updateData(const AttributeMultiVectorGen* attrib);

Thery Sylvain's avatar
Thery Sylvain committed
131 132 133
	/**
	 * update data from attribute handler to the vbo
	 */
134 135 136 137 138
	inline void updateData(const AttributeHandlerGen& attrib)
	{
		updateData(attrib.getDataVectorGen()) ;
	}

Thery Sylvain's avatar
Thery Sylvain committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
	/**
	 * update data from given data vector
	 * @warning use only with include vbo.h (not vbo_base.h)
	 */
	template <typename T>
	void updateData(std::vector<T>& data);

	void* lockPtr();

	const void* lockPtr() const;

	void releasePtr() const;

	void copyData(void *ptr) const;

	void allocate(unsigned int nbElts);
Sylvain Thery's avatar
Sylvain Thery committed
155

156
	/**
157
	 * update the VBO from Attribute Handler of vectors with on the fly conversion
158 159 160 161
	 * template paramters:
	 * T_IN input type  attribute handler
	 * NB_COMPONENTS 3 for vbo of pos/normal, 2 for texture etc..
	 * @param attribHG the attribute handler source
162
	 * @param conv lambda or function/fonctor that take a const T_IN& and return a Vector<NB_COMPONENTS,float>
163 164
	 */
	template <typename T_IN, unsigned int NB_COMPONENTS, typename CONVFUNC>
165
	inline void updateDataConversion(const AttributeHandlerGen& attribHG, CONVFUNC conv)
Sylvain Thery's avatar
Sylvain Thery committed
166
	{
167 168 169
		const AttributeMultiVectorGen* attrib = attribHG.getDataVectorGen();
		updateDataConversion<T_IN,Geom::Vector<NB_COMPONENTS,float>,NB_COMPONENTS,CONVFUNC>(attrib,conv);
	}
170

171 172 173 174 175 176 177 178 179 180
	/**
	 * update the VBO from Attribute Handler of vectors with on the fly conversion
	 * template paramters:
	 * T_IN input type  attribute handler
	 * @param attribHG the attribute handler source
	 * @param conv lambda or function/fonctor that take a const T_IN& and return a Vector<NB_COMPONENTS,float>
	 */
	template <typename T_IN, typename CONVFUNC>
	inline void updateDataConversion(const AttributeHandlerGen& attribHG, CONVFUNC conv)
	{
Sylvain Thery's avatar
Sylvain Thery committed
181
		const AttributeMultiVectorGen* attrib = attribHG.getDataVectorGen();
182 183
		updateDataConversion<T_IN,float,1,CONVFUNC>(attrib,conv);
	}
Sylvain Thery's avatar
Sylvain Thery committed
184

185 186 187 188 189 190 191 192 193 194 195 196 197 198

protected:
	/**
	 * update the VBO from Attribute Handler with on the fly conversion
	 * template paramters:
	 * T_IN input type  attribute handler
	 * NB_COMPONENTS 3 for vbo of pos/normal, 2 for texture etc..
	 * @param attrib the attribute multivector source
	 * @param conv lambda function that take a const T_IN& and return a Vector<NB_COMPONENTS,float>
	 */
	template <typename T_IN, typename T_OUT, unsigned int NB_COMPONENTS, typename CONVFUNC>
	void updateDataConversion(const AttributeMultiVectorGen* attrib, CONVFUNC conv)
	{
		unsigned int old_nbb =  sizeof(float) * m_data_size * m_nbElts;
Sylvain Thery's avatar
Sylvain Thery committed
199 200
		m_name = attrib->getName();
		m_typeName = attrib->getTypeName();
201
		m_data_size = NB_COMPONENTS;
Sylvain Thery's avatar
Sylvain Thery committed
202 203 204 205 206 207 208 209

		// alloue la memoire pour le buffer et initialise le conv
		T_OUT* typedBuffer = new T_OUT[_BLOCKSIZE_];

		std::vector<void*> addr;
		unsigned int byteTableSize;
		unsigned int nbb = attrib->getBlocksPointers(addr, byteTableSize);

210
		m_nbElts = nbb * _BLOCKSIZE_/(sizeof(T_OUT));
Sylvain Thery's avatar
Sylvain Thery committed
211 212 213 214

		unsigned int offset = 0;
		unsigned int szb = _BLOCKSIZE_*sizeof(T_OUT);

215 216
		// bind buffer to update
		glBindBuffer(GL_ARRAY_BUFFER, *m_id);
217 218
		if (nbb!=old_nbb)
			glBufferData(GL_ARRAY_BUFFER, nbb * szb, 0, GL_STREAM_DRAW);
219

Sylvain Thery's avatar
Sylvain Thery committed
220 221 222 223 224 225
		for (unsigned int i = 0; i < nbb; ++i)
		{
			// convertit les donnees dans le buffer de conv
			const T_IN* typedIn = reinterpret_cast<const T_IN*>(addr[i]);
			T_OUT* typedOut = typedBuffer;
			// compute conversion
226 227
			for (unsigned int j = 0; j < _BLOCKSIZE_; ++j)
				*typedOut++ = conv(*typedIn++);
Sylvain Thery's avatar
Sylvain Thery committed
228 229

			// update sub-vbo
230
			glBufferSubData(GL_ARRAY_BUFFER, offset, szb, reinterpret_cast<void*>(typedBuffer));
Sylvain Thery's avatar
Sylvain Thery committed
231 232 233 234 235 236
			// block suivant
			offset += szb;
		}

		// libere la memoire de la conversion
		delete[] typedBuffer;
237

Sylvain Thery's avatar
Sylvain Thery committed
238 239
	}

Thery Sylvain's avatar
Thery Sylvain committed
240 241
};

Sylvain Thery's avatar
Sylvain Thery committed
242 243


Thery Sylvain's avatar
Thery Sylvain committed
244 245 246 247 248
} // namespace Utils

} // namespace CGoGN

#endif