vbo.cpp 5.76 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1 2 3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
Pierre Kraemer's avatar
Pierre Kraemer committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
*                                                                              *
* 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.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
Pierre Kraemer's avatar
Pierre Kraemer committed
21 22 23 24
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

Thery Sylvain's avatar
Thery Sylvain committed
25
#include "Utils/vbo_base.h"
Sylvain Thery's avatar
Sylvain Thery committed
26
#include "Utils/GLSLShader.h"
27 28
#include <stdio.h>
#include <string.h>
Sylvain Thery's avatar
Sylvain Thery committed
29

Pierre Kraemer's avatar
Pierre Kraemer committed
30 31
namespace CGoGN
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
32

Sylvain Thery's avatar
Sylvain Thery committed
33
namespace Utils
Pierre Kraemer's avatar
Pierre Kraemer committed
34 35
{

36 37 38 39 40 41 42
VBO::VBO(const std::string& name) : m_nbElts(0), m_lock(false), m_name(name), m_conv(NULL)
{
	glGenBuffers(1, &(*m_id));
	m_refs.reserve(4);
}

VBO::VBO(ConvertBuffer* conv, const std::string& name) : m_nbElts(0), m_lock(false), m_name(name), m_conv(conv)
Pierre Kraemer's avatar
Pierre Kraemer committed
43
{
44
	glGenBuffers(1, &(*m_id));
Sylvain Thery's avatar
Sylvain Thery committed
45 46
	m_refs.reserve(4);
}
Pierre Kraemer's avatar
Pierre Kraemer committed
47

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
48 49 50
VBO::VBO(const VBO& vbo) :
	m_data_size(vbo.m_data_size),
	m_nbElts(vbo.m_nbElts),
51 52
	m_lock(false),
	m_conv(NULL)
53
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
54
	unsigned int nbbytes =  sizeof(float) * m_data_size * m_nbElts;
55

56
	glGenBuffers(1, &(*m_id));
57 58 59 60 61 62 63 64 65 66 67

	vbo.bind();
	void* src = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);

	bind();
	glBufferData(GL_ARRAY_BUFFER, nbbytes, src, GL_STREAM_DRAW);

	vbo.bind();
	glUnmapBuffer(GL_ARRAY_BUFFER);
}

Sylvain Thery's avatar
Sylvain Thery committed
68
VBO::~VBO()
Pierre Kraemer's avatar
Pierre Kraemer committed
69
{
70 71
	if (m_lock)
		releasePtr();
72
	glDeleteBuffers(1, &(*m_id));
Pierre Kraemer's avatar
Pierre Kraemer committed
73 74
}

75 76 77 78 79
void VBO::setBufferConverter(ConvertBuffer *conv)
{
	m_conv = conv;
}

80 81 82 83 84 85 86 87 88
void VBO::sameAllocSameBufferSize(const VBO& vbo)
{
	m_data_size = vbo.m_data_size;
	m_nbElts = vbo.m_nbElts;
	unsigned int nbbytes =  sizeof(float) * m_data_size * m_nbElts;
	bind();
	glBufferData(GL_ARRAY_BUFFER, nbbytes, NULL, GL_STREAM_DRAW);
}

89 90
void VBO::updateData(const AttributeMultiVectorGen* attrib)
{
91

92 93 94 95 96 97
	if (m_lock)
	{
		CGoGNerr << "Error locked VBO" << CGoGNendl;
		return;
	}

98 99 100 101 102 103
	if (m_conv != NULL)
	{
		updateData_withConversion(attrib, m_conv);
		return;
	}

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
	m_name = attrib->getName();
	m_typeName = attrib->getTypeName();

	m_data_size = attrib->getSizeOfType() / sizeof(float);

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

	glBindBuffer(GL_ARRAY_BUFFER, *m_id);
	glBufferData(GL_ARRAY_BUFFER, nbb * byteTableSize, 0, GL_STREAM_DRAW);

	m_nbElts = nbb * byteTableSize / attrib->getSizeOfType();

	unsigned int offset = 0;

	for (unsigned int i = 0; i < nbb; ++i)
	{
		glBufferSubDataARB(GL_ARRAY_BUFFER, offset, byteTableSize, addr[i]);
		offset += byteTableSize;
	}

}

128 129

void VBO::updateData_withConversion(const AttributeMultiVectorGen* attrib, ConvertBuffer* conv)
130 131 132 133
{

	m_name = attrib->getName();
	m_typeName = attrib->getTypeName();
134 135 136 137
	m_data_size = conv->vectorSize();

	// alloue la memoire pour le buffer et initialise le conv
	conv->reserve(attrib->getBlockSize());
138 139 140 141 142

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

Sylvain Thery's avatar
Sylvain Thery committed
143
//	m_nbElts = nbb * attrib->getBlockSize()/m_data_size;
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

	// bind buffer to update
	glBindBuffer(GL_ARRAY_BUFFER, *m_id);
	glBufferData(GL_ARRAY_BUFFER, nbb * conv->sizeBuffer(), 0, GL_STREAM_DRAW);

	unsigned int offset = 0;

	for (unsigned int i = 0; i < nbb; ++i)
	{
		// convertit les donnees dans le buffer de conv
		conv->convert(addr[i]);
		// update sub-vbo
		glBufferSubDataARB(GL_ARRAY_BUFFER, offset, conv->sizeBuffer(), conv->buffer());
		// block suivant
		offset += conv->sizeBuffer();
	}

	// libere la memoire de la conversion
	conv->release();
163

164 165
}

166 167 168 169
void* VBO::lockPtr()
{
	if (m_lock)
	{
170
		CGoGNerr << "Error already locked VBO" << CGoGNendl;
171 172 173
		return NULL;
	}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
174
	m_lock = true;
175
	glBindBuffer(GL_ARRAY_BUFFER, *m_id);
176 177 178
	return glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
}

179 180 181 182
const void* VBO::lockPtr() const
{
	if (m_lock)
	{
183
		CGoGNerr << "Error already locked VBO" << CGoGNendl;
184 185 186 187
		return NULL;
	}

	m_lock = true;
188
	glBindBuffer(GL_ARRAY_BUFFER, *m_id);
189 190 191 192
	return glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
}

void VBO::releasePtr() const
193
{
194
	glBindBuffer(GL_ARRAY_BUFFER, *m_id);
195
	glUnmapBuffer(GL_ARRAY_BUFFER);
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
196
	m_lock = false;
197 198
}

199 200
void VBO::copyData(void *ptr) const
{
201
	glBindBuffer(GL_ARRAY_BUFFER, *m_id);
202
	glGetBufferSubData(GL_ARRAY_BUFFER, 0, m_nbElts * m_data_size * sizeof(float), ptr);
203 204 205 206 207
}

void VBO::allocate(unsigned int nbElts)
{
	m_nbElts = nbElts;
208
	glBindBuffer(GL_ARRAY_BUFFER, *m_id);
209
	glBufferData(GL_ARRAY_BUFFER, nbElts * m_data_size * sizeof(float), 0, GL_STREAM_DRAW);
210 211
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
212
} // namespace Utils
213

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
214
} // namespace CGoGN