framework2

Форк
0
462 строки · 11.9 Кб
1
/*
2
 * ofMatrixStack.cpp
3
 *
4
 *  Created on: Apr 3, 2013
5
 *      Author: arturo
6
 */
7

8
#include "ofMatrixStack.h"
9
#include "ofAppBaseWindow.h"
10
#include "ofGraphicsBaseTypes.h"
11
#include "ofLog.h"
12

13
#define GLM_FORCE_CTOR_INIT
14
#include "glm/mat4x4.hpp"
15
#include "glm/gtx/transform.hpp"
16

17
using std::swap;
18
using std::make_pair;
19
using std::pair;
20

21
ofMatrixStack::ofMatrixStack(const ofAppBaseWindow * window)
22
:vFlipped(true)
23
,orientation(OF_ORIENTATION_DEFAULT)
24
,handedness(OF_LEFT_HANDED)
25
,currentRenderSurface(nullptr)
26
,currentWindow(const_cast<ofAppBaseWindow*>(window))
27
,currentMatrixMode(OF_MATRIX_MODELVIEW)
28
,currentMatrix(&modelViewMatrix)
29
,flipRenderSurfaceMatrix(true)
30
,modelMatrix(1)
31
,viewMatrix(1)
32
,viewInverse(1)
33
,modelViewMatrix(1)
34
,projectionMatrix(1)
35
,textureMatrix(1)
36
,modelViewProjectionMatrix(1)
37
,orientedProjectionMatrix(1)
38
,orientationMatrix(1)
39
,orientationMatrixInverse(1)
40
{
41

42
}
43

44
void ofMatrixStack::setRenderSurface(const ofBaseDraws & renderSurface_){
45
	currentRenderSurface = const_cast<ofBaseDraws*>(&renderSurface_);
46
	flipRenderSurfaceMatrix = true;
47
	setOrientation(orientation,vFlipped);
48
}
49

50
void ofMatrixStack::setRenderSurfaceNoMatrixFlip(const ofBaseDraws & renderSurface_) {
51
	currentRenderSurface = const_cast<ofBaseDraws*>(&renderSurface_);
52
	flipRenderSurfaceMatrix = false;
53
	setOrientation(orientation, vFlipped);
54
}
55

56
void ofMatrixStack::setRenderSurface(const ofAppBaseWindow & window){
57
	currentWindow = const_cast<ofAppBaseWindow*>(&window);
58
	currentRenderSurface = nullptr;
59
	setOrientation(orientation,vFlipped);
60
}
61

62
void ofMatrixStack::setOrientation(ofOrientation _orientation, bool vFlip){
63
	vFlipped = vFlip;
64
	orientation = _orientation;
65

66
	if(vFlip){
67
		handedness = OF_LEFT_HANDED;
68
	}else{
69
		handedness = OF_RIGHT_HANDED;
70
	}
71

72
	orientationMatrix = glm::mat4(1.0);
73

74
	bool vFlipMatrix = customMatrixNeedsFlip();
75

76
	if(vFlipMatrix)
77
		orientationMatrix = glm::scale(orientationMatrix, glm::vec3(1.f,-1.f,1.f));
78

79
	if(!doesHWOrientation()){
80
		switch(orientation) {
81
			case OF_ORIENTATION_180:
82
				orientationMatrix = glm::rotate(orientationMatrix, glm::pi<float>(), glm::vec3{0.f, 0.f, 1.f});
83
				break;
84

85
			case OF_ORIENTATION_90_RIGHT:
86
				orientationMatrix = glm::rotate(orientationMatrix, glm::half_pi<float>(), glm::vec3{0.f, 0.f, 1.f});
87
				break;
88

89
			case OF_ORIENTATION_90_LEFT:
90
				orientationMatrix = glm::rotate(orientationMatrix, -glm::half_pi<float>(), glm::vec3{0.f, 0.f, 1.f});
91
				break;
92

93
			case OF_ORIENTATION_DEFAULT:
94
			default:
95
				break;
96
		}
97
	}
98

99
	orientationMatrixInverse = glm::inverse(orientationMatrix);
100
	orientedProjectionMatrix = orientationMatrix * projectionMatrix;
101
	modelViewProjectionMatrix = orientedProjectionMatrix * modelViewMatrix;
102
}
103

104
ofOrientation ofMatrixStack::getOrientation() const{
105
	return orientation;
106
}
107

108
bool ofMatrixStack::isVFlipped() const{
109
	return vFlipped;
110
}
111

112
bool ofMatrixStack::customMatrixNeedsFlip() const{
113
	return vFlipped != (bool(currentRenderSurface) && flipRenderSurfaceMatrix);
114
}
115

