framework2

Форк
0
1115 строк · 32.0 Кб
1
//TODO:
2
//GL Error checking
3
// handle idling of arrays: possibly let gl create memory and use map buffers for streaming
4
// index updating/deleting?
5
// setVertexData with float* should know about ofVec3f vs ofVec2f?
6

7

8
#include "ofUtils.h"
9
#include "ofVbo.h"
10
#include "ofShader.h"
11
#include "ofGLUtils.h"
12
#include "ofMesh.h"
13
#include "ofGLBaseTypes.h"
14

15
#ifdef TARGET_ANDROID
16
#include "ofAppAndroidWindow.h"
17
#endif
18

19
using std::unordered_map;
20

21
bool ofVbo::vaoSupported=true;
22
bool ofVbo::vaoChecked=false;
23

24
#ifdef TARGET_OPENGLES
25
	#include <dlfcn.h>
26
	typedef void (* glGenVertexArraysType) (GLsizei n,  GLuint *arrays);
27
	glGenVertexArraysType glGenVertexArraysFunc = nullptr;
28
	#define glGenVertexArrays								glGenVertexArraysFunc
29

30
	typedef void (* glDeleteVertexArraysType) (GLsizei n,  GLuint *arrays);
31
	glDeleteVertexArraysType glDeleteVertexArraysFunc = nullptr;
32
	#define glDeleteVertexArrays							glDeleteVertexArraysFunc
33

34
	typedef void (* glBindVertexArrayType) (GLuint array);
35
	glBindVertexArrayType glBindVertexArrayFunc = nullptr;
36
	#define glBindVertexArray								glBindVertexArrayFunc
37
#endif
38

39
static unordered_map<GLuint,int> & getVAOIds(){
40
	static unordered_map<GLuint,int> * ids = new unordered_map<GLuint,int>;
41
	return *ids;
42
}
43

44
//--------------------------------------------------------------
45
static void retainVAO(GLuint id){
46
	if(id==0) return;
47
	if(getVAOIds().find(id)!=getVAOIds().end()){
48
		getVAOIds()[id]++;
49
	}else{
50
		getVAOIds()[id]=1;
51
	}
52
}
53

54
//--------------------------------------------------------------
55
static void releaseVAO(GLuint id){
56
	if(getVAOIds().find(id)!=getVAOIds().end()){
57
		getVAOIds()[id]--;
58
		if(getVAOIds()[id]==0){
59
#ifdef TARGET_ANDROID
60
			if (!ofAppAndroidWindow::isSurfaceDestroyed())
61
#endif
62
				glDeleteVertexArrays(1, &id);
63
			getVAOIds().erase(id);
64
		}
65
	}else{
66
		ofLogWarning("ofVbo") << "releaseVAO(): something's wrong here, releasing unknown vertex array object id " << id;
67

68
#ifdef TARGET_ANDROID
69
		if (!ofAppAndroidWindow::isSurfaceDestroyed())
70
#endif
71
			glDeleteVertexArrays(1, &id);
72
	}
73
}
74

75
//--------------------------------------------------------------
76
ofVbo::VertexAttribute::VertexAttribute()
77
:stride(0)
78
,offset(0)
79
,numCoords(0)
80
,location(0)
81
,normalize(false)
82
,divisor(0){
83

84
}
85

86
//--------------------------------------------------------------
87
bool ofVbo::VertexAttribute::isAllocated() const{
88
	return buffer.isAllocated();
89
}
90

91

92
//--------------------------------------------------------------
93
void ofVbo::VertexAttribute::allocate(){
94
	buffer.allocate();
95
}
96

97
//--------------------------------------------------------------
98
void ofVbo::VertexAttribute::bind() const{
99
	buffer.bind(GL_ARRAY_BUFFER);
100
}
101

102
//--------------------------------------------------------------
103
void ofVbo::VertexAttribute::setData(GLsizeiptr bytes, const void * data, GLenum usage){
104
	buffer.setData(bytes,data,usage);
105
}
106

107
//--------------------------------------------------------------
108
void ofVbo::VertexAttribute::unbind() const{
109
	buffer.unbind(GL_ARRAY_BUFFER);
110
}
111

112
//--------------------------------------------------------------
113
GLuint ofVbo::VertexAttribute::getId() const{
114
	return buffer.getId();
115
}
116

117
//--------------------------------------------------------------
118
void ofVbo::VertexAttribute::updateData(GLintptr offset, GLsizeiptr bytes, const void * data){
119
	buffer.updateData(offset,bytes,data);
120
}
121

122

123
//--------------------------------------------------------------
124
void ofVbo::VertexAttribute::setData(const float * attrib0x, int numCoords, int total, int usage, int stride, bool normalize){
125
	if (!isAllocated()) {
126
		allocate();
127
	}
128
	GLsizeiptr size = (stride == 0) ? numCoords * sizeof(float) : stride;
129
	this->stride = size;
130
	this->numCoords = numCoords;
131
	this->offset = 0;
132
	this->normalize = normalize;
133
	setData(total * size, attrib0x, usage);
134
};
135

136
//--------------------------------------------------------------
137
void ofVbo::VertexAttribute::setBuffer(ofBufferObject & buffer, int numCoords, int stride, int offset){
138
	this->buffer = buffer;
139
	this->offset = offset;
140
	this->numCoords = numCoords;
141
	GLsizeiptr size = (stride == 0) ? numCoords * sizeof(float) : stride;
142
	this->stride = size;
143

144
};
145