116
int ofMatrixStack::getRenderSurfaceWidth() const{
117
	if(currentRenderSurface){
118
		return currentRenderSurface->getWidth();
119
	}else if(currentWindow){
120
		return currentWindow->getWindowSize().x;
121
	}else{
122
		return 0;
123
	}
124
}
125

126
int ofMatrixStack::getRenderSurfaceHeight() const{
127
	if(currentRenderSurface){
128
		return currentRenderSurface->getHeight();
129
	}else if(currentWindow){
130
		return currentWindow->getWindowSize().y;
131
	}else{
132
		return 0;
133
	}
134
}
135

136
ofMatrixMode ofMatrixStack::getCurrentMatrixMode() const{
137
	return currentMatrixMode;
138
}
139

140
ofHandednessType ofMatrixStack::getHandedness() const{
141
	return handedness;
142
}
143

144

145
bool ofMatrixStack::doesHWOrientation() const{
146
	return currentRenderSurface || (currentWindow && currentWindow->doesHWOrientation());
147
}
148

149
void ofMatrixStack::viewport(float x, float y, float width, float height, bool vflip){
150
	if(!doesHWOrientation() && (orientation==OF_ORIENTATION_90_LEFT || orientation==OF_ORIENTATION_90_RIGHT)){
151
		swap(width,height);
152
		swap(x,y);
153
	}
154

155
	if(width < 0 || height < 0){
156
		width = getRenderSurfaceWidth();
157
		height = getRenderSurfaceHeight();
158
		vflip = isVFlipped();
159
	}
160

161
	if (vflip){
162
		y = getRenderSurfaceHeight() - (y + height);
163
	}
164

165
	currentViewport.set(x,y,width,height);
166
}
167

168
ofRectangle ofMatrixStack::getCurrentViewport() const{
169
	ofRectangle tmpCurrentViewport = currentViewport;
170
	if (isVFlipped()){
171
		tmpCurrentViewport.y = getRenderSurfaceHeight() - (tmpCurrentViewport.y + tmpCurrentViewport.height);
172
	}
173

174
	if(!doesHWOrientation() && (orientation==OF_ORIENTATION_90_LEFT || orientation==OF_ORIENTATION_90_RIGHT)){
175
		swap(tmpCurrentViewport.width,tmpCurrentViewport.height);
176
		swap(tmpCurrentViewport.x,tmpCurrentViewport.y);
177
	}
178
	return tmpCurrentViewport;
179
}
180

181
ofRectangle ofMatrixStack::getNativeViewport() const{
182
	return currentViewport;
183
}
184

185
ofRectangle ofMatrixStack::getFullSurfaceViewport() const{
186
	if(currentRenderSurface){
187
		return ofRectangle(0,0,currentRenderSurface->getWidth(),currentRenderSurface->getHeight());
188
	}else if(currentWindow){
189
		return ofRectangle(0,0,currentWindow->getWidth(),currentWindow->getHeight());
190
	}else{
191
		return ofRectangle();
192
	}
193
}
194

195
void ofMatrixStack::nativeViewport(ofRectangle viewport){
196
	currentViewport=viewport;
197
}
198

199
const glm::mat4 & ofMatrixStack::getModelMatrix() const{
200
	return modelMatrix;
201
}
202

203
const glm::mat4 & ofMatrixStack::getViewMatrix() const{
204
	return viewMatrix;
205
}
206

207
const glm::mat4 & ofMatrixStack::getViewInverse() const{
208
	return viewInverse;
209
}
210

211
const glm::mat4 & ofMatrixStack::getProjectionMatrix() const{
212
	return orientedProjectionMatrix;
213
}
214

215
const glm::mat4 & ofMatrixStack::getModelViewMatrix() const{
216
	return modelViewMatrix;
217
}
218

219
const glm::mat4 & ofMatrixStack::getModelViewProjectionMatrix() const{
220
	return modelViewProjectionMatrix;
221
}
222

223
const glm::mat4 & ofMatrixStack::getTextureMatrix() const{
224
	return textureMatrix;
225
}
226

227
const glm::mat4 & ofMatrixStack::getCurrentMatrix() const{
228
	return *currentMatrix;
229
}
230

231
const glm::mat4 & ofMatrixStack::getProjectionMatrixNoOrientation() const{
232
	return projectionMatrix;
233
}
234

235
const glm::mat4 & ofMatrixStack::getOrientationMatrix() const{
236
	return orientationMatrix;
237
}
238