146
//--------------------------------------------------------------
147
void ofVbo::VertexAttribute::enable() const{
148
	bind();
149
	glEnableVertexAttribArray(location);
150
	glVertexAttribPointer(location, numCoords, GL_FLOAT, normalize?GL_TRUE:GL_FALSE, stride, (void*)offset);
151
#ifndef TARGET_OPENGLES
152
	glVertexAttribDivisor(location, divisor);
153
#endif
154
	unbind();
155
}
156

157
//--------------------------------------------------------------
158
void ofVbo::VertexAttribute::disable() const{
159
	glDisableVertexAttribArray(location);
160
}
161

162
//--------------------------------------------------------------
163
ofVbo::IndexAttribute::IndexAttribute()
164
{
165

166
}
167

168
//--------------------------------------------------------------
169
bool ofVbo::IndexAttribute::isAllocated() const{
170
	return buffer.isAllocated();
171
}
172

173
//--------------------------------------------------------------
174
void ofVbo::IndexAttribute::allocate(){
175
	buffer.allocate();
176
}
177

178
//--------------------------------------------------------------
179
void ofVbo::IndexAttribute::bind() const{
180
	buffer.bind(GL_ELEMENT_ARRAY_BUFFER);
181
}
182

183
//--------------------------------------------------------------
184
void ofVbo::IndexAttribute::setData(GLsizeiptr bytes, const void * data, GLenum usage){
185
	buffer.bind(GL_ELEMENT_ARRAY_BUFFER);
186
	buffer.setData(bytes,data,usage);
187
	buffer.unbind(GL_ELEMENT_ARRAY_BUFFER);
188
}
189

190
//--------------------------------------------------------------
191
void ofVbo::IndexAttribute::unbind() const{
192
	buffer.unbind(GL_ELEMENT_ARRAY_BUFFER);
193
}
194

195
//--------------------------------------------------------------
196
void ofVbo::IndexAttribute::updateData(GLintptr offset, GLsizeiptr bytes, const void * data){
197
	buffer.updateData(offset,bytes,data);
198
}
199

200
//--------------------------------------------------------------
201
GLuint ofVbo::IndexAttribute::getId() const{
202
	return buffer.getId();
203
}
204

205

206
//--------------------------------------------------------------
207
ofVbo::ofVbo(){
208
	bUsingVerts = false;
209
	bUsingTexCoords = false;
210
	bUsingColors = false;
211
	bUsingNormals = false;
212
	bUsingIndices = false;
213

214
	totalVerts = 0;
215
	totalIndices = 0;
216

217
	vaoChanged 		= false;
218
	vaoID			= 0;
219

220
	positionAttribute.location = ofShader::POSITION_ATTRIBUTE;
221
	colorAttribute.location = ofShader::COLOR_ATTRIBUTE;
222
	texCoordAttribute.location = ofShader::TEXCOORD_ATTRIBUTE;
223
	normalAttribute.location = ofShader::NORMAL_ATTRIBUTE;
224
}
225

226
ofVbo::ofVbo(const ofVbo & mom){
227
	bUsingVerts = mom.bUsingVerts;
228
	bUsingTexCoords = mom.bUsingTexCoords;
229
	bUsingColors = mom.bUsingColors;
230
	bUsingNormals = mom.bUsingNormals;
231
	bUsingIndices = mom.bUsingIndices;
232

233
	positionAttribute = mom.positionAttribute;
234
	colorAttribute = mom.colorAttribute;
235
	texCoordAttribute = mom.texCoordAttribute;
236
	normalAttribute = mom.normalAttribute;
237

238
	customAttributes = mom.customAttributes;
239

240
	totalVerts = mom.totalVerts;
241
	totalIndices = mom.totalIndices;
242
	indexAttribute = mom.indexAttribute;
243

244
	vaoChanged = mom.vaoChanged;
245
	vaoID = mom.vaoID;
246

247
	if(ofIsGLProgrammableRenderer()){
248
		retainVAO(vaoID);
249
	}
250
}
251

252
ofVbo & ofVbo::operator=(const ofVbo& mom){
253
	if(&mom==this) return *this;
254
	clear();
255
	bUsingVerts = mom.bUsingVerts;
256
	bUsingTexCoords = mom.bUsingTexCoords;
257
	bUsingColors = mom.bUsingColors;
258
	bUsingNormals = mom.bUsingNormals;
259
	bUsingIndices = mom.bUsingIndices;
260

261
	positionAttribute = mom.positionAttribute;
262
	colorAttribute = mom.colorAttribute;
263
	texCoordAttribute = mom.texCoordAttribute;
264
	normalAttribute = mom.normalAttribute;
265

266
	customAttributes = mom.customAttributes;
267

268
	totalVerts = mom.totalVerts;
269
	totalIndices = mom.totalIndices;
270
	indexAttribute = mom.indexAttribute;
271

272
	vaoChanged = mom.vaoChanged;
273
	vaoID = mom.vaoID;
274

275
	if(ofIsGLProgrammableRenderer()){
276
		retainVAO(vaoID);
277
	}
278
	return *this;
279
}
280

281
//--------------------------------------------------------------
282
ofVbo::~ofVbo(){
283
	clear();
284
}
285

286
//--------------------------------------------------------------
287
void ofVbo::setMesh(const ofMesh & mesh, int usage){
288
	setMesh(mesh,usage,mesh.hasColors(),mesh.hasTexCoords(),mesh.hasNormals());
289
}
290

291
//--------------------------------------------------------------
292
void ofVbo::setMesh(const ofMesh & mesh, int usage, bool useColors, bool useTextures, bool useNormals){
293
	if(mesh.getVertices().empty()){
294
		ofLogWarning("ofVbo") << "setMesh(): ignoring mesh with no vertices";
295
		return;
296
	}
297
	setVertexData(mesh.getVerticesPointer(),mesh.getNumVertices(),usage);
298
	if(mesh.hasColors() && useColors){
299
		setColorData(mesh.getColorsPointer(),mesh.getNumColors(),usage);
300
		enableColors();
301
	}else{
302
		disableColors();
303
	}
304
	if(mesh.hasNormals() && useNormals){
305
		setNormalData(mesh.getNormalsPointer(),mesh.getNumNormals(),usage);
306
		enableNormals();
307
	}else{
308
		disableNormals();
309
	}
310
	if(mesh.hasTexCoords() && useTextures){
311
		setTexCoordData(mesh.getTexCoordsPointer(),mesh.getNumTexCoords(),usage);
312
		enableTexCoords();
313
	}else{
314
		disableTexCoords();
315
	}
316
	if(mesh.hasIndices()){
317
		setIndexData(mesh.getIndexPointer(), mesh.getNumIndices(), usage);
318
		enableIndices();
319
	}else{
320
		disableIndices();
321
	}
322
}
323

324
//--------------------------------------------------------------
325
void ofVbo::setVertexData(const glm::vec3 * verts, int total, int usage) {
326
	setVertexData(&verts[0].x,3,total,usage,sizeof(glm::vec3));
327
}
328

329
//--------------------------------------------------------------
330
void ofVbo::setVertexData(const ofVec3f * verts, int total, int usage) {
331
	setVertexData(&verts[0].x,3,total,usage,sizeof(glm::vec3));
332
}
333

334
//--------------------------------------------------------------
335
void ofVbo::setVertexData(const glm::vec2 * verts, int total, int usage) {
336
	setVertexData(&verts[0].x,2,total,usage,sizeof(glm::vec2));
337
}
338

339
//--------------------------------------------------------------
340
void ofVbo::setVertexData(const ofVec2f * verts, int total, int usage) {
341
	setVertexData(&verts[0].x,2,total,usage,sizeof(glm::vec2));
342
}
343

344
//--------------------------------------------------------------
345
void ofVbo::setVertexData(const float * vert0x, int numCoords, int total, int usage, int stride) {
346
	positionAttribute.setData(vert0x, numCoords, total, usage, stride);
347
	bUsingVerts = true;
348
	totalVerts = total;
349
}
350

351
//--------------------------------------------------------------
352
void ofVbo::setColorData(const ofFloatColor * colors, int total, int usage) {
353
	setColorData(&colors[0].r,total,usage,sizeof(ofFloatColor));
354
}
355

356
//--------------------------------------------------------------
357
void ofVbo::setColorData(const float * color0r, int total, int usage, int stride) {
358
	colorAttribute.setData(color0r, 4, total, usage, stride);
359
	enableColors();
360
}
361

362
//--------------------------------------------------------------
363
void ofVbo::setNormalData(const glm::vec3 * normals, int total, int usage) {
364
	setNormalData(&normals[0].x,total,usage,sizeof(glm::vec3));
365
}
366

367
//--------------------------------------------------------------
368
void ofVbo::setNormalData(const ofVec3f * normals, int total, int usage) {
369
	setNormalData(&normals[0].x,total,usage,sizeof(glm::vec3));
370
}
371

372
//--------------------------------------------------------------
373
void ofVbo::setNormalData(const float * normal0x, int total, int usage, int stride) {
374
	normalAttribute.setData(normal0x, 3, total, usage, stride);
375
	enableNormals();
376
}
377

378
//--------------------------------------------------------------
379
void ofVbo::setTexCoordData(const glm::vec2 * texCoords, int total, int usage) {
380
	setTexCoordData(&texCoords[0].x,total, usage, sizeof(glm::vec2));
381
}
382

383
//--------------------------------------------------------------
384
void ofVbo::setTexCoordData(const ofVec2f * texCoords, int total, int usage) {
385
	setTexCoordData(&texCoords[0].x,total, usage, sizeof(glm::vec2));
386
}
387

388
//--------------------------------------------------------------
389
void ofVbo::setTexCoordData(const float * texCoord0x, int total, int usage, int stride) {
390
	texCoordAttribute.setData(texCoord0x, 2, total, usage, stride);
391
	enableTexCoords();
392
}
393

394

395
//--------------------------------------------------------------
396
void ofVbo::setIndexData(const ofIndexType * indices, int total, int usage){
397
	if(!indexAttribute.isAllocated()){
398
		indexAttribute.allocate();
399
		enableIndices();
400
	}
401
	totalIndices = total;
402
	indexAttribute.setData(sizeof(ofIndexType) * total, &indices[0], usage);
403
}
404