239
const glm::mat4 & ofMatrixStack::getOrientationMatrixInverse() const{
240
	return orientationMatrixInverse;
241
}
242

243
void ofMatrixStack::pushView(){
244
	viewportHistory.push(currentViewport);
245

246
	ofMatrixMode currentMode = currentMatrixMode;
247

248
	matrixMode(OF_MATRIX_PROJECTION);
249
	pushMatrix();
250

251
	matrixMode(OF_MATRIX_MODELVIEW);
252
	pushMatrix();
253

254
	matrixMode(currentMode);
255

256
	viewMatrixStack.push(viewMatrix);
257

258
	orientationStack.push(make_pair(orientation,vFlipped));
259
}
260

261
void ofMatrixStack::popView(){
262
	if(!viewMatrixStack.empty()){
263
		viewMatrix = viewMatrixStack.top();
264
		viewInverse = glm::inverse(viewMatrix);
265
		viewMatrixStack.pop();
266
	}
267

268
	if(!orientationStack.empty()){
269
		pair<ofOrientation,bool> orientationFlip = orientationStack.top();
270
		setOrientation(orientationFlip.first,orientationFlip.second);
271
		orientationStack.pop();
272
	}
273

274
	if( viewportHistory.size() ){
275
		currentViewport = viewportHistory.top();
276
		viewportHistory.pop();
277
	}
278

279
	ofMatrixMode currentMode = currentMatrixMode;
280

281
	matrixMode(OF_MATRIX_PROJECTION);
282
	popMatrix();
283

284
	matrixMode(OF_MATRIX_MODELVIEW);
285
	popMatrix();
286

287
	matrixMode(currentMode);
288
}
289

290
void ofMatrixStack::pushMatrix(){
291
	switch(currentMatrixMode){
292
	case OF_MATRIX_MODELVIEW:
293
		modelViewMatrixStack.push(modelViewMatrix);
294
		break;
295
	case OF_MATRIX_PROJECTION:
296
		projectionMatrixStack.push(projectionMatrix);
297
		break;
298
	case OF_MATRIX_TEXTURE:
299
		textureMatrixStack.push(textureMatrix);
300
		break;
301
	}
302
}
303

304
void ofMatrixStack::popMatrix(){
305
	if (currentMatrixMode == OF_MATRIX_MODELVIEW && !modelViewMatrixStack.empty()){
306
		modelViewMatrix = modelViewMatrixStack.top();
307
		modelViewMatrixStack.pop();
308
		modelMatrix = viewInverse * modelViewMatrix;
309
	} else if (currentMatrixMode == OF_MATRIX_PROJECTION && !projectionMatrixStack.empty()){
310
		projectionMatrix = projectionMatrixStack.top();
311
		projectionMatrixStack.pop();
312
	} else if (currentMatrixMode == OF_MATRIX_TEXTURE && !textureMatrixStack.empty()){
313
		textureMatrix = textureMatrixStack.top();
314
		textureMatrixStack.pop();
315
	} else {
316
		ofLogWarning("ofMatrixStack") << "popMatrix(): empty matrix stack, cannot pop any further";
317
	}
318
	updatedRelatedMatrices();
319
}
320

321
void ofMatrixStack::clearStacks(){
322
	int tmpCounter = 0;
323
	while (!modelViewMatrixStack.empty()){
324
		modelViewMatrixStack.pop();
325
		tmpCounter++;
326
	}
327
	if (tmpCounter > 0 ){
328
		ofLogWarning("ofMatrixStack") << "clearStacks(): found " << tmpCounter << " extra modelview matrices on the stack, did you forget to pop somewhere?";
329
	}
330
	
331
	tmpCounter = 0;
332
	while (!projectionMatrixStack.empty()){
333
		projectionMatrixStack.pop();
334
		tmpCounter++;
335
	}
336
	if (tmpCounter > 0 ){
337
		ofLogWarning("ofMatrixStack") << "clearStacks(): found " << tmpCounter << " extra projection matrices on the stack, did you forget to pop somewhere?";
338
	}
339

340
	tmpCounter = 0;
341
	while (!textureMatrixStack.empty()){
342
		textureMatrixStack.pop();
343
		tmpCounter++;
344
	}
345
	if (tmpCounter > 0 ){
346
		ofLogWarning("ofMatrixStack") << "clearStacks(): found " << tmpCounter << " extra texture matrices on the stack, did you forget to pop somewhere?";
347
	}
348

349
	tmpCounter = 0;
350
	while (!viewportHistory.empty()){
351
		viewportHistory.pop();
352
		tmpCounter++;
353
	}
354
	if (tmpCounter > 0 ){
355
		ofLogWarning("ofMatrixStack") << "clearStacks(): found " << tmpCounter << " extra viewports on the stack, did you forget to popView() somewhere?";
356
	}
357

358
	tmpCounter = 0;
359
	while (!orientationStack.empty()){
360
		orientationStack.pop();
361
		tmpCounter++;
362
	}
363
	if (tmpCounter > 0 ){
364
		ofLogWarning("ofMatrixStack") << "clearStacks(): found " << tmpCounter << " extra orientations on the stack, did you forget to popView() somewhere?";
365
	}
366

367
	tmpCounter = 0;
368
	while (!viewMatrixStack.empty()){
369
		viewMatrixStack.pop();
370
		tmpCounter++;
371
	}
372
	if (tmpCounter > 0 ){
373
		ofLogWarning("ofMatrixStack") << "clearStacks(): found " << tmpCounter << " extra view matrices on the stack, did you forget to popView() somewhere?";
374
	}
375
}
376