405
//--------------------------------------------------------------
406
ofVbo::VertexAttribute & ofVbo::getOrCreateAttr(int location){
407
	VertexAttribute * attr = nullptr;
408
	if (ofIsGLProgrammableRenderer()) {
409
		switch (location){
410
			case ofShader::POSITION_ATTRIBUTE:
411
				attr = &positionAttribute;
412
				break;
413
			case ofShader::COLOR_ATTRIBUTE:
414
				attr = &colorAttribute;
415
				break;
416
			case ofShader::NORMAL_ATTRIBUTE:
417
				attr = &normalAttribute;
418
				break;
419
			case ofShader::TEXCOORD_ATTRIBUTE:
420
				attr = &texCoordAttribute;
421
				break;
422
			default:
423
				customAttributes[location].location = location;
424
				attr = &customAttributes[location];
425
				vaoChanged = true;
426
				break;
427
		}
428
	}else{
429
		customAttributes[location].location = location;
430
		attr = &customAttributes[location];
431
		vaoChanged = true;
432
	}
433
	return *attr;
434
}
435

436
//--------------------------------------------------------------
437
void ofVbo::setAttributeData(int location, const float * attrib0x, int numCoords, int total, int usage, int stride){
438
	if(ofIsGLProgrammableRenderer() && location==ofShader::POSITION_ATTRIBUTE){
439
		totalVerts = total;
440
	}
441

442
	bool normalize = false;
443
	if(ofIsGLProgrammableRenderer() && !hasAttribute(location)){
444
		vaoChanged = true;
445
		bUsingVerts |= (location == ofShader::POSITION_ATTRIBUTE);
446
		bUsingColors |= (location == ofShader::COLOR_ATTRIBUTE);
447
		bUsingNormals |= (location == ofShader::NORMAL_ATTRIBUTE);
448
		bUsingTexCoords |= (location == ofShader::TEXCOORD_ATTRIBUTE);
449
	}
450

451
	getOrCreateAttr(location).setData(attrib0x,numCoords,total,usage,stride,normalize);
452
}
453

454
#ifndef TARGET_OPENGLES
455
//--------------------------------------------------------------
456
void ofVbo::setAttributeDivisor(int location, int divisor){
457
	getOrCreateAttr(location).divisor = divisor;
458
}
459
#endif
460

461
//--------------------------------------------------------------
462
void ofVbo::updateMesh(const ofMesh & mesh){
463
	updateVertexData(mesh.getVerticesPointer(),mesh.getNumVertices());
464
	updateColorData(mesh.getColorsPointer(),mesh.getNumColors());
465
	updateNormalData(mesh.getNormalsPointer(),mesh.getNumNormals());
466
	updateTexCoordData(mesh.getTexCoordsPointer(),mesh.getNumTexCoords());
467
}
468

469
//--------------------------------------------------------------
470
void ofVbo::updateVertexData(const glm::vec3 * verts, int total) {
471
	updateVertexData(&verts[0].x,total);
472
}
473

474
//--------------------------------------------------------------
475
void ofVbo::updateVertexData(const ofVec3f * verts, int total) {
476
	updateVertexData(&verts[0].x,total);
477
}
478

479
//--------------------------------------------------------------
480
void ofVbo::updateVertexData(const glm::vec2 * verts, int total) {
481
	updateVertexData(&verts[0].x,total);
482
}
483

484
//--------------------------------------------------------------
485
void ofVbo::updateVertexData(const ofVec2f * verts, int total) {
486
	updateVertexData(&verts[0].x,total);
487
}
488

489
//--------------------------------------------------------------
490
void ofVbo::updateVertexData(const float * vert0x, int total) {
491
	positionAttribute.updateData(0, total * positionAttribute.stride, vert0x);
492
}
493

494
//--------------------------------------------------------------
495
void ofVbo::updateColorData(const ofFloatColor * colors, int total) {
496
	updateColorData(&colors[0].r,total);
497
}
498

499
//--------------------------------------------------------------
500
void ofVbo::updateColorData(const float * color0r, int total) {
501
	colorAttribute.updateData(0, total * colorAttribute.stride, color0r);
502
}
503

504
//--------------------------------------------------------------
505
void ofVbo::updateNormalData(const glm::vec3 * normals, int total) {
506
	updateNormalData(&normals[0].x,total);
507
}
508

509
//--------------------------------------------------------------
510
void ofVbo::updateNormalData(const ofVec3f * normals, int total) {
511
	updateNormalData(&normals[0].x,total);
512
}
513

514
//--------------------------------------------------------------
515
void ofVbo::updateNormalData(const float * normal0x, int total) {
516
	normalAttribute.updateData(0, total * normalAttribute.stride, normal0x);
517
}
518

519
//--------------------------------------------------------------
520
void ofVbo::updateTexCoordData(const glm::vec2 * texCoords, int total) {
521
	updateTexCoordData(&texCoords[0].x,total);
522
}
523

524
//--------------------------------------------------------------
525
void ofVbo::updateTexCoordData(const ofVec2f * texCoords, int total) {
526
	updateTexCoordData(&texCoords[0].x,total);
527
}
528

529
//--------------------------------------------------------------
530
void ofVbo::updateTexCoordData(const float * texCoord0x, int total) {
531
	texCoordAttribute.updateData(0, total * texCoordAttribute.stride, texCoord0x);
532
}
533

534
//--------------------------------------------------------------
535
void ofVbo::updateIndexData(const ofIndexType * indices, int total) {
536
	if(indexAttribute.isAllocated()) {
537
		indexAttribute.updateData(0, total*sizeof(ofIndexType), indices);
538
	}
539
}
540

541
void ofVbo::updateAttributeData(int location, const float * attr0x, int total){
542
	VertexAttribute * attr = nullptr;
543
	if (ofIsGLProgrammableRenderer()) {
544
		switch (location){
545
			case ofShader::POSITION_ATTRIBUTE:
546
				attr = &positionAttribute;
547
				break;
548
			case ofShader::COLOR_ATTRIBUTE:
549
				attr = &colorAttribute;
550
				break;
551
			case ofShader::NORMAL_ATTRIBUTE:
552
				attr = &normalAttribute;
553
				break;
554
			case ofShader::TEXCOORD_ATTRIBUTE:
555
				attr = &texCoordAttribute;
556
				break;
557
			default:
558
				if(customAttributes.find(location)!=customAttributes.end()) {
559
					attr = &customAttributes[location];
560
				}
561
				break;
562
		}
563
	} else {
564
		if(customAttributes.find(location)!=customAttributes.end()) {
565
			attr = &customAttributes[location];
566
		}
567
	}
568
	if (attr !=nullptr && attr->isAllocated()) {
569
		attr->updateData(0, total*attr->stride, attr0x);
570
	}
571
}
572

573
void ofVbo::enableColors() {
574
	if (!bUsingColors && colorAttribute.isAllocated()) {
575
		bUsingColors=true;
576
		vaoChanged = true;
577
	}
578
}
579

580
void ofVbo::enableNormals(){
581
	if (!bUsingNormals && normalAttribute.isAllocated()) {
582
		bUsingNormals=true;
583
		vaoChanged = true;
584
	}
585
}
586

587
void ofVbo::enableTexCoords(){
588
	if (!bUsingTexCoords && texCoordAttribute.isAllocated()){
589
		bUsingTexCoords = true;
590
		vaoChanged = true;
591
	}
592
}
593

594
void ofVbo::enableIndices(){
595
	if(indexAttribute.isAllocated() && !bUsingIndices){
596
		bUsingIndices=true;
597
		vaoChanged = true;
598
	}
599
}
600

601
void ofVbo::disableColors(){
602
	if(bUsingColors){
603
		bUsingColors=false;
604
		vaoChanged = true;
605
	}
606
}
607

608
void ofVbo::disableNormals(){
609
	if(bUsingNormals){
610
		bUsingNormals=false;
611
		vaoChanged = true;
612
	}
613
}
614

615
void ofVbo::disableTexCoords(){
616
	if(bUsingTexCoords){
617
		bUsingTexCoords=false;
618
		vaoChanged = true;
619
	}
620
}
621

622
void ofVbo::disableIndices(){
623
	if(bUsingIndices){
624
		bUsingIndices=false;
625
		vaoChanged = true;
626
	}
627
}
628

629
//--------------------------------------------------------------
630
bool ofVbo::getIsAllocated() const {
631
	return positionAttribute.isAllocated();
632
}
633

634
//--------------------------------------------------------------
635
bool ofVbo::getUsingVerts() const  {
636
	return bUsingVerts;
637
}
638

639
//--------------------------------------------------------------
640
bool ofVbo::getUsingColors() const {
641
	return bUsingColors;
642
}
643

644
//--------------------------------------------------------------
645
bool ofVbo::getUsingNormals() const {
646
	return bUsingNormals;
647
}
648

649
//--------------------------------------------------------------
650
bool ofVbo::getUsingTexCoords() const {
651
	return bUsingTexCoords;
652
}
653

654
//--------------------------------------------------------------
655
bool ofVbo::getUsingIndices() const {
656
	return  bUsingIndices;
657
}
658

659
//--------------------------------------------------------------
660
GLuint ofVbo::getVaoId() const{
661
	return vaoID;
662
}
663

664
//--------------------------------------------------------------
665
GLuint ofVbo::getVertId() const {
666
	return positionAttribute.getId();
667
}
668

669
//--------------------------------------------------------------
670
GLuint ofVbo::getColorId() const{
671
	return colorAttribute.getId();
672
}
673

674
//--------------------------------------------------------------
675
GLuint ofVbo::getNormalId() const {
676
	return normalAttribute.getId();
677
}
678

679
//--------------------------------------------------------------
680
GLuint ofVbo::getTexCoordId() const {
681
	return texCoordAttribute.getId();
682
}
683

684
//--------------------------------------------------------------
685
GLuint ofVbo::getIndexId() const {
686
	return indexAttribute.getId();
687
}
688

689
//--------------------------------------------------------------
690
GLuint ofVbo::getAttributeId(int location) const {
691
	if (!hasAttribute(location)) {
692
		ofLogWarning() << "No attribute id found for attribute pos: " << location;
693
		return 0;
694
	}
695
	return const_cast<ofVbo*>(this)->getOrCreateAttr(location).getId();
696
}
697