377
void ofMatrixStack::translate(float x, float y, float z){
378
	*currentMatrix = glm::translate(*currentMatrix, glm::vec3(x, y, z));
379
	updatedRelatedMatrices();
380
}
381

382
void ofMatrixStack::scale(float xAmnt, float yAmnt, float zAmnt){
383
	*currentMatrix = glm::scale(*currentMatrix, glm::vec3(xAmnt, yAmnt, zAmnt));
384
	updatedRelatedMatrices();
385
}
386

387
void ofMatrixStack::rotateRad(float radians, float vecX, float vecY, float vecZ){
388
	*currentMatrix = glm::rotate(*currentMatrix, radians, glm::vec3(vecX, vecY, vecZ));
389
	updatedRelatedMatrices();
390
}
391

392
void ofMatrixStack::matrixMode(ofMatrixMode mode){
393
	currentMatrixMode = mode;
394
	switch(currentMatrixMode){
395
	case OF_MATRIX_MODELVIEW:
396
		currentMatrix = &modelViewMatrix;
397
		break;
398
	case OF_MATRIX_PROJECTION:
399
		currentMatrix = &projectionMatrix;
400
		break;
401
	case OF_MATRIX_TEXTURE:
402
		currentMatrix = &textureMatrix;
403
		break;
404
	}
405
}
406

407
void ofMatrixStack::loadIdentityMatrix (void){
408
	*currentMatrix = glm::mat4(1.0);
409
	updatedRelatedMatrices();
410
}
411

412
void ofMatrixStack::loadMatrix (const glm::mat4 & m){
413
	*currentMatrix = glm::mat4(m);
414
	updatedRelatedMatrices();
415
}
416

417
void ofMatrixStack::multMatrix (const glm::mat4 & m){
418
	*currentMatrix = *currentMatrix * m;
419
	updatedRelatedMatrices();
420
}
421

422
void ofMatrixStack::loadViewMatrix(const glm::mat4 & matrix){
423
	auto lastMatrixMode = currentMatrixMode;
424
	currentMatrixMode = OF_MATRIX_MODELVIEW;
425
	viewMatrix = matrix;
426
	viewInverse = glm::inverse(viewMatrix);
427
	loadMatrix(matrix);
428
	currentMatrixMode = lastMatrixMode;
429
}
430

431
void ofMatrixStack::multViewMatrix(const glm::mat4 & matrix){
432
	ofMatrixMode lastMatrixMode = currentMatrixMode;
433
	currentMatrixMode = OF_MATRIX_MODELVIEW;
434
	viewMatrix = viewMatrix * matrix;
435
	viewInverse = glm::inverse(viewMatrix);
436
	multMatrix(matrix);
437
	currentMatrixMode = lastMatrixMode;
438
}
439

440

441
void ofMatrixStack::updatedRelatedMatrices(){
442
	switch(currentMatrixMode){
443
	case OF_MATRIX_MODELVIEW:
444
		modelViewProjectionMatrix = orientedProjectionMatrix * modelViewMatrix;
445
		modelMatrix = viewInverse * modelViewMatrix;
446
		break;
447
	case OF_MATRIX_PROJECTION:
448
		orientedProjectionMatrix = orientationMatrix * projectionMatrix;
449
		modelViewProjectionMatrix = orientedProjectionMatrix * modelViewMatrix;
450
		break;
451
	default:
452
		break;
453
	}
454
}
455

456
bool ofMatrixStack::doesHardwareOrientation() const{
457
	if(currentRenderSurface){
458
		return true;
459
	}else{
460
		return currentWindow->doesHWOrientation();
461
	}
462
}
463

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

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

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

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