698
//--------------------------------------------------------------
699
void ofVbo::setVertexBuffer(ofBufferObject & buffer, int numCoords, int stride, int offset){
700
	positionAttribute.setBuffer(buffer, numCoords, stride, offset);
701
	bUsingVerts = true;
702
	vaoChanged = true;
703
	// Calculate the total number of vertices based on what we know:
704
	int tmpStride = stride;
705
	if (tmpStride == 0) {
706
		// if stride is not given through argument, we need to calculate it based on
707
		// on the data size and the number of coordinates.
708
		tmpStride = (numCoords * sizeof(float));
709
		if (tmpStride == 0) {
710
			ofLogWarning() << "Setting buffer with 0 vertices.";
711
			totalVerts = 0;
712
			return;
713
		}
714
	}
715
	totalVerts = buffer.size() / tmpStride;
716
}
717

718
//--------------------------------------------------------------
719
void ofVbo::setColorBuffer(ofBufferObject & buffer, int stride, int offset){
720
	colorAttribute.setBuffer(buffer, 4, stride, offset);
721
	enableColors();
722
}
723

724
//--------------------------------------------------------------
725
void ofVbo::setNormalBuffer(ofBufferObject & buffer, int stride, int offset){
726
	normalAttribute.setBuffer(buffer, 3, stride, offset);
727
	enableNormals();
728
}
729

730
//--------------------------------------------------------------
731
void ofVbo::setTexCoordBuffer(ofBufferObject & buffer, int stride, int offset){
732
	texCoordAttribute.setBuffer(buffer, 2, stride, offset);
733
	enableTexCoords();
734
}
735

736
//--------------------------------------------------------------
737
void ofVbo::setIndexBuffer(ofBufferObject & buffer){
738
	indexAttribute.buffer = buffer;
739
	vaoChanged = true;
740
	enableIndices();
741
}
742

743
//--------------------------------------------------------------
744
void ofVbo::setAttributeBuffer(int location, ofBufferObject & buffer, int numCoords, int stride, int offset){
745
	if(ofIsGLProgrammableRenderer() && !hasAttribute(location)){
746
		vaoChanged = true;
747
		bUsingVerts |= (location == ofShader::POSITION_ATTRIBUTE);
748
		bUsingColors |= (location == ofShader::COLOR_ATTRIBUTE);
749
		bUsingNormals |= (location == ofShader::NORMAL_ATTRIBUTE);
750
		bUsingTexCoords |= (location == ofShader::TEXCOORD_ATTRIBUTE);
751
	}
752

753
	getOrCreateAttr(location).setBuffer(buffer, numCoords, stride, offset);
754
}
755

756
//--------------------------------------------------------------
757
ofBufferObject & ofVbo::getVertexBuffer(){
758
	return positionAttribute.buffer;
759
}
760

761
//--------------------------------------------------------------
762
ofBufferObject & ofVbo::getColorBuffer(){
763
	return colorAttribute.buffer;
764
}
765

766
//--------------------------------------------------------------
767
ofBufferObject & ofVbo::getNormalBuffer(){
768
	return normalAttribute.buffer;
769
}
770

771
//--------------------------------------------------------------
772
ofBufferObject & ofVbo::getTexCoordBuffer(){
773
	return texCoordAttribute.buffer;
774
}
775

776
//--------------------------------------------------------------
777
ofBufferObject & ofVbo::getIndexBuffer(){
778
	return indexAttribute.buffer;
779
}
780

781
//--------------------------------------------------------------
782
ofBufferObject & ofVbo::getAttributeBuffer(int attributePos_) {
783
	
784
	if( attributePos_ == ofShader::POSITION_ATTRIBUTE ) {
785
		return getVertexBuffer();
786
	} else if( attributePos_ == ofShader::COLOR_ATTRIBUTE ) {
787
		return getColorBuffer();
788
	} else if( attributePos_ == ofShader::NORMAL_ATTRIBUTE ) {
789
		return getNormalBuffer();
790
	} else if( attributePos_ == ofShader::TEXCOORD_ATTRIBUTE ) {
791
		return getTexCoordBuffer();
792
	}
793
	
794
	return customAttributes.at(attributePos_).buffer;
795
}
796

797
//--------------------------------------------------------------
798
const ofBufferObject & ofVbo::getVertexBuffer() const{
799
	return positionAttribute.buffer;
800
}
801

802
//--------------------------------------------------------------
803
const ofBufferObject & ofVbo::getColorBuffer() const{
804
	return colorAttribute.buffer;
805
}
806

807
//--------------------------------------------------------------
808
const ofBufferObject & ofVbo::getNormalBuffer() const{
809
	return normalAttribute.buffer;
810
}
811

812
//--------------------------------------------------------------
813
const ofBufferObject & ofVbo::getTexCoordBuffer() const{
814
	return texCoordAttribute.buffer;
815
}
816

817
//--------------------------------------------------------------
818
const ofBufferObject & ofVbo::getAttributeBuffer(int attributePos_) const{
819
	if( attributePos_ == ofShader::POSITION_ATTRIBUTE ) {
820
		return getVertexBuffer();
821
	} else if( attributePos_ == ofShader::COLOR_ATTRIBUTE ) {
822
		return getColorBuffer();
823
	} else if( attributePos_ == ofShader::NORMAL_ATTRIBUTE ) {
824
		return getNormalBuffer();
825
	} else if( attributePos_ == ofShader::TEXCOORD_ATTRIBUTE ) {
826
		return getTexCoordBuffer();
827
	}
828
	
829
	return customAttributes.at(attributePos_).buffer;
830
}
831

832

833
//--------------------------------------------------------------
834
const ofBufferObject & ofVbo::getIndexBuffer() const{
835
	return indexAttribute.buffer;
836
}
837

838
//--------------------------------------------------------------
839
void ofVbo::bind() const{
840
	bool programmable = ofIsGLProgrammableRenderer();
841
	if(programmable && (vaoSupported || !vaoChecked)){
842
		if(vaoID==0){
843
			#if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN)
844
			if(glGenVertexArrays==0 && !vaoChecked){
845
				glGenVertexArrays = (glGenVertexArraysType)dlsym(RTLD_DEFAULT, "glGenVertexArrays");
846
				glDeleteVertexArrays = (glDeleteVertexArraysType)dlsym(RTLD_DEFAULT, "glDeleteVertexArrays");
847
				glBindVertexArray = (glBindVertexArrayType)dlsym(RTLD_DEFAULT, "glBindVertexArray");
848
				vaoChecked = true;
849
				vaoSupported = glGenVertexArrays;
850
			}
851
			#elif  defined(TARGET_EMSCRIPTEN)
852
				vaoChecked = true;
853
				vaoSupported = false;
854
			#else
855
				vaoChecked = true;
856
				vaoSupported = true;
857
			#endif
858
			if(vaoSupported) glGenVertexArrays(1, &const_cast<ofVbo*>(this)->vaoID);
859
			if(vaoID!=0){
860
				retainVAO(vaoID);
861
				vaoChanged = true;
862
			}
863
		}
864
		if(vaoSupported) glBindVertexArray(vaoID);
865
	}else{
866
		vaoSupported = false;
867
	}
868

869
	if(vaoChanged || !vaoSupported){
870
		if(bUsingVerts){
871
			if(!programmable){
872
				positionAttribute.bind();
873
				#ifndef TARGET_PROGRAMMABLE_GL
874
				glEnableClientState(GL_VERTEX_ARRAY);
875
				glVertexPointer(positionAttribute.numCoords, GL_FLOAT,
876
								positionAttribute.stride,
877
								(void*)positionAttribute.offset);
878
				#endif
879
			}else{
880
				positionAttribute.enable();
881
			}
882
		}else if(programmable){
883
			positionAttribute.disable();
884
		}
885

886
		if(bUsingColors) {
887
			if(!programmable){
888
				colorAttribute.bind();
889
				#ifndef TARGET_PROGRAMMABLE_GL
890
				glEnableClientState(GL_COLOR_ARRAY);
891
				glColorPointer(colorAttribute.numCoords, GL_FLOAT,
892
						colorAttribute.stride,
893
							   (void*)colorAttribute.offset);
894
				#endif
895
			}else{
896
				colorAttribute.enable();
897
			}
898
		}else if(programmable){
899
			colorAttribute.disable();
900
		}
901

902
		if(bUsingNormals) {
903
			if(!programmable){
904
				normalAttribute.bind();
905
				#ifndef TARGET_PROGRAMMABLE_GL
906
				glEnableClientState(GL_NORMAL_ARRAY);
907
				glNormalPointer(GL_FLOAT, normalAttribute.stride,
908
								(void*)normalAttribute.offset);
909
				#endif
910
			}else{
911
				normalAttribute.enable();
912
			}
913
		}else if(programmable){
914
			normalAttribute.disable();
915
		}
916

917
		if(bUsingTexCoords) {
918
			if(!programmable){
919
				texCoordAttribute.bind();
920
				#ifndef TARGET_PROGRAMMABLE_GL
921
				glEnableClientState(GL_TEXTURE_COORD_ARRAY);
922
				glTexCoordPointer(texCoordAttribute.numCoords,
923
								  GL_FLOAT, texCoordAttribute.stride,
924
								  (void*)texCoordAttribute.offset);
925
				#endif
926
			}else{
927
				texCoordAttribute.enable();
928
			}
929
		}else if(programmable){
930
			texCoordAttribute.disable();
931
		}
932

933
        if (bUsingIndices) {
934
            indexAttribute.bind();
935
        }
936

937
		unordered_map<int,VertexAttribute>::const_iterator it;
938
		for(it = customAttributes.begin();it!=customAttributes.end();it++){
939
			it->second.enable();
940
		}
941

942
		vaoChanged=false;
943
	}
944
}
945

946
//--------------------------------------------------------------
947
void ofVbo::unbind() const{
948
	if(vaoSupported){
949
		glBindVertexArray(0);
950
	}
951
	glBindBuffer(GL_ARRAY_BUFFER, 0);
952
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
953
	if(!ofIsGLProgrammableRenderer()){
954
		#ifndef TARGET_PROGRAMMABLE_GL
955
		if(bUsingColors){
956
			glDisableClientState(GL_COLOR_ARRAY);
957
		}
958
		if(bUsingNormals){
959
			glDisableClientState(GL_NORMAL_ARRAY);
960
		}
961
		if(bUsingTexCoords){
962
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
963
		}
964
		#endif
965
	}
966
}
967

968
//--------------------------------------------------------------
969
void ofVbo::draw(int drawMode, int first, int total) const{
970
	ofGetGLRenderer()->draw(*this,drawMode,first,total);
971
}
972

973
//--------------------------------------------------------------
974
void ofVbo::drawElements(int drawMode, int amt, int offsetelements) const{
975
	ofGetGLRenderer()->drawElements(*this,drawMode,amt,offsetelements);
976
}
977

978
//--------------------------------------------------------------
979
void ofVbo::drawInstanced(int drawMode, int first, int total, int primCount) const{
980
	ofGetGLRenderer()->drawInstanced(*this,drawMode,first,total,primCount);
981
}
982

983
//--------------------------------------------------------------
984
void ofVbo::drawElementsInstanced(int drawMode, int amt, int primCount) const{
985
	ofGetGLRenderer()->drawElementsInstanced(*this,drawMode,amt,primCount);
986
}
987

988
//--------------------------------------------------------------
989
void ofVbo::clear(){
990

991
	// clear all fixed function attributes
992

993
	clearVertices();
994
	clearColors();
995
	clearNormals();
996
	clearTexCoords();
997

998
	// we're not using any of these.
999
	bUsingVerts = false;
1000
	bUsingColors = false;
1001
	bUsingNormals = false;
1002
	bUsingTexCoords = false;
1003

1004
	// clear all custom attributes.
1005
	customAttributes.clear();
1006

1007
	clearIndices();
1008
	if(vaoID!=0){
1009
		releaseVAO(vaoID);
1010
		vaoID=0;
1011
	}
1012
}
1013

1014

1015
//--------------------------------------------------------------
1016
void ofVbo::clearVertices(){
1017
	positionAttribute = VertexAttribute();
1018
	positionAttribute.location = ofShader::POSITION_ATTRIBUTE;
1019
	bUsingVerts = false;
1020
	totalVerts = 0;
1021
}
1022

1023
//--------------------------------------------------------------
1024
void ofVbo::clearNormals(){
1025
	normalAttribute = VertexAttribute();
1026
	normalAttribute.location = ofShader::NORMAL_ATTRIBUTE;
1027
	bUsingNormals = false;
1028
}
1029

1030
//--------------------------------------------------------------
1031
void ofVbo::clearColors(){
1032
	colorAttribute = VertexAttribute();
1033
	colorAttribute.location = ofShader::COLOR_ATTRIBUTE;
1034
	bUsingColors = false;
1035

1036
}
1037

1038
//--------------------------------------------------------------
1039
void ofVbo::clearTexCoords(){
1040
	texCoordAttribute = VertexAttribute();
1041
	texCoordAttribute.location = ofShader::TEXCOORD_ATTRIBUTE;
1042
	bUsingTexCoords = false;
1043
}
1044

1045
//--------------------------------------------------------------
1046
void ofVbo::clearIndices(){
1047
	if(indexAttribute.isAllocated()){
1048
		indexAttribute = IndexAttribute();
1049
		bUsingIndices = false;
1050
		totalIndices = 0;
1051
	}
1052
}
1053

1054
//--------------------------------------------------------------
1055

1056
void ofVbo::clearAttribute(int attributePos_){
1057

1058
	if (!hasAttribute(attributePos_)) return;
1059

1060
	if (ofIsGLProgrammableRenderer()) {
1061
		if(attributePos_>3){
1062
			customAttributes.erase(attributePos_);
1063
		}else{
1064
			switch (attributePos_){
1065
				case ofShader::POSITION_ATTRIBUTE:
1066
					clearVertices();
1067
					break;
1068
				case ofShader::COLOR_ATTRIBUTE:
1069
					clearColors();
1070
					break;
1071
				case ofShader::NORMAL_ATTRIBUTE:
1072
					clearNormals();
1073
					break;
1074
				case ofShader::TEXCOORD_ATTRIBUTE:
1075
					clearTexCoords();
1076
					break;
1077
				default:
1078
					break;
1079
			}
1080
		}
1081
	}else{
1082
		customAttributes.erase(attributePos_);
1083
	}
1084
}
1085

1086
//--------------------------------------------------------------
1087
int ofVbo::getNumIndices() const {
1088
	if (bUsingIndices) {
1089
		return totalIndices;
1090
	} else {
1091
		return 0;
1092
	}
1093
}
1094

1095
//--------------------------------------------------------------
1096
int ofVbo::getNumVertices() const {
1097
	return totalVerts;
1098
}
1099

1100
//--------------------------------------------------------------
1101
bool ofVbo::hasAttribute(int attributePos) const {
1102
	if(ofIsGLProgrammableRenderer()){
1103
		switch(attributePos){
1104
		case ofShader::POSITION_ATTRIBUTE:
1105
			return positionAttribute.isAllocated();
1106
		case ofShader::COLOR_ATTRIBUTE:
1107
			return colorAttribute.isAllocated();
1108
		case ofShader::NORMAL_ATTRIBUTE:
1109
			return normalAttribute.isAllocated();
1110
		case ofShader::TEXCOORD_ATTRIBUTE:
1111
			return texCoordAttribute.isAllocated();
1112
		}
1113
	}
1114
	return (customAttributes.find(attributePos) != customAttributes.end());
1115
}
1116

1117

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